爬虫---某翻译响应解密和sign逆向

目标网址接口:aHR0cHM6Ly9kaWN0LnlvdWRhby5jb20vd2VidHJhbnNsYXRl

  • 仅供学习交流使用,非商业用途,如有侵权,请联系删除!!!
  • 仅供学习交流使用,非商业用途,如有侵权,请联系删除!!!
  • 仅供学习交流使用,非商业用途,如有侵权,请联系删除!!!

调研接口

  • 查看每次请求的参数发现,每次请求sign参数和mysticTime参数都会变
    在这里插入图片描述

  • mysticTime参数不难看出是一个13位的时间戳

  • sign参数猜测是时间戳和一些其他参数组成的字符串进行hash之后的值

  • 查看返回的响应是一堆字母,需要解密

在这里插入图片描述

  • 为了测试自己还原的sign是不是可用,还是先解密响应数据

响应数据解密

  • 一般来说数据解密都会解密为json数据,直接去hook JSON.parse()方法
(function () {
    var my_parse = JSON.parse;
    JSON.parse = function (params) {
        console.log("HOOK parse", params);
        return my_parse(params);
    }
})();
  • 果然发现解析的数据
    在这里插入图片描述

  • 打断点定位到这个位置发现解密函数

在这里插入图片描述

  • 跟进参数发现是AES加密 128 cbc模式,现在只要知道key iv 就可以模拟了
    在这里插入图片描述

  • 经过跟进发现这里的key和iv是在原始的key上面又md5了之后获取了二进制数据转为了uint8数组来进行解密的

在这里插入图片描述

  • 继续跟进发现原始的数据解密为了一个大的uint8数组
    在这里插入图片描述

  • 尝试自己用python进行base64解码一下,发现数组不一样,说明他用了自己解码base64的方式

import base64

t1 = 'Z21kD9ZK1ke6ugku2ccWu-MeDWh3z252xRTQv-wZ6jddVo3tJLe7gIXz4PyxGl73nSfLAADyElSjjvrYdCvEP4pfohVVEX1DxoI0yhm36ysrEuPNKkODn7po6VcuUUdOhXRO9VoaHHPXgSaHRFizTx17FrMowUelZSlyO2Jp-9biXcOlcPxkntWQp1hPDqWu81kg8jzGxgjNOi75FsPNURfLQwSaoG83BqqTNs-LTrA1oUr9ozX7WYrui9n5voGo-P8tg3GMhKpjpC15FQRQZym6KbwDOTyTL8x87VIqwANWkuek5pPnzzlK6SxYY1I1le5EOpQnORyobm7rWr4gVp0cWI3W85cbXdMjaGSok8gQBF1rpqSF2c6CY-e5_Xihisj9hWT1VY472r7LxYbX8A2BkKHWr88pk_1Fwlk-wvn-Tx-heigVVSEFq1PRCzhB-JG4O6Zx_1YUZOSgrTHYAVrag2wsKExTRMZtxU4-7J3hXi8UYgNV-uLN0YvIRWZ0l6Vr-RAGBHu8UsmH2nHSCoanA6wHJbCv58RnYPws6OLsDAJWDnR0kp4Cr6Xm-P3zYVgXehfNyMBTewzDwbTXoSLK-HAIqZP-9T7MUxbN09aqa-CPS_eui99UqOhe780hIXNeSyHuTt5LY_PqhcLvPhkdmQch1RASrQBK4WYgEwiomPqHt_ap8DxDSOyhNsRFm8nFw1Ml1Tmr338WJPLYzUI51hqr85Tw0_9y_siScO098y26eSmBn58QZEjY5ip7IJiNIW93mLXx4Ftzg8LOgs4HRoBPuqu4PcAtXr652xE0Q30_roz2CnQ3Edp0HlDvo8KV7jbosXY_Sb4KWMwavSd-cebsVYKPq0ACaFj_iLXTV5zfQAIkjgJZzbY3N3pG_kfGGRw_0BTh7NeMeRmsuS0cMOgoE1GhQE2JaXH7q5X9oklIV1h60D8NaLUIHHZpjiWDML0cXYoNVQl8eQgxlO0PC129w3KSAGlZsaWbl-jEpap7rkNZsM9BhNcSKjOt8pBvQ3dQ2eDyMgJo28tNBA=='
a1 = base64.b64decode(t1)
print(list(a1))

在这里插入图片描述

  • 发现是经过,r.toByteArray方法转为了uint8数组

在这里插入图片描述

  • 那么只需要用python还原这个函数就可以了
    在这里插入图片描述

  • h函数检测字符串长度之类 i数组是一个固定生成的值

在这里插入图片描述

  • python还原base64转为数组代码

    因为i数组有很多空值,所以需要在python中以None替代,发现i数组为123个元素
    在这里插入图片描述

        def get_i():
            i = [None] * 123
            s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
            for index, a in enumerate(s):
                i[ord(a)] = index
            i[ord("-")] = 62
            i[ord("_")] = 63
            return i
    
        def h(t):
            e = len(t)
            if e % 4 > 0:
                raise "Invalid string. Length must be a multiple of 4"
            try:
                n = t.index("=")
            except ValueError:
                n = -1
    
            if n == -1:
                n = e
    
            r = 0 if n == e else 4 - n % 4
            return [n, r]
            
        def c(e, n):
            return int(3 * (e + n) / 4 - n)
            
        def base_64_2_bytes_array(t):
            # h函数
            r = h(t)
            s = r[0]
            a = r[1]
            # 用numpy创建一个全是0的uint8数组
            u = np.zeros(c(s, a), dtype='uint8')
            f = 0
            l = s - 4 if a > 0 else s
            n = 0
            # 获取i数组
            i = get_i()
            while n < l:
                e = i[ord(t[n])] << 18 | i[ord(t[n + 1])] << 12 | i[ord(t[n + 2])] << 6 | i[ord(t[n + 3])]
                u[f] = e >> 16 & 255
                f += 1
                u[f] = e >> 8 & 255
                f += 1
                u[f] = 255 & e
                f += 1
                n += 4
    
            if a == 2:
                e = i[ord(t[n])] << 2 | i[ord(t[n + 1])] >> 4
                u[f] = 255 & e
                f += 1
            elif a == 1:
                e = i[ord(t[n])] << 10 | i[ord(t[n + 1])] << 4 | i[ord(t[n + 2])] >> 2
                u[f] = e >> 8 & 255
                f += 1
                u[f] = 255 & e
                f += 1
            return u
    
    
  • 处理key和iv

    def get_md5(sb1: str):
        return hashlib.md5(sb1.encode()).digest()
    key = get_md5('ydsecret://query/key/B*RGygVywfNBwpmBaZg*WT7SIOUP2T0C9WHMZN39j^DAdaZhAnxvGcCY6VYFwnHl')
    iv = get_md5('ydsecret://query/iv/C@lZe2YzHtZ2CYgaXKSVfsb7Y4QWHjITPPZ0nQp87fBeJ!Iv6v^6fvi2WN@bYpJ4')
    
  • 解密代码

    aes_obj = AES.new(key=key, iv=iv, mode=AES.MODE_CBC)
    a1 = aes_obj.decrypt(base_64_2_bytes_array(sb1).tobytes()).decode()
    print(a1)
    

    在这里插入图片描述
    解密完之后发现还有padding,还不能进行json转换,加个unpad

    aes_obj =AES.new(key=key, iv=iv, mode=AES.MODE_CBC)
    decrypt_str = aes_obj.decrypt(base_64_2_bytes_array(sb1).tobytes())
    json_str = unpad(decrypt_str, AES.block_size, style='pkcs7').decode()
    json_data = json.loads(json_str)
    print(json_data)
    

    在这里插入图片描述


sign参数逆向

  • 直接从调用堆栈中第一行打断点
    在这里插入图片描述
  • 查看调用堆栈看sign参数在哪生成的

在这里插入图片描述

  • 堆栈跟到这发现O函数生成的sign,继续跟值

t是个时间戳,sign为h函数生成

在这里插入图片描述

继续跟值就发现sign为字符串md5之后的十六进制字符串,多试几次之后发现只有时间戳的变化

在这里插入图片描述

Last

在这里插入图片描述

果然尝试请求之后大功告成 🐔🐔🐔🐔限单杀

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值