首先进入题目环境,检查页面、页面源代码、以及URL:
发现页面无异常。
使用 dirsearch 扫描网站,检查是否存在可访问的文件或者文件泄露:
发现 可访问界面/templates/ 以及 .git文件泄露,故使用 GItHack 来查看泄露的 .git 文件:
首先查看flag.php文件,检查是否存在flag的信息:
发现没有关于 flag 的信息,于是改变思路,查看 index.php 中的源代码,检查有用信息:
在这里只截取源代码中的PHP代码演示,html不做演示
<?php
if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = "home";
}
$file = "templates/" . $page . ".php";
// I heard '..' is dangerous!
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
// TODO: Make this look nice
assert("file_exists('$file')") or die("That file doesn't exist!");
?>
<div class="container" style="margin-top: 50px">
<?php
require_once $file;
?>
</div>
观察到代码中存在 assert() 函数,猜测从 assert() 函数入手:
strops('$file', '..') === false:
判断变量 $file 中是否存在 '..'字样,主要目的为了防止用户进行 ../../etc/passwd 等指令来进行非法操作。
assert()函数:
在PHP中,
assert()
函数用于在代码执行过程中对一个表达式进行断言,以确保其为真。如果表达式返回false,则会抛出一个 AssertionError,并且脚本的执行将会中止。语法 assert(参数一,参数二):
参数一:需要进行断言的表达式
参数二:(可选参数),用于在断言返回结果为 False 时输出错误信息。
构造payload: ?page=123')%20or%20system("cat%20templates/flag.php");//
可以达到类似于SQL注入的闭合效果:
通过利用 // 将后方代码注释,最终有效的PHP语句只剩下 system("cat%20templates/flag.php");
提交payload,页面回显如下:
没有回显flag值,查看页面源代码:
发现flag,成功拿到flag值。