Subject
PHP 代码审计
Mind Palace
打开题目:
查看网页源代码获得提示:
URL后面加上source.php,获得需要审计的代码:
思路
<?php
// 重點的內容:
// in_array() mb_substr() mb_strpos()
// in_array — Checks if a value exists in an array | 檢查
// mb_substr — Get part of string | 切割字符串
// mb_strpos — Find position of first occurrence of string in a string | 定位
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;
}
// 1. 判斷變量 page 是否存在於白名單
if (in_array($page, $whitelist)) {
return true;
}
// 變換1 => $page -> $_page
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
// 2. 判斷變量 _page 是否存在於白名單
if (in_array($_page, $whitelist)) {
return true;
}
// 變換2 => $_page -> $_page
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
// 3. 判斷變量 _page 是否存在於白名單
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}// class: emmm
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file']; // $_REQUEST['file'] ==> 需要通過三項檢測
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
- 代码审计后找到的重点是:emmm类中checkFile中含有三个if审查
- 三个if审查中一个return true之后就可以携带payload获取flag
- 第一个if肯定无法return true;因为含有payload的
$page一定不在白名单之中 - 考虑第二个or第三个if审查中构造可以通过白名单并携带了payload的
$_REQUEST['file'] url/hint.php中获得提示ffffllllaaaagggg=> 可能是向上四次穿透
Payload
(1) Linux服务器中文件夹可以含'?'(在第二次if审查即可通过白名单):
Payload1 ==> ?file=source.php?/../../../../ffffllllaaaagggg
(2) Windows中文件夹不可以含'?'(在第三次if审查中通过白名单|%253F经过url解码两次解码回字符串'?'):
Payload2 ==> ?file=source.php%253F/../../../../ffffllllaaaagggg
Look Ahead
代码审计的题目一定要了解关键函数/代码块的功能;抓最重点
END ψ(`∇´)ψ