进入靶场后查看head

hint中有查询语句,可以构造万能密码来绕过

select * from 'admin' where password=''or'6.......'

这里可以使用ffifdyop
ffifdyop——绕过中一个奇妙的字符串
ffifdyop经过md5加密后为:276f722736c95d99e921722cf9ed621c
再转换为字符串:

'or'6<乱码> 即 'or'66�]��!r,��b

这个字符串前几位刚好是 'or'6,而 Mysql 刚好又会吧 hex 转成 ascii 解释,因此拼接之后的形式是select * from 'admin' where password='' or '6xxxxx'等价于 or 一个永真式,因此相当于万能密码,可以绕过md5()函数
进入这一步查看源码

$a = $GET['a'];
$b = $_GET['b'];
if($a != $b && md5($a) == md5($b)){
    // wow, glzjin wants a girl friend.

典型MD5弱比较
可以通过两种方法绕过
1、数组?a[]=1&b[]=2
md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的。
2、MD5碰撞一些0e值 在弱类型比较过程中。
被php当成科学计数法的,计算,所以结果都是0,比较时会相等
相当于0e830==0e462;true
QNKCDZO 的md5值为 0e830400451993494058024219903391
240610708 的md5值为 0e462097431906509019562988736854

绕过后进入第三步

<?php
error_reporting(0);
include "flag.php";

highlight_file(__FILE__);

if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
    echo $flag;
}

这里不能用第二种方法来绕过了,这里可以使用第一种数组来绕过,具体原因是因为前面用了!==,后面用了===,在比较的时候不会将其当做科学计数法了。

构造payload
POST
param1[]=1&param2[]=2
即可得到flag

这里我们要做的就是,假如我们转递进去的内容经过这个md5加密之后的结果为'or'+一段内容并且在or后面加的这一段内容为true,在这种条件下就可以实现那个select * from 'admin' where password=md5($pass,true)sql语句的注入

并且这里还有一个知识点就是在mysql当中只要or后面的内容为数字+字符串也就是or 1……这样之后返回的值就为true

mysql中演示

我们用mysql实际演示一下

原本有一个这样的表
然后我们直接去找pass为123的那条数据

然后再用or连接'数字+字符串'的查询语句,可以发现,确实查出了所有的语句,证明了只要or后面+(数字+字符串),返回结果就为true

最后修改:2022 年 11 月 27 日
如果觉得我的文章对你有用,请随意赞赏