low
,看到其界面以下:IP地址
,而后经过ping
进行测试,先输入127.0.0.1
和www.baidu.com
测试以下:127.0.0.1
php
www.baidu.com
linux
命令拼接
测试了,输入127.0.0.1 | whoami
shell
命令注入成功。windows
127.0.0.1|whoami数组
127.0.0.1&whoami安全
127.0.0.1000 || whoami服务器
127.0.0.1 && whoamisession
注意:
有空格和无空格有时会有意想不到的效果函数
作完了固然得看一下源码:学习
能够看到,该代码没有对用户的输入作任何的过滤,直接使用shell_exec函数
执行用户输入,这是很是危险的。
经过分析,能够看出,medium
关卡比low
关卡多了一个黑名单
。其经过数组的方式将&&
和;
进行了过滤,即将其替换为空
。可是,这种过滤基本上仍是跟没有过滤差很少,由于黑名单里的过滤太少了,黑名单也不安全。
127.0.0.1 || whoami
127.0.0.1|whoami
127.0.0.1000||whoami
能够看到,此次的黑名单过滤明显的多了起来,可是也发现(多是故意给咱们漏出来的😂),其在过滤的时候,没有过滤|
而是过滤了|+空格
,因此,该代码只是遇到单单一个|
,不会进行过滤。
<?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
。能够说,过滤确实很绝,可是也有一个很差之处就是屏蔽掉了域名。
命令执行漏洞(| || & && 称为管道符)
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()
⑥ ``(反引号)