DVWA通关之命令注入(command injection)
DVWA通关之命令注入(command injection)
难度等级:low
过关思路
- 我们先将其难度设置为
low
,看到其界面如下:
- 通过分析得知,该功能是输入一个
IP地址
,然后通过ping
进行测试,先输入127.0.0.1
和www.baidu.com
测试如下:
127.0.0.1
www.baidu.com
- 可以看到,IP地址和域名都是能够ping通的,接下来就是使用
命令拼接
测试了,
输入127.0.0.1 | whoami
命令注入成功。
- 命令汇总,经过测试,以下命令均可注入成功。
127.0.0.1|whoami
127.0.0.1&whoami
127.0.0.1000 || whoami
127.0.0.1 && whoami
-
注意:
有空格和无空格有时会有意想不到的效果 -
做完了当然得看一下源码:
可以看到,该代码没有对用户的输入做任何的过滤,直接使用shell_exec函数
执行用户输入,这是非常危险的。
难度等级:medium
过关思路
- 这里过关思路和low一致,也没啥可说的,我们主要看一下源码就行。
- 源代码如下:
通过分析,可以看出,medium
关卡比low
关卡多了一个黑名单
。其通过数组的方式将&&
和;
进行了过滤,即将其替换为空
。但是,这种过滤基本上还是跟没有过滤差不多,因为黑名单里的过滤太少了,黑名单也不安全。
难度等级:high
过关思路
- 上手先测试几个前面的payload,发下好多都被过滤了,但是还有几个可以用:
127.0.0.1 || whoami
127.0.0.1|whoami
127.0.0.1000||whoami
- 我们直接看源代码:
可以看到,这次的黑名单过滤明显的多了起来,但是也发现(可能是故意给我们漏出来的😂),其在过滤的时候,没有过滤|
而是过滤了|+空格
,所以,该代码只是遇到单单一个|
,不会进行过滤。
难度等级: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();
?>
一波代码审计,我们发现,这次的过滤和前面的两关没有任何相似之处,而是直接换了一种思路,也就是我们所说的白名单
。其控制了用户的输入,不在控制用户的输入哪些不能用,而是控制用户的输入哪些能用。
- 我们还是慢慢从函数入手分析:
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
这段代码是控制了用户身份信息,在每次和服务器交互之时,服务器会随机给用户分配一个ID,用作用户的身份凭证,这样也就断绝了假冒用户的事件发生。
$target = stripslashes( $target );
stripslashes函数
用于删除输入中的反斜杠。
$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 ))
而这段代码是控制了用户只能输入IP地址
,无法使用域名。且在用户输入IP地址后,使用explode函数
以.
为分割,将IP地址分割为数组,最后判断数组的个数是否为4
。可以说,过滤确实很绝,但是也有一个不好之处就是屏蔽掉了域名。
总结
- 掌握有关命令执行的知识 windows 或 linux 下:
命令执行漏洞(| || & && 称为管道符)
command1 && command2 先执行 command1,如果为真,再执行 command2
command1 | command2 只执行 command2
command1 & command2 先执行 command2 后执行 command1
command1 || command2 先执行 command1,如果为假,再执行 command2
windows:(1)|(2)||(3)&(4)&&
linux:(1)|(2)||(3);(4)&&
- 命令注入的相关系统函数:
① system()
② exec()
③ shell_exec()
④ passthru()
⑤ popen()
⑥ ``(反引号)