BUUCTF-Web-[WUSTCTF2020]朴实无华
本文为记录个人信安小白的刷题路程,大佬勿喷,也同时希望文章能对您有所帮助
打开靶机,发现一个warning
,提到了header
,用Burp抓包看看请求头,
没有发现什么有用的信息,用dirsearch扫描网站,
访问robots.txt
,
访问fAke_flagggg.php
,
到这又卡住了,想起来header
,
这次有信息了,
访问fl4g.php
,
看到源码了,但是有一些乱码,按住Alt
键,网页上方会出现查看
的选项,然后选择修复编码文字,
进行代码审计,
1 |
|
总共有三关需要绕过
PHP弱类型比较
1 | if (isset($_GET['num'])){ |
intval()
函数将变量转换为整数。但它有一个特性:如果转换失败(例如,字符串开头不是数字),它会返回0
。
这里的关键是$num + 1
。这里用的是+
(算术运算符),而不是.
(字符串连接符)。当$num
是一个字符串时,PHP会尝试将它转换为数字再进行计算。如果字符串以数字开头,就取前面的数字部分;如果不是,则转换为0
。
payload:
1 | ?num=1e10 |
?num=1e10
// 1e10
表示1
乘以10的10次方,即10000000000intval('1e10')
:字符串'1e10'
转换成整数,只会取到第一个非数字字符e
之前的部分,所以结果是1
。1 < 2020
成立。'1e10' + 1
:PHP会将字符串'1e10'
识别为浮点数10000000000
,然后加1
,结果是10000000001
。intval(10000000001)
结果是10000000001。10000000001 > 2021
成立。
MD5哈希碰撞 (弱比较)
1 | if (isset($_GET['md5'])){ |
payload:
1 | ?md5=0e215962017 |
==
是弱比较。如果比较一个字符串和MD5哈希值(32位16进制数),PHP会尝试将双方转换为数字再进行比较。
MD5哈希值是一个以字母开头的字符串(例如 md5(‘abc’) 是 900150983…),当它被当作数字时,值会是 0。
所以,我们需要找一个字符串,它的MD5哈希值经过弱类型比较后,等于它自身。更准确地说,我们需要:$md5
和md5($md5)
在弱比较下都等于0
。md5('0e215962017') = 0e291242476940776845150308577824
字符串:0e215962017
(弱比较 == 0
)
其MD5:0e291242476940776845150308577824
(弱比较 == 0
)
所以:0 == 0
成立,条件满足。
命令注入绕过
1 | if (isset($_GET['get_flag'])){ |
绕过空格:${IFS}
:IFS
是内部字段分隔符,默认是空格。
绕过cat
过滤:
使用其他命令读取文件:
1 | more |
最终payload:
1 | ?num=3e10&md5=0e215962017&get_flag=ls //获得flag文件位置 |
获得flag