梳理思路
打开网站,发现很简单,只有flag在哪里的字样。
查看源码,常用后台目录,robots.txt,都未发现有任何东西。
扫描
直接拉进扫描器一扫,发现
思考可能是git源码泄露,可能可以恢复源码。github上有很多优秀的git恢复工具。在这里推荐两款:Git Extract 和githack。都支持differ更改后的文件,这点很重要,有些ctf比赛题会更改文件,如果你的git恢复工具不带的话,只能获取未修改前的数据,无法获取完整源码
使用Git Extract,获取了源码:
<?php include "flag.php"; echo "flag在哪里呢?<br>"; if(isset($_GET['exp'])){ if (!preg_match('/data://|filter://|php://|phar:///i', $_GET['exp'])) { if(';' === preg_replace('/[a-z,_]+((?R)?)/', NULL, $_GET['exp'])) { if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) { // echo $_GET['exp']; @eval($_GET['exp']); } else{ die("还差一点哦!"); } } else{ die("再好好想想!"); } } else{ die("还想读flag,臭弟弟!"); } } // highlight_file(__FILE__); ?>
代码审计
发现这句代码
if(';' === preg_replace('/[a-z,_]+((?R)?)/', NULL, $_GET['exp']))
很经典的正则匹配无参数RCE,大概解释一下就是:
(?R)?表示引用当前表达式一次或多次。即可以变成w+(w+((?R)?)),w+(w+(w+((?R)?))),等等在(?R)?中无限套娃的情况。
所以只能让参数=一个函数,或函数包含函数的情况
方法网上也总结了很多,我在这就不再讲原理,稍微梳理一下:
RCE:
- http头传参(session)
- GET/POST传参
读取文件:
- 函数读取
但本题又过滤了很多字符串,导致无法使用,所以只讲第一种方法
解题
- http头传参(session)
总结思路
- 因为打开网址后发现没什么东西,首先思考有无后台,扫描器可否扫描出来
- 代码审计,要知道那一句话是无参数RCE,只能使用套娃类函数
- session_id可以获取会话id,通过此方法达到传参的目的(此方法在其他题目上是否也可以运用还在尝试)
知识点
- 信息泄露
- 代码审计(无参数RCE)