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
