dvwa高难命令执行漏洞的代码审计
审计dvwa高难度命令执行漏洞的代码
首先查看源代码:
<?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.判断操作系统并执行ping命令
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[ 'Submit' ] ) ) {
//判断PHP的isset函数是否已经赋值接受post传参的一个叫Submit的参数,接受了就往下执行
$target = trim($_REQUEST[ 'ip' ]);
//给$target这个函数赋值=用户post/get提交的IP这个参数并删除周围的空格
// Set blacklist设置黑名单
$substitutions = array( //快速定义了数值
'&' => '', //均为关联数组键==>值
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
$target = str_replace(array_keys( $substitutions ), $substitutions, $target );
//第一个参数是数组$substitutions的key变换为新的数组的value,第二个参数为替换数组$substitutions的value,执行完后会把这个值给$targe。
第二段:
// Determine OS and execute the ping command.判断操作系统并执行ping命令
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
//判断查找,输出操作系统的名称,匹配Windows NT这个字符。是的话就往下走,不是就进入 else 这个语句。
// Windows(Windows就ping四次,会自己停止)
$cmd = shell_exec( 'ping ' . $target );
}
//$target这个函数是上方接受一个叫IP的参数,就是IP地址。
//判断系统,是不是Windows,是就ping,不是就执行else的语句,ping四次
else {
// *nix(Linux/Unix无限ping,所以取四次)
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
//给$cmd赋值=ping的结果
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
//输出$cmd这个函数,也就是输出ping的结果
}
解释并说明如下重要函数的用法:
trim
用于删除字符串两侧的空白字符或其他预定义字符。它可以删除包括空格、制表符、换行符等在内的多种字符。
<?php
$text = " Hello World! ";
echo trim($text);
?>
在这个例子中,输出将是"Hello World!",因为在文本的开始和结束处都有一些额外的空格,这些空格被trim函数删除了。
str_replace
PHP的str_replace()函数用于搜索字符串中指定值,并将其替换为另一个值。它可以接受三个参数:要搜索和替换的目标字符串、要搜索的值以及要替换的新值。
<?php
$str = "Hello, World!";
echo str_replace("World", "Dolly", $str);
?>
在这个例子中,str_replace()
会找到所有的"World"并将其替换为"Dolly",结果输出为:“Hello, Dolly!”
array_keys
PHP的array_keys()函数用于从关联数组中获取所有键名,或从索引数组中获取所有索引。
<?php
$array = array("a" => "1", "b" => 2, "c" => "3");
print_r(array_keys($array));
?>
在这个例子中,array_keys()
会返回数组中的所有键名,结果输出为:
Array([0] =>a [1] =>b [2] =>c) //键Key变成了值
stristr
PHP的stristr函数是一个用于查找字符串在另一字符串中首次出现的位置的函数,而且这个函数是不区分大小写的。如果找到匹配项,则返回该字符串的其余部分(从匹配点开始)。
<?php
$text = "Hello, World!";
$find = "world";
echo stristr($text, $find);
?>
在这个例子中,$find
是我们要查找的字符串,$text
是我们要在其中进行搜索的字符串。运行上述代码后,输出的结果将会是:“World!”。因为stristr函数会返回从匹配点开始的字符串的剩余部分。
php_uname
PHP中的php_uname函数用于获取系统信息,包括操作系统名称、主机名、内核版本等。
以下是php_uname函数的一些参数及其作用:
- ‘s’:获取操作系统的名称。
- ‘n’:获取主机名。
- ‘r’:获取内核版本。
- ‘m’:获取机器类型。
- ‘p’:获取处理器类型。
- ‘v’:获取版本信息。
简单地调用不带参数的php_uname函数,如下所示:
<?php
echo php_uname();
?>
这将输出以下内容:
系统的信息。
审计impossible难度的代码
查看源代码:
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Check Anti-CSRF token增加了token验证
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$target = $_REQUEST[ 'ip' ];
$target = stripslashes( $target );
// Split the IP into 4 octects将IP分割为四个字节
$octet = explode( ".", $target );
// Check IF each octet is an integer检查每八位是否为一个整数
if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
// If all 4 octets are int's put the IP back together.如果4个字节都是int类型,就将IP重新组合在一起。
$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
// 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>";
}
else {
// Ops. Let the user name theres a mistake输入的有误
echo '<pre>ERROR: You have entered an invalid IP.</pre>';
}
}
// Generate Anti-CSRF token生成token
generateSessionToken();
?>
解释说明其中函数的作用
$_SESSION[ ‘session_token’ ]
存储用户 token 到会话
stripslashes
PHP的stripslashes()函数主要用于去除字符串中的反斜线(\
),这通常是为了防止SQL注入攻击而对用户输入数据进行过滤处理的一种方式。
explode
PHP 的 explode() 函数用于将一个字符串切割成一个数组。它接受两个参数:一是分隔符(即将被用来切割字符串的一个或多个字符),二是需要被切割的字符串。如果设置了可选的第三个参数,则该参数限制了返回数组的长度。
<?php
$string = "Hello, world! This is an example.";
$delimiter = " ";
$array = explode($delimiter, $string);
print_r($array);
?>
//输出后Array([0] => Hello, [1] => world! [2] => This [3] => is [4] => an [5] => example.)
is_numeric()
PHP的is_numeric()
函数用于检查变量是否包含数字或数字格式的内容。如果变量是数字类型或只包含数字(包括正负号、小数点和科学计数法等),则该函数将返回true
;否则,它将返回false
。