Parse_str()函数引发的变量覆盖漏洞php
parse_str() 函数用于把查询字符串解析到变量中,若是没有array 参数,则由该函数设置的变量将覆盖已存在的同名变量。 极度不建议 在没有 array参数的状况下使用此函数,而且在 PHP 7.2 中将废弃不设置参数的行为。此函数没有返回值
1、分析题目源码:html
一、 error_reporting()函数规定不一样级别错误,这里为关闭错误报告ide
二、 show_source()函数,别名highlight_file()高亮显示文件。函数
三、 empty()函数姜茶一个变量是否为空,因此动咱们发送请求的时候必定带有id参数测试
四、 include(‘flag.php’)调用flag.php文件,应该就是存放flag的文件加密
五、 @parse_str($id)把查询字符串解析到变量中,没有使用array选项,如有同名变量,将原来的覆盖。这里明显将原来的$a的值给覆盖掉。3d
六、 $a[0] != 'QNKCDZO' && md5($a[0]) == md5('QNKCDZO')判断$a[0]的值不是QNKCDZO而且$a[0]的MD5值要和QNKCDZO的MD5值相同。咱们知道很难找出这样的字符串。code
2、构造咱们的payloadhtm
总体源码已经分析过了,如今惟一要作的就是须要找出字符串不一样,但MD5值相同的值。这很难找出。这个时候能够利用php处理MD5哈希字符串的缺陷进行处理。blog
缺陷的原理:利用php弱语言特性。“10”==“1e1”吗?这样看是不等于的,可是到了php处理的时候,他会将1e1看作科学计数法来计算1e1=1*10^1=10,那这样是否是就相等了。
题目这里给出的QNKCDZO的MD5值为:0e830400451993494058024219903391。通过php处理后会认为0*10^n。因此结果为零。
因此,咱们能够找到字符串MD5加密后结果开头为0e的便可。这里有篇文章记录了不少这样的字符串:http://www.cnblogs.com/Primzahl/p/6018158.html
因此咱们的payload为
?id=a[]=s878926199a(s878926199a的MD5值为0e开头的字符串)
3、测试结果。
将payload用get方法传输:
获得flag哈。