0x01 命令执行
Command Injection,即命令注入,是指通过提交恶意构造的参数破坏命令语句结构,从而达到执行恶意命令的目的。
注:"|"和"||"是有区别的,"|"不管竖杠左边的命令是否正确都会执行竖杠右边的命令。"||"则是左边的命令正确就只执行左边的命令,左边的命令错误才会执行右边的命令。
0x02 Low级别
使用&、|等符号就可以成功,例如127.0.0.1&net user等。
代码分析:
<?php if( isset( $_POST[ 'Submit' ] ) ) { // 将输入的ip赋值给$target $target = $_REQUEST[ 'ip' ]; // 判断操作系统。php_uname返回运行PHP的系统的有关信息;stristr函数用于搜索字符串在另一字符串中的第一次出现。 if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // 如果是Windows,就执行下面这段语句 $cmd = shell_exec( 'ping ' . $target ); } else { // 不是Windows就执行下面的语句,也就是Linux等操作系统。 $cmd = shell_exec( 'ping -c 4 ' . $target ); } // 返回信息给用户 echo "<pre>{$cmd}</pre>"; } ?>
0x03 Medium级别
除了黑名单中的两个符号以外,还可以使用&、|等符号。
代码如下:
<?php if( isset( $_POST[ 'Submit' ] ) ) { // 同Low级别一样 $target = $_REQUEST[ 'ip' ]; // 设置黑名单,一旦有&&或;就将其替换为空。 $substitutions = array( '&&' => '', ';' => '', ); // 将$target中的&&和;替换为空。array_keys用于返回包含数组中所有键名的一个新数组。 $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); // 判断操作系统. if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // Windows $cmd = shell_exec( 'ping ' . $target ); } else { // 不是Windows $cmd = shell_exec( 'ping -c 4 ' . $target ); } // 返回信息给用户 echo "<pre>{$cmd}</pre>"; } ?>
0x04 High级别
没有过滤单竖杠"|"。
代码如下:
<?php if( isset( $_POST[ 'Submit' ] ) ) { // trim函数用于清除字符串两侧的空白字符或预定义字符。 $target = trim($_REQUEST[ 'ip' ]); // 设置黑名单,其中的第一行&符号,相当与过滤了一个及以上的&符号。第三行的是过滤的"| ",有一个空格哦。 $substitutions = array( '&' => '', ';' => '', '| ' => '', '-' => '', '$' => '', '(' => '', ')' => '', '`' => '', '||' => '', ); // 利用黑名单进行过滤 $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); // 判断操作系统 if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // Windows $cmd = shell_exec( 'ping ' . $target ); } else { // 不是Windows $cmd = shell_exec( 'ping -c 4 ' . $target ); } // 返回信息给用户 echo "<pre>{$cmd}</pre>"; } ?>
0x05 Impossible级别
代码如下:
<?php if( isset( $_POST[ 'Submit' ] ) ) { // 利用token来防止模糊测试 checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); // 获取用户的输入,并将其中的反斜杠进行删除 $target = $_REQUEST[ 'ip' ]; $target = stripslashes( $target ); // 将ip以.为分界符分成4个部分。explode函数用于把字符串打散为数组。 $octet = explode( ".", $target ); // 检查4部分是否都为字符串或数字,并且必须为4个部分。is_numeric函数用于检测变量是否为数字或数字字符串;sizeof函数用于返回数组中元素的数目。 if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) { // 拼接ip,点号在php中为拼接符。 $target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3]; // 判断操作系统. if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // Windows $cmd = shell_exec( 'ping ' . $target ); } else { // 不是Windows $cmd = shell_exec( 'ping -c 4 ' . $target ); } // 返回信息给用户 echo "<pre>{$cmd}</pre>"; } else { // 不是有效的ip,就会返回以下的错误信息 echo '<pre>ERROR: You have entered an invalid IP.</pre>'; } } // 产生token generateSessionToken(); ?>
0x06 总结
1.使用黑名单进行过滤。
2.替换、转义关键字。
3.对于ip地址,可以以点号来进行分界,将所有数字拆分到数组,单个判断是否为数字is_numeric()。