本次搭建OWASP靶機(jī)中自帶的DWVA靶機(jī)對(duì)命令注入執(zhí)行
Simple級(jí)別
源代碼查看
<?php
if( isset( $_POST[ 'submit' ] ) ) {
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if (stristr(php_uname('s'), 'Windows NT')) {
$cmd = shell_exec( 'ping ' . $target );
echo '<pre>'.$cmd.'</pre>';
} else {
$cmd = shell_exec( 'ping -c 3 ' . $target );
echo '<pre>'.$cmd.'</pre>';
}
}
?>
關(guān)鍵函數(shù)
php_uname(mode) 函數(shù):
mode內(nèi)容如下:
'a':此為默認(rèn)。包含序列 "s n r v m" 里的所有模式。
's':操作系統(tǒng)名稱。例如: FreeBSD。
'n':主機(jī)名。例如: localhost.example.com。
'r':版本名稱,例如: 5.1.2-RELEASE。
'v':版本信息。操作系統(tǒng)之間有很大的不同。
'm':機(jī)器類型。例如:i386。
shell_exec() 函數(shù):
通過shell執(zhí)行命令并以字符串的形式返回完整的輸出
代碼審計(jì):
通過關(guān)鍵函數(shù)結(jié)合源代碼,可以看到原意是通過ping命令和用戶輸入的信息進(jìn)行拼接調(diào)用shell_exec()函數(shù)來執(zhí)行shell命令,最后回顯結(jié)果。由于此處只是進(jìn)行簡單憑借,所以通過構(gòu)造特殊輸入內(nèi)容,可以利用命令注入漏洞來進(jìn)行執(zhí)行。
命令注入
核心思想是,通過執(zhí)行完第一個(gè)command后,在執(zhí)行惡意拼接的command
主要使用的命令拼接符號(hào)有 | || & &&
| 拼接符 | 使用方法 | 功能 | 適用系統(tǒng) |
|---|---|---|---|
| | | command1 | command2 | 只顯示Command2結(jié)果 | W/L |
| || | command1 || command2 | 顯示command1和command2結(jié)果,Command1不影響2 | W/L |
| & | command1 & command2 | 顯示command1和command2結(jié)果,Command1不影響2 | W |
| && | command1 && command2 | 顯示command1和command2結(jié)果,Command1必須正確 | W/L |
| ; | command1 ; command2 | 顯示command1和command2結(jié)果,Command1不影響2 | L |
Simple測試






Medium級(jí)別
源代碼查看
<?php
if( isset( $_POST[ 'submit' ] ) ) {
$target = $_REQUEST[ 'ip' ];
$substitutions = array(
'&&' => '',
';' => '',
);
// Determine OS and execute the ping command.
if (stristr(php_uname('s'), 'Windows NT')) {
$cmd = shell_exec( 'ping ' . $target );
echo '<pre>'.$cmd.'</pre>';
} else {
$cmd = shell_exec( 'ping -c 3 ' . $target );
echo '<pre>'.$cmd.'</pre>';
}
}
?>
代碼分析
相對(duì)于Simple的源代碼,此處進(jìn)行了關(guān)鍵性的黑名單替換,對(duì)&&與;進(jìn)行了過濾,所以可以通過采用未過濾連接符( | 與 || )進(jìn)行測試。

當(dāng)然可以嘗試?yán)^續(xù)利用黑名單的&&符號(hào),可以進(jìn)行繞過操作,為了更好理解,可以添加代碼,查看效果。代碼添加部分如下

根據(jù)最后黑名單替換結(jié)果變?yōu)? '的思想,可以輸入
&;&進(jìn)行繞過,由于;進(jìn)入了黑名單,而&與第二個(gè)&和黑名單不匹配所以,可以進(jìn)行繞過。運(yùn)行效果如下

經(jīng)過測試可進(jìn)行繞過的payload有
&a& ;&-&;&+&;&_&;對(duì)于這些payload,剛開始不是很理解為什么可以執(zhí)行,通過在系統(tǒng)呢測試,可以發(fā)現(xiàn),本質(zhì)上是將中間的符號(hào)當(dāng)做命令執(zhí)行了

High級(jí)別
源代碼查看

代碼分析
相對(duì)于Simple和Medium的源代碼,對(duì)輸入內(nèi)容進(jìn)行嚴(yán)格的預(yù)處理,通過點(diǎn).將Ip地址分開,將每部分進(jìn)行判斷是否是數(shù)字。
關(guān)鍵函數(shù)
stripslashes():刪除反斜杠
反函數(shù):addslashes()函數(shù)添加的反斜杠
explode():將字符串分割后打散為數(shù)組
is_numeric():函數(shù)用于檢測變量是否為數(shù)字或數(shù)字字符串
此函數(shù)具有漏洞,常見于CTF中獲取flag時(shí)進(jìn)行與特定值比較
目前自己未發(fā)現(xiàn)有好的繞過方法,詳細(xì)可以參考資料一欄
思維擴(kuò)展
可以根據(jù)目前High級(jí)別的源碼,可進(jìn)行稍作修改,變?yōu)檎齽t表達(dá)式匹配,自己嘗試寫出的簡單WAF如下:
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
參考資料
CSDN:PHP is_numeric()函數(shù)安全漏洞
51CTO:PHP 函數(shù)漏洞原理解析
實(shí)戰(zhàn)練習(xí)
可參考文章
RCE-命令注入