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

目标网址接口:aHR0cHM6Ly9kaWN0LnlvdWRhby5jb20vd2VidHJhbnNsYXRl

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

调研接口

  • 查看每次请求的参数发现,每次请求sign参数和mysticTime参数都会变
    爬虫---某翻译响应解密和sign逆向_第1张图片

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

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

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

爬虫---某翻译响应解密和sign逆向_第2张图片

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

响应数据解密

  • 一般来说数据解密都会解密为json数据,直接去hook JSON.parse()方法
(function () {
    var my_parse = JSON.parse;
    JSON.parse = function (params) {
        console.log("HOOK parse", params);
        return my_parse(params);
    }
})();
  • 果然发现解析的数据
    爬虫---某翻译响应解密和sign逆向_第3张图片

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

爬虫---某翻译响应解密和sign逆向_第4张图片

  • 跟进参数发现是AES加密 128 cbc模式,现在只要知道key iv 就可以模拟了
    爬虫---某翻译响应解密和sign逆向_第5张图片

  • 经过跟进发现这里的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数组

爬虫---某翻译响应解密和sign逆向_第6张图片

  • 那么只需要用python还原这个函数就可以了
    爬虫---某翻译响应解密和sign逆向_第7张图片

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

爬虫---某翻译响应解密和sign逆向_第8张图片

  • python还原base64转为数组代码

    因为i数组有很多空值,所以需要在python中以None替代,发现i数组为123个元素
    爬虫---某翻译响应解密和sign逆向_第9张图片

        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逆向_第10张图片
  • 查看调用堆栈看sign参数在哪生成的

爬虫---某翻译响应解密和sign逆向_第11张图片

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

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

爬虫---某翻译响应解密和sign逆向_第12张图片

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

爬虫---某翻译响应解密和sign逆向_第13张图片

Last

爬虫---某翻译响应解密和sign逆向_第14张图片

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

你可能感兴趣的:(爬虫,javascript,爬虫)