需要的环境:dvwa
使用的工具:PHP手册
high难度源代码:
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = trim($_REQUEST[ 'ip' ]);
// Set blacklist
$substitutions = array(
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
// Remove any of the charactars in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
?>
首先进行if判断,使用isset函数判断post传入的参数是否为空,如果不为空,执行下面的语句
trim
遇到了不熟悉的语句trim,翻PHP手册并尝试使用该语句,
$target = **<u>trim</u>**($_REQUEST[ 'ip' ]);
由手册得知,trim可以去除字符串首尾的空白字符,能够使页面更加整洁
尝试trim函数
如图,php代码内参数左边有一个空格,中间一个空格,右边有两个空格,为了更加直观的看出区别,使用管道符对两个变量进行分割,同时输出
网页页面看不出太大区别
右键查看网页的源代码,可以看出管道符左右的区别,使用trim函数后,参数中间空格不受影响,两边的空格消失,没什么太大作用,只是使页面更加整洁美观
=============================================
array
翻手册查询语句array
$substitutions = array( '&' => '', ';' => '', '| ' => '', '-' => '', '$' => '', '(' => '', ')' => '', '`' => '', '||' => '', );
使用array函数可以创建一个数组
=============================================
查询语句str_replace,array_keys
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
array_keys函数在str_replace函数中,从里到外对函数进行解析
array_keys
array_keys( $substitutions )
array_keys返回数组中的键名,可知该函数获取了array函数中的键名
尝试array_keys函数
使用var_dump输出array_keys函数的内容及类型
如图输出了一个索引数组
看起来不太明显,使用for循环对数组进行遍历
$arr1=array_keys($substitutions) //定义一个变量arr1,把array_keys数组赋赋给变量arr1 for($a=0,$a<sizeof($substitutions),$a++){ //sizeof用于计算数组内元素的个数 //定义一个变量a为0,当变量a小于$substitutions变量内元素个数的时候停止,变量a自增 echo $arr1[$a]."<br \>"; //取$arr1数组内的第$a个元素,返回给$arr1,并输出,为了更加直观,拼接一个换行 //这样可以查看到array_keys返回的数组具体有什么 }
由此可知array_keys具体返回的数组
由此可知,array_keys函数将$substitutions数组中的键名取出并做成了一个新的索引数组
=============================================
str_replace
str_replace( array_keys( $substitutions ), $substitutions, $target )
str_replace函数可以对字符串进行替换
尝试str_replace函数
$substitutions = array( 'ipconfig' => '', 'whoami' => '', 'pwd' => '', ); $arr1 = array_keys( $substitutions ); $a="whoamiabcipconfig123pwd"; echo $a.<br \>; //分别输出执行str_replace前后的字符串 //str_replace(数组1返回的键名,数组1,变量(字符串)) echo str_replace($arr1, $substitutions, $a);
如图可知,str_replace将(第三个参数)中的字符串与(第一个参数)数组1返回的键名进行匹配,有相同的字符串就会访问(第二个参数)数组1查看规则将其替换为空
解析语句str_replace( array_keys( $substitutions ), $substitutions, $target )
str_replace( array_keys( $substitutions ), $substitutions, $target )
//先通过array_keys返回$substitutions数组内的键名,然后根据键名,查找传递过来的$target,如果有与键名相匹配的字符,就根据$substitutions数组内的value值进行替换
=============================================
stristr
stristr( php_uname( 's' ), 'Windows NT' )
php_uname用于返回php系统信息
尝试php_name,由此可知,该函数用于判定当前操作系统的版本(由于Windows系统和*nix系统的ping规则不同,所以需要区分,分别进行操作)
stristr是strstr的忽略大小写版本
Windows不区分大小写,但是php区分大小写,所以需要stristr函数来忽略大小写
strstr用于查找字符串的首次出现
解析语句stristr( php_uname( 's' ), 'Windows NT' )
stristr( php_uname( 's' ), 'Windows NT' )
//查看当前的操作系统是否为Windows,忽略大小写
=============================================
全代码解析
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
//进行if判断,使用isset函数判断post传入的参数是否为空,如果不为空,执行下面的语句
$target = trim($_REQUEST[ 'ip' ]);
//去除用户输入字符串首尾的空白字符,并返回给变量$target,使页面更加整洁
$substitutions = array(
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
); //创建一个数组
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
//先通过array_keys返回$substitutions数组内的键名,然后根据键名,查找传递过来的$target,如果有与键名相匹配的字符,就根据$substitutions数组内的value值进行替换,再将数值返回给$target
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
//if进行判断,查看当前的操作系统是否为Windows,忽略大小写,如果为windows,执行下面的语句,对目标进行ping命令,返回给变量$cmd
$cmd = shell_exec( 'ping ' . $target );
}
else {
//if判断如果不为Windows则默认为*nix系统,对目标进行ping命令,限制为4个包,返回给变量$cmd
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
//将返回的结果$cmd输出到页面
echo "<pre>{$cmd}</pre>";
}
?>