buu第一題。
get到的知識:
- ?二次編碼的文件會被當成目錄(phpmyadmin4.81的漏洞);
- 一個新的繞過姿勢;
題目:
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
} //檢測傳入的page變量是否為空
if (in_array($page, $whitelist)) {
return true; // 檢測page變量是否在白名單中
}
$_page = mb_substr( //第一次?截斷。具體的語法見下文
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true; //檢測一次?過濾后的變量是否在白名單里
}
$_page = urldecode($page); //二次解碼 關鍵步驟
$_page = mb_substr(
$_page, //第二次?截斷
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true; //檢測第二次?過濾后的變量是否在白名單里
}
echo "you can't see it";
return false;
}
}
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\" />";
}
?>
思路分析:
代碼的總體思路已經寫在注釋里了。這里主要有兩個點要注意:
- ?過濾中的php函數:
mb_substr():跟substr()差不多,截取目標串的相關區間的字符串。
mb_strpos():返回要查找的字符串在別一個字符串中首次出現的位置。
- 關于?的二次編碼:
簡而言之,就是:如果我們對?進行二次編碼/解碼(傳入url時解碼一次,上文的代碼中urldecode函數解碼一次),那么所被包含的名稱就會被認為是一個目錄(文件夾)而不是一個特定的文件。
payload的構造和相關分析:
?file=hint.php?../../../../../ffffllllaaaagggg
- 前面的問號是為了使file在檢測中被截斷為hint.php,從而繞過白名單。
- ../../../../是因為傳入的的hint.php被當作是一個目錄,需要多個../去跨目錄。具體是幾層,大概是自己試出來的?
參考:
2.對于這個漏洞的詳細分析:
https://blog.csdn.net/Mikasa_/article/details/88594749
浙公網安備 33010602011771號