[BJDCTF2020]Easy MD5(详细)

[BJDCTF2020]Easy MD5(详细)

这一题也是挺多知识点的。

1.打开网站,发现输入啥都没变化:
[BJDCTF2020]Easy MD5(详细)_第1张图片
2.看到响应头有提示,应该是绕过md5进行注入了:
[BJDCTF2020]Easy MD5(详细)_第2张图片
3.这里有个很离谱的点,我是真的没想到:
         md5函数在指定了true的时候,是返回的原始 16 字符二进制格式。也就是说会返回这样子的字符串:'or’6\xc9]\x99\xe9!r,\xf9\xedb\x1c(抄的= =)
         然后就会拼接成:
(题目的提示感觉还是有点问题的,因为md5函数返回的是字符串,后端应该会用单引号/双引号包起来的),所以应该会拼接为这样子:

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

这就是永真的了。接下来就是找到这样子的字符串。

我是想用python3跑出来的,但是有些麻烦,php写了个,但是跑了十几次,一个没出来(代码应该是没问题的吧,因为直接赋值为答案是可以的)。如果遍历的话= =比如答案里面的8位数,那就是26^8=208827064576!!!:


function getRandStr($length) {  
	$str = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 
	$randString = ''; 
	$len = strlen($str)-1; 
	for($i = 0;$i < $length;$i ++){ 
		$num = mt_rand(0, $len); 
		$randString .= $str[$num]; 
	} 
	return $randString ;  
}
for($i=8; $i<10; $i++){
	for ($j=1; $j<100000; $j++){
		$test=getRandStr($length=$i);
		$dddd = md5($test,TRUE);
		$find = "'or'";
		$retur = stripos($dddd,$find);
		if ($retur > 0 || $retur ===0) {
		    echo $dddd;
		    echo "\n";
			echo $test;
			echo "\n";
		}
	}
}
?>

WP里面就是给的 ffifdyop 。我直接用好了= =心累。

4.输入进去,发现跳转到了另一个界面:
[BJDCTF2020]Easy MD5(详细)_第3张图片
5.查看源代码:
[BJDCTF2020]Easy MD5(详细)_第4张图片
真碰撞的话是比较难的了,还有另外两种方法:

(1)找出md5值都是两个0e开头的开头的。原理是php里面在做 == 的时候会先把两边的类型转成一样的,因为是0e开头,php会认为它是科学技计数法,而0的多少次方都是0。
举例:
QNKCDZO
s155964671a
s1091221200a
等等…
示例:
[BJDCTF2020]Easy MD5(详细)_第5张图片

(2)数组绕过。原理是md5等函数不能处理数组,导致函数返回Null。而Null是等于Null的,导致了绕过。看下面的示例,是返回了yes的。(题目中就传入    ?a[]=1&b[]=2    )
[BJDCTF2020]Easy MD5(详细)_第6张图片
6.又来到一个新页面,这里和上面的不同就是用了===。这里就不存在上面的第一种绕过了,但是依然可以用第二种方法绕过。
在这里插入图片描述

(因为这些在审计的时候也要注意,我也放在审计里面了= =)

你可能感兴趣的:(CTF,代码审计)