基本环境:
系统环境 | Windows系统 |
靶场 | dvwa靶场 |
impossible命令执行漏洞的代码
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$target = $_REQUEST[ 'ip' ];
$target = stripslashes( $target );
// Split the IP into 4 octects
$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.
$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
generateSessionToken();
?>
运行原理:
1.首先查看是不是post传输数据,如果是则进入if语句,否则不执行
2. 利用checkToken()函数对数据中的token进行验证。
3.利用stripslashes()函数消除数据中的 \;
4.利用explode()将数据进行拆分
5.将拆分的数据转换成数组,利用is_numeric()判断拆分的数组是否为数字,同时利用sizeof()判断数组长度是否为4(sizeof( $octet ) == 4)。(如果是进入if分支,否则输出You have entered an invalid IP)
6.将判断的数组进行拼接
7.利用php_uname()函数获取系统信息。
8.利用stristr()函数判断数据的系统信息中有没有Windows NT。如果有进入if分支
9.输出从cmd
关键函数:
checkToken
checkToken()
是一种常见的自定义函数名,在 Web 开发中经常用作令牌校验。 令牌(token)是一种常用的安全机制,用来防止跨站请求伪造(CSRF)攻击和其他形式的身份冒充攻击。checkToken()
函数通常会比较客户端提交过来的令牌与服务器生成的有效令牌是否一致,如果不一致则认为存在潜在的安全威胁,并拒绝后续的操作请求。这种做法可以有效保护 Web 应用程序免受 CSRF 攻击的影响。 下面是一个简单的checkToken()
函数示例:function checkToken() { if (!isset($_POST['token']) || !hash_equals($_SESSION['token'], $_POST['token'])) { die('Invalid token'); } }
这个函数首先检查是否存在名为
token
的 POST 变量,然后将其与服务器上存储的 Session 变量进行对比。如果两者的哈希值不相等,则说明可能存在安全问题,函数就会停止运行并显示错误消息。
stripslashes
stripslashes()
是 PHP 中的一个函数,用于移除字符串中的反斜杠转义字符\
。 在 PHP 中,反斜杠是一个转义字符,用于表示一些特殊字符(例如\"
表示双引号,\n
表示换行符等)。然而,在某些情况下,您可能不需要这些转义字符,这时可以使用stripslashes()
函数将其移除。 下面是一个使用stripslashes()
函数的例子:$text = "\nHello, \\World\\!"; echo stripslashes($text);
输出
Hello, \World\!
,这是因为
stripslashes()
函数移除了字符串中的所有反斜杠转义字符。
explode
explode()
是 PHP 中的一个函数,用于将字符串按照指定的分隔符拆分为数组。 这个函数接受两个参数:第一个参数是要分割的字符串,第二个参数是用于拆分的分隔符。 下面是一个使用explode()
函数的例子:$text = "Hello, World!"; $arr = explode(", ", $text); print_r($arr);
输出如下数组:
Array ( [0] => Hello [1] => World! )
这是因为
explode()
函数将字符串Hello, World!
按照,
分割成了两个元素:Hello 和 World! 。 需要注意的是。
sizeof
sizeof()
是 PHP 中的一个函数,用于获取数组的长度。 这个函数接受一个数组作为参数,并返回数组中元素的数量。 下面是一个使用sizeof()
函数的例子:$arr = array(1, 2, 3, 4, 5); echo sizeof($arr);
这段代码将会输出
5
,因为数组中有五个元素。
is_numeric
is_numeric()
是 PHP 中的一个函数,用于检查一个变量是否为数字。 这个函数接受一个变量作为参数,并返回 TRUE 或 FALSE 来指示该变量是否为数字。如果该变量可以转换为合法的浮点数,那么就返回 TRUE;否则返回 FALSE。 下面是一个使用is_numeric()
函数的例子:$a = "42"; if (is_numeric($a)) { echo "This is a number"; } else { echo "This is not a number"; }
输出 "This is a number",
因为变量
$a
是一个数字。
php_uname
php_uname()
是 PHP 中的一个函数,用于获取系统的信息。 这个函数返回一个包含系统信息的字符串,包括操作系统名称、版本号、主机名等内容。 下面是一个使用php_uname()
函数的例子:$info = php_uname(); echo $info;
这段代码将会打印出当前系统的详细信息,如下所示:
Linux localhost 4.4.0-19041-Microsoft #267-Microsoft Thu Dec 12 14:58:½
stristr
stristr()
是 PHP 中的一个函数,用于在字符串中搜索一个子串,忽略大小写。 这个函数接受两个参数:第一个参数是要搜索的目标字符串,第二个参数是要搜索的子串。如果找到了匹配的子串,那么就返回包含该子串及其后面部分的字符串;否则返回 FALSE。 下面是一个使用stristr()
函数的例子$text = "Hello, World!"; $find = "world"; $result = stristr($text, $find); echo $result;
这段代码将输出
World!
,因为它是在忽略大小写的条件下搜索world
子串的结果。 需要注意的是,stristr()函数只会返回找到的第一个匹配项及其后面的部分。