美文网首页js css html
【网络安全】记一次数据包解签名实战

【网络安全】记一次数据包解签名实战

作者: H_00c8 | 来源:发表于2022-04-14 18:15 被阅读0次

    声明:系统为授权测试,本文所提供的信息学习研究或自查使用,切勿用于非法用途,由于传播,利用此文所提供的信息而造成的任何直接或间接的后果和损失,均由使用者本人负责,本文作者不承担任何责任。

    前言

    来了一个测试项目,启动burp开始日常操作后,很快就发现事情不太对劲,应用系统使用数据包签名用于数据防篡改,本文主要介绍寻找签名算法和实现自动化签名的过程。

    找签名算法

    观察http请求包后发现发现有sign字段,应该是对请求内容做了签名防篡改,签名破解不了,也就没法开始后面的业务测试。

    image.png

    从burp里找到该接口对应的html页面,在浏览器访问该页面,打开F12源代码里进行搜索,根据经验尝试对请求里的sign、reqno这几个参数进行反查,最终确定到这一段可疑代码。

    image.png

    代码是看不懂滴,能调就调,530行下断点,刷新下网页,可以看到,c是由http body、reqNo、reqTime组成,t是一段字符串,m不知道是个什么函数。

    i=m()(c+t)
    "sign":i
    
    image.png

    先试试hash算法,命中了md5。

    image.png

    【相关技术资料】
    1、网络安全学习路线
    2、电子书籍(白帽子)
    3、安全大厂内部视频
    4、100份src文档
    5、常见安全面试题
    6、ctf大赛经典题目解析
    7、全套工具包
    8、应急响应笔记

    自动化签名

    现在已知了sign的计算方法,但如果不能实现自动改签名的话,会给后面手动测试和工具扫描带来很大的麻烦,现在有两条路:

    1、写burp插件

    2、代理脚本

    3、xray插件?

    第1种:通用性可能不行,需要能兼容我burp里各种插件,还要能用于后面的漏扫工具,况且我也不会jvav。

    第2种:最终找到了mitmproxy这个工具,能自定义python脚本,可以满足站在burp背后工作的需求。

    image.png

    开始写mitm的py脚本。

    #!/usr/bin/python
    # coding: UTF-8
    # author: DF2L
    # https://docs.mitmproxy.org/stable/api/events.html
    # https://www.jianshu.com/p/036e5057f0b9 常见接口
    
    from mitmproxy import ctx, http
    import hashlib
    import json
    
    def md5(str):
     m5 = hashlib.md5()
     m5.update(str.encode('utf-8'))
     return m5.hexdigest()
    
    def chenchen(a, b, c, d):
     plaintext = "reqData={http_body}&reqN0={reqno}&reqTime={reqtime}{SecretKey}".format(http_body=a, reqno=b, reqtime=c, SecretKey=d)
     Sign = md5(plaintext)
     return Sign, plaintext
    
    class Modify:
    
     def request(self, flow):
      if flow.request.method == "POST" and flow.request.host == "www.example.com":
       try:
        #http_body = flow.request.raw_content.decode('utf-8')   # byte => str
        http_body = flow.request.get_text()         # 获取json,dict类型
        #http_body = json.dumps(http_body, sort_keys=False, separators=(',', ':'))    # dict格式转字符串,去空格,按key排序
        reqno = flow.request.headers["reqno"]
        reqtime = flow.request.headers["reqtime"]
        SecretKey = 'abcdefgabcdefgabcdefg'
        ori_sign = flow.request.headers["sign"]
        self.new_sign, self.plaintext = chenchen(http_body, reqno, reqtime, SecretKey)
    
        if http_body != '{}':
         flow.request.headers["sign"] = self.new_sign
         ctx.log.info('\n接口地址:{}\n更新签名:{} => {}\n签名内容:{}\n'.format(flow.request.path, ori_sign, self.new_sign, self.plaintext))
        else:
         ctx.log.info('无参数无需改签')
       except KeyError as e:
        ctx.log.info('数据包无签名')
    '''
    请求字段:flow.request
     host字段:flow.request.host
     url字段:flow.request.url
     path字段:flow.request.path
     cookie字段:flow.request.cookies
     body字段:flow.request.urlencoded_form、.get_text()、.raw_content
     整个请求包:flow.request.data
    '''
     def response(self, flow):
      if '渠道验签异常' in flow.response.get_text():
       ctx.log.error('\n签名异常:\nurl => {}\n异常信息 => {}\n'.format(flow.request.path, flow.response.get_text()))
    '''
    响应字段:flow.response
    响应body json:flow.response.get_text()
    '''
    
    addons = [
        Modify()        # 加载类
    ]
    
    image.png

    mitmdump启动,good! (看起来很顺利,其实调了一年 - -。)

    mitmdump.exe -p 7788 -s .\X-sign2.py --flow-detail 0
    
    image.png

    插曲

    后面刚准备套娃上xray,结果命令行异常弹刀怀疑人生。

    image.png

    回到burp查看这些异常的接口,手动算和程序算的值确实不一样,猜想某些特定接口是不是用了不同的secret。通过对比验签成功和失败的数据包后,发现了一个可疑的请求头Appkey,验签成功的是100301,而失败的都是100101,所以两套验签应该没跑了。

    用同样的方法开始调试找签名内容,发现格式是一样的,只是拼接的字符串不一样。

    image.png

    验证正确,后面发现直接改Appkey,强制请求去第一套网关验签也是可行的。。。。

    image.png

    ok,再改改mitmdump脚本,另外由于服务端会校验时间戳是否过期,但不向上校验,所以直接把时间戳拉满写死,便于后面重放复现。

    image.png

    开始套娃:App => Burp => xray => mitmdump => Server

    burp:User options -> Upstream Proxy Servers -> 指向xray

    xray:

    # 启动监听
    .\xray_windows_amd64.exe webscan --listen 127.0.0.1:7777 --html-output report-__datetime__.html
    # config.yaml 配置代理
    http: 
        proxy: "http://127.0.0.1:7788"
    

    mitmdump:

    # 启动监听
    mitmdump.exe -p 7788 -s .\X-sign.py --flow-detail 0
    

    套完之后,可以看到已经成功跑起来!

    image.png

    总结

    这次的破解签名算法还是比较顺利的,简单回顾下过程:

    1、找签名算法。

    2、用py实现一个demo。

    3、寻找自动化工具mitmdump,调试脚本。

    4、处理异常,完善脚本。

    5、串联xray,over。

    数据包签名做防御机制还是很大程度的提升了攻击成本,当然没有绝对的安全,而企业能做的就是不断提高防御水平,缩小暴露风险面,从而提高攻击者的攻击成本。

    相关文章

      网友评论

        本文标题:【网络安全】记一次数据包解签名实战

        本文链接:https://www.haomeiwen.com/subject/vzotertx.html