[HCTF 2018]WarmUp 1
审题
- 观察题目,查看源代码,看到source.php。
- 访问,看到源代码。
知识点
PHP的代码审计,include函数的应用,文件包含漏洞。
代码审计
<?phphighlight_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 = ["source"=>"source.php","hint"=>"hint.php"];if (! isset($page) || !is_string($page)) {echo "you can't see it";return false;}
这一部分有两个作用
- 定义$whitelist参数,也就是我们常说的白名单。
- 是判断传入的$page参数是否存在,并且是否为字符串。如果不满足这两个条件中的任意一个函数就会返回false。
第二部分:
if (in_array($page, $whitelist)) {return true;}
这个部分的内容很简单,就是判断page参数是否等于白名单里的内容,如果等于就返回true。
第三部分:
$_page = mb_substr($page,0,mb_strpos($page . '?', '?'));if (in_array($_page, $whitelist)) {return true;}
这一部分也分为两部分
- 使用mb_substr函数让page参数中?之前的字符串被截取,后面的字符消失。
- 让被截取后的$page参数和白名单匹配,如果相等返回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;}
这一部分和第二部分十分像,只是在开头加了一个url解码。
file获取(可以看成C语言中的main函数)
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不为空,
- 判断是否为字符串
- 是否可以通过emmm类中的checkFile函数,也就是让它返回true。
- 如果以上条件都通过就进行include函数,include函数可以调用php文件从而形成安全隐患。
解题
在看到代码后可以发现还有一个hint.php,访问后得到flag在ffffllllaaaagggg文件中
经过上面的代码审计之后,我们可以很容易的看到file函数构造的要求。
- 不为空
- 要是字符串
- 通过emmm返回ture
- 让include访问ffffllllaaaagggg文件
emmm中
第一部分也是判断
第二部分要求page本身就是source.php或者hint.php
第三部分可以通过问号来截取符合要求的部分,可以利用。
第四部分同理,将第三部分的答案ulr加密后也可以利用。
最后使用/让source.php?或者hint.php?成为不存在的目录,再用…/跳转到ffffllllaaaagggg文件就行。
**tip:正常情况下,URL 的路径部分表示要访问的文件或目录的路径。当 URL 中的路径部分以斜杠 “/” 结尾时,服务器通常会将其解析为目录而不是文件。然而,如果在该斜杠后面紧跟查询参数,如 “source.php?/”,服务器会将其视为一个文件路径,并尝试查找名为 “source.php?” 的文件。然而由于这个目录不存在就会被看成一个不存在的目录。 **
最后得到答案file=hint.php?/…/…/…/…/ffffllllaaaagggg或者source.php?/…/…/…/…/ffffllllaaaagggg。
**tip:…/一定要大于4个,可以多不能少,如果少了无法跳转到flag目录 **