sha1和md5函数漏洞

sha1函数和md5函数比较绕过

在CTF比赛中经常遇到利用sha1()和md5()函数漏洞的题,先看一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
 <?php  
require 'flag.php';

if (isset($_GET['name']) and isset($_GET['password'])) {
if ($_GET['name'] == $_GET['password'])
print 'Your password can not be your name.';
else if (sha1($_GET['name']) == sha1($_GET['password']))
die('Flag: '.$flag);
else
print '<p class="alert">Invalid password.</p>';
}
?>

GET了两个参数name和password,获得flag要求的条件是:name != password & sha1(name) == sha1(password)

此时就可以利用sha1()函数的漏洞来绕过。如果把这两个字段构造为数组,如:

name[]=a&password[]=b

这样在第一处判断时两数组确实是不同的,但在第二处判断时由于sha1()函数无法处理数组类型,将报错并返回NULL,if 条件成立,获得flag。

经验证md5()函数同样存在此漏洞。

md5加密相等绕过

题目代码:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
$md51 = md5('QNKCDZO');
$a = @$_GET['a'];
$md52 = @md5($a);
if(isset($a)){
if ($a != 'QNKCDZO' && $md51 == $md52) {
echo "flag{*}";
} else {
echo "false!!!";
}}
else{echo "please input a";}
?>

输入的参数不等于QNKCDZO,但是md5('QNKCDZO')==md5($a)

md5(‘QNKCDZO ‘)=0e830400451993494058024219903391

而0e 开头且后面都是数字会被当作科学计数法,也就是等于 0*10^xxx=0

如果md5 是以 0e 开头,在做比较的时候,便可以用这种方法绕过

1
2
3
4
5
6
md5(s878926199a)=0e545993274517709034328855841020
md5(s155964671a)=0e342768416822451524974117254469
md5(s214587387a)=0e848240448830537924465865611904
md5(s1091221200a)=0e940624217856561557816327384675
md5(s1885207154a)=0e509367213418206700842008763514
md5(s1502113478a)=0e861580163291561247404381396064

以上这些都可以使用

解题方法:

GET请求:?a=s878926199a 即可获得flag