zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    完美解决CTRL+空格不能切换中/英文输入法的问题
    【Delphi内联汇编学习1】Delphi与汇编
    替换bmp图片中的颜色 good
    将四个BYTE数值转换成IEEE754标准的浮点数(两种方法:用Addr函数取字节数字的首地址,或者用Absolute关键字)
    在delphi的exe文件中嵌入另外一个exe文件
    Qt中的串口编程之三
    使用MIDAS访问远程Access数据库
    QSqlDatabase的进一步封装(多线程支持+更加简单的操作)——同时支持MySQL, SQL Server和Sqlite
    Qt for Linux:环境搭建(CentOS 6.5 32位)——完全从零安装
    Qt for Windows:使用WinPcap开发高性能UDP服务器
  • 原文地址:https://www.cnblogs.com/huim/p/8486104.html
Copyright © 2011-2022 走看看