注:本篇为 上一篇 的延续内容,主要内容是讲解 DVWA high 和 impossible 防御等级的命令执行漏洞。
上一篇 Medium 只是屏蔽掉了两个命令连接符,那么我们在 DVWA Security 切换成 high 等级看一下。老规矩,打开 View Source 查看源码。
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = trim($_REQUEST[ 'ip' ]);
// Set blacklist
$substitutions = array(
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
// Remove any of the characters 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>";
}
?>
在 High 的防御等级中屏蔽了所有符号,包括我们常见的,比如括号减号。如果用户输入了上面屏蔽的符号,就会自动删除,这样就导致我们没有办法进行命令执行。
那有的同学会问了,这代码已经写死了,我们不是没有办法进行命令执行攻击了吗?这里就需要大家仔细观看了,可能未来大家在打CTF比赛的时候会遇到这种场景。
因为做研发每天面对的无数行代码,有时候多敲了一个空格很难察觉的到。我们返回去看到第三行屏蔽的字符:‘| ‘ => ”, 发现了什么?是不是多出了一个空格。那说明程序只能拦截竖线+空格,你单独输入一个竖线,程序是拦截不了的。
那我们返回 DVWA 输入 127.0.0.1|whoami ,发现已经成功运行了。大家可能也发现了我在编写文章的时候,代码左右或中间都加了一个空格,是因为我要考虑美观效果。但是在代码世界可就不一样了,一个空格可能改变程序的走向,这个就需要大家要记住的点。
我们也可以加其他命令尝试一下,比如 dir,命令为:127.0.0.1|dir ,就能把网站目录给列出来了。
������ D �еľ��� WorkFiles
��������� 8C00-1CEA
D:\backup\DVWA-master\vulnerabilities\exec ��Ŀ¼
2023/03/22 19:17
.
2023/03/22 19:17
..
2023/03/22 19:17
help
2023/03/22 19:17 1,829 index.php
2023/03/22 19:17
source
1 ���ļ� 1,829 �ֽ�
4 ��Ŀ¼ 112,476,471,296 �����ֽ�
其实 Medium 和 High 防御等级的代码相差不多,只是多屏蔽了几个字符。在 High 的代码中,缺少了对空格的检测,代码中屏蔽掉了竖线+空格,但并不影响竖线的使用。在 High 的防御等级,他没有起到任何技术性的突破,那么接下来我们就来看一下,在开发中应该采取什么样的算法去防御这个漏洞。
我们将防御等级提高到 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:$target = stripslashes( $target );
首先我们输入的 IP 还是赋值给了 $target 这个变量,下面有一个 stripslashes($target) ,这是一个PHP的函数,意思是删除所有的反斜杠 “ \ ” ,比如:stripslashes(“Who\’s Go\ya\sha?”),实际上输出的是 “ Who’s Goyasha? ”,那 $target = stripslashes( $target ) 的意思就是删除用户输入的斜杠。
开发者设计这个功能的时候,就只想让你输入一个 IP 进行检测,如果你乱输入的话就给你做相应的屏蔽。不管你做什么,先给你屏蔽了再说。
关键点2:$octet = explode( “.”, $target );
使用了一个PHP函数 explode() ,意思是利用 “ . ” 对我们输入的 IP 地址进行分割。比如我们输入的 IP 地址是 “ 58.123.46.23 ”,他就会把 “ . ” 给去掉并分割为4个部分,分别为58、123、46、23。
关键点3:if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) )
首先我们来看出现的第一个PHP函数 is_numeric(),他是用来检测输入的内容是否为数字,后面跟着 $octet[0] ,这个 0 代表着上面拆分的第一个数值 58,如果是 $octet[1] 那就是 123,以此类推。如果检测到你输入的不是数字,那就给相应的错误提示。
再来看 sizeof( $octet ) == 4 这个大家可以猜一下是什么作用?这段代码是来判断你输入的是不是四组内容,可以看一下之前的是 is_numeric( $octet[3]) 只判断到了第四个数字。
那我突发奇想,假如没有 sizeof( $octet ) == 4 的判断,那我通过 “ 58.123.46.23.111|whoami ” 是否能查到用户名呢?因为只判断了 “ 58.123.46.23 ” 是不是数字,后面的信息他并没有验证。所以如果没有该验证点,是可以命令执行攻击成功的!
不是很关键的关键点:$target = $octet[0] . ‘.’ . $octet[1] . ‘.’ . $octet[2] . ‘.’ . $octet[3];
这段代码就是将上述判断的四个数字,再合成 IP 形式的,给四个数字加上 “ . ”(点),最后我们再将上面解析的做个总结:
1、如果用户输入了斜杠,stripslashes() 函数就将斜杠自动删除;
2、explode() 再将删除斜杠后的数据根据 “ . ”(点)进行分割成4组内容;
3、分别判断这4组内容都是不是数值,如果判断任意一组不是数值,那就报错;
4、把验证完成的四个数字在用 “ . ”(点)拼接起来,恢复成正常的 IP 格式。
这毕竟是 DVWA impossible 防御等级,单从命令执行漏洞已经无法对其进行攻击了。目前也是简单了解一下,研发人员是如何防御此类漏洞的。
那么两篇文章内容比较多,相信大家也都初步了解命令执行漏洞是如何执行发生的了,如果还有同学对这些内容有疑问的话,欢迎在两篇内容下方评论!如果有空我会私下在教大家的。