一、Command Injection(命令注入)
1.定义:就是指通过提交一些恶意构造的参数破坏命令语句结构,从而达到执行恶意命令的目的。
2.ping 命令(Packet Internet Groper),因特网包探索器,用于测试网络连接量的程序。Ping发送一个ICMP;回声请求消息给目的地并报告是否收到所希望的ICMP echo (ICMP回声应答)。
3.特殊符号:
; 前后命令依次执行 注意前后顺序,若更变目录,则必须在“一句”指令内
|| 前命令执行失败后才执行后命令 -
&& 前命令执行成功后才执行后命令 -
& 前台执行后任务,后台执行前任务 如 a&b&c 则显示c的执行信息,a b在后台执行
| 管道,只输出后者的命令 当第一条命令失败时,它仍然会执行第二条命令
(反引号,仅linux) 即命令替换,echodate,输出系统时间 使用反引号运算符的效果与函数shell_exec()相同,但在激活了安全模式或者关闭了shell_exec()时是无效的
$(command) 这是命令替换的不同符号。与反引号效果一样。echo $(date),输出系统时间. 按理说更推荐用这种方法,而不是反引号。
难度等级:Low
<?php if( isset( $_POST[ 'Submit' ] ) ) { // Get input $target = $_REQUEST[ 'ip' ]; // 确定操作系统并执行ping命令 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>"; }
漏洞复现
通过代码可以发现,服务器仅仅只是判断了不同的操作系统执行不同的命令,并没有做其他的限制
先简单介绍一下如何使用连接符号拼接自己的命令
127.0.0.1 & ipconfig 先执行127.0.0.1,不管127.0.0.1是否执行成功都会执行ipconfig 127.0.0.1 && ipconfig 先执行127.0.0.1,127.0.0.1执行成功后才会执行ipconfig 127.0.0.1 | ipconfig 不管127.0.0.1执行是否成功都会执行ipconfig 127.0.0 || ipconfig 前面的命令要执行失败,才可以执行后面的命令
在这我们直接使用第一个 127.0.0.1 & ipconfig 就好了:
难度等级:Medium
源码解析
<?php if( isset( $_POST[ 'Submit' ] ) ) { // Get input $target = $_REQUEST[ 'ip' ]; // Set blacklist //设置命令黑名单,里面包含&&和; $substitutions = array( '&&' => '', ';' => '', ); // Remove any of the charactars 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>"; } ?>
漏洞复现
从源码中可以看出,相比于Low难度,增加了黑名单,将 "&&",";" 做了限制,将其改成空格,但是别的没有什么改变,在这里依旧可以通过 127.0.0.1 & ipconfig 来绕过。
难度等级:High
源码解析
<?php if( isset( $_POST[ 'Submit' ] ) ) { // Get input $target = trim($_REQUEST[ 'ip' ]); // Set blacklist //设置命令黑名单,里面包含& ;| - $ ( ) \ ' || $substitutions = array( '&' => '', ';' => '', '| ' => '', '-' => '', '$' => '', '(' => '', ')' => '', '`' => '', '||' => '', ); // Remove any of the charactars 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>"; } ?>
漏洞复现
看到代码,发现黑名单中的限制更多了,像 '&','| ','||',';','$' 等许多都加了限制,但是要仔细观察 ,比如说这个 '| ' ,它是在管道符后面加了个空格,因此考虑使用 127.0.0.1 |ipconfig 来绕过。