所需环境:
windows系统下的dvwa靶场
命令执行漏洞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>";
}
?>
运行原理
- 通过post方式上传一个参数(如果不是post参数则不执行)
- 利用trim()函数,删除上传命令首尾的空白字符和预定义字符,然后再将$target。(过滤预定义字符:括号、引号、运算符等)
- 创建一个数组
- 利用array_keys将原数组的key(键名)生成一个新的数组
- 利用str_replace()函数将查看上传的数据有没有array_keys生成的新数组值(如果有则将数据中与新数组值一样的值替换成原数组的vale值.(过滤)
- 利用息php_uname()函数获取主机信
- 利用stristr()函数对上传的数据进行搜索,判断数据中有没有'Windows NT',如果有是Windows输出,否则是nix输出.
重要函数的使用:
trim
trim() 函数是一个 PHP 内置函数,用于删除字符串开头和结尾的空白字符。它可以清除字符串两边的空格、换行符、制表符和其他非可视字符。下面是一个简单的例子:
$str = " Hello World! ";
echo trim($str); // 输出: Hello World!
在这个例子中,trim() 函数将字符串开头和结尾的三个空格去掉,只保留中间的文字。 此外,trim() 函数还可以指定一个自定义字符集,用于删除特定类型的字符。例如,可以使用下面的代码删除字符串开头和结尾的 HTML 标签:
$str = "<div>Hello World!</div>";
echo trim($str, '<>'); // 输出: Hello World!
在这个例子中,trim() 函数将字符串开头和结尾的所有 '<' 和 '>' 字符去掉,只保留中间的文字。 需要注意的是,trim() 函数只能删除字符串开头和结尾的字符,不能删除字符串内部的字符。
str_replace
$text = "Hello world!";
echo str_replace("world", "universe", $text);
在这个例子中,str_replace() 函数将字符串中的 "world" 替换为 "universe",输出为 "Hello universe!"。 str_replace() 函数支持三个参数:要替换的值、新的值和要替换的对象。如果要替换多个值,请将要替换的值放入数组中。例如:
$text = "I love PHP!";
$search = array("love", "PHP");
$replace = array("enjoy", "Python");
echo str_replace($search, $replace, $text);
在这个例子中,str_replace() 函数将 "love" 替换成 "enjoy",并将 "PHP" 替换成 "Python",输出为 "I enjoy Python!"。 如果希望一次性替换多个值,请将要替换的对象和要替换的值放入关联数组中。例如:
$text = "Hello world!";
$replaceArray = array("world"=>"universe", "Hello"=>"Goodbye");
echo str_replace(array_keys($replaceArray), array_values($replaceArray), $text);
在这个例子中,str_replace() 函数将 "world" 替换为 "universe",并将 "Hello" 替换成 "Goodbye",输出为 "Goodbye universe!"。 需要注意的是,str_replace() 函数只会替换第一次出现的匹配字符,如果希望替换全部匹配字符,请使用 preg_replace() 函数。
array_keys
在这个例子中,array_keys() 函数将返回一个数组,其中包含了原数组中的键名:
$array = array("apple", "banana", "cherry");
print_r(array_keys($array));
在这个例子中,array_keys() 函数将返回一个数组,其中包含了原数组中所有匹配 "red" 的键名:
$array = array("fruit" => "apple", "color" => "red", "shape" => "round");
print_r(array_keys($array, "red"));
array_keys() 函数还可以用于检索关联数组中的键名。例如:
$array = array("a" => "red", "b" => "green", "c" => "blue", "d" => "yellow");
print_r(array_keys($array));
在这个例子中,array_keys() 函数将返回一个数组,其中包含了原数组中的键名
stristr
在这个例子中,stristr() 函数将在字符串中查找 "wor" 子串,并在找到的情况下返回剩余部分。由于字符串中包含 "wor" 子串,所以输出将是 "Found"。 stristr() 函数的工作原理类似于 strstr() 函数,但它不区分大小写,可以更方便地搜索文本中的字符串。请注意,stristr() 函数只能找到第一个出现的子串,如果希望查找所有出现的位置,请使用 preg_match_all() 函数。
$text = "Hello world!";
if (stristr($text,"wor")) {
echo "Found";
} else {
echo "Not found";
}
php_uname
在这个例子中,php_uname() 函数将返回服务器的操作系统名称,例如 Windows 或 Linux。请注意,该函数适用于本地环境中的PHP开发环境,而不是远程服务器。
print_r(PHP_OS);
如果您想要获取更多关于服务器的信息,可以传入额外参数:
print_r(php_uname());
这将返回服务器的信息,包括操作系统名称、内核版本等:
Array
(
[0] => Linux
[1] =>
[2] => 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2+deb8u2 (2015-07-06) x86_64
[3] => GNU/Linux
[NAME] => Linux
[VERSION] =>
[RELEASE] => 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2+deb8u2 (2015-07-06)
[ID] => Debian
[PRETTY_NAME] => Debian GNU/Linux 8 (jessie)
[VERSION_ID] => 8
[ANSI_COLOR] => 0;33m
[HOME_URL] => http://www.debian.org/
[SUPPORT_URL] => http://www.debian.org/support
[BUG_REPORT_URL] => https://bugs.debian.org/
[REDIRECT_STATUS] => 200