[BJDCTF2020]Easy MD5

[BJDCTF2020]Easy MD5

打开靶机,看到一个输入框,首先尝试是不是sql注入,结果发现尝试了很多payload,都没有任何回显,只是知道了它是通过get传参的,所以我们看看响应头

image-20220715163517501

image-20220715163828230

从中我们可以看到有一段sql语句,还有一个md5函数,我们先来了解一下md5这个函数的相关知识

image-20220715164009084

这个md5函数可以根据这个row参数的不同,来返回不同格式的数据

<?php
$str = "jinx";
echo "字符串:".$str."<br>";
echo "TRUE - 原始 16 字符二进制格式:".md5($str, TRUE)."<br>";
echo "FALSE - 32 字符十六进制格式:".md5($str)."<br>";
?>

返回结果:

image-20220715164409636

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

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

我们用mysql实际演示一下

image-20220715172339444

原本有一个这样的表

然后我们直接去找pass为123的那条数据

image-20220715172416324

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

image-20220715172457151

所以我们的目的就是去寻找一个字符串,使它经过MD5加密之后的值是'or'+数字……我们这里找了一个字符串就是:ffifdyop,我们可以看一下加密之后的结果

image-20220715165256890

其实这里具体的值应该是: 'or'6但由于浏览器的原因导致了乱码

然后我们在输入框里输入'or'6之后继续,会跳出以下界面

image-20220715165622479

我们审查源代码:

$a = $GET['a'];
$b = $_GET['b'];

if($a != $b && md5($a) == md5($b)){
    

发现这里是要让我们这里传入两个不一样的参数值,但是在md5加密之后又要相等

这里就有了一个新的知识:==弱比较的时候会把两边的变量类型先转换成一样的再进行比较

而我们要做的就是让他们在转换之后的值相等,这里也有一个知识点就是0e在比较的时候会被当作科学计数法

0e6=0*10^6

1e6=1*10^6

所以我们所做的就是传入一个字符串,使它经过md5加密的值为0e开头,从而再转换类型的时候会被当成是0,从而相等

这里有一些字符,在加密之后为0e开头:

原值:QNKCDZO 加密后的值:0e830400451993494058024219903391 240610708 0e462097431906509019562988736854 s878926199a 0e545993274517709034328855841020 s155964671a 0e342768416822451524974117254469 s214587387a 0e848240448830537924465865611904 s214587387a 0e848240448830537924465865611904 s878926199a 0e545993274517709034328855841020 s1091221200a 0e940624217856561557816327384675

所以我们这里就可以往a和b当中随便传两个上述的值就可以

image-20220715170817684

其实这里还有一种绕过的方法就是传入两个不同的数组变量,因为md5函数不能对数组变量进行加密,如果传进去的是数组变量,就会返回NULL,这个时候弱比较的值也是会相等的,这里要注意的是a[]和b[]的值也要是不相等的才行

image-20220715171017928

传进去之后页面上就出现了一段代码,我们也同样进行审计

image-20220715171237248

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

highlight_file(__FILE__);

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

这里的逻辑和上面的差不多,不过这里的比较改成了前面改成弱比较,后面是强比较,前面是弱比较,我们就不能使用之前那种使它的值为0e开头的那种方法,只能通过传递数组的方式来使他们的弱比较的值不相等,使它们经过md5之后的值又相等

image-20220715171643447

image-20220715171647926

posted @ 2022-07-15 17:30  Jinx8823  阅读(282)  评论(0编辑  收藏  举报