猿人学二十题 js 逆向分析

查看 19|回复 2
作者:chocolate.   
猿人学第二十关逆向分析教程
[原创] 猿人学学员题34题 js加课例题1 逆向分析
还原“猿人学 第20关”中加密参数 sign 的生成逻辑,最终用 Python 脚本模拟访问接口。
分析地址:aHR0cHM6Ly9tYXRjaC55dWFucmVueHVlLmNuL21hdGNoLzIwIw==
 第一步:抓包定位 sign 参数
F12 打开 DevTools,观察 Network 请求


image-20250707142338096.png (140.04 KB, 下载次数: 0)
下载附件
2025-7-7 15:27 上传

易 第二步:断点调试找加密函数

  • 在浏览器中找到 sign 的调用


    image-20250707142447212.png (341.34 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:28 上传



    image-20250707142503175.png (363.32 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:28 上传

  • 下断点进入内部方法,最终定位到调用 _index_bg_wasm__WEBPACK_IMPORTED_MODULE_0__["sign"](retptr, ptr0, len0); 的过程


    image-20250707142615626.png (410.3 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:28 上传

    这里可以看出是使用的wasm加密

     第三步:进入 WASM 找明文
  • 打断点观察指针值



    image-20250707142707404.png (596.45 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:29 上传

    下个断点,找到加密方法


    image-20250707142731094.png (633.51 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:29 上传

    直接复制所有的加密方法,扔给ai


    image-20250707142845195.png (523.81 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:29 上传

    这里我们看到具体的加密方法为match_twenty__sign,找一下对应位置
    call $match_twenty::sign::h5787c0a9b8e619b6
    下断点进入到具体的方法里


    image-20250707143005687.png (450.32 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:30 上传



    image-20250707143042317.png (649 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:30 上传

    同样的复制内容给ai


    image-20250707143428036.png (438.98 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:30 上传

    然后找到对应的加密方法(wasm中对应的位置)


    image-20250707143522857.png (434.5 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:30 上传

    在这里下断点
    查看


    image-20250707143616996.png (489.43 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:31 上传

    往下找一下,发现有个md5字样,打上断点


    image-20250707145803940.png (789.29 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:31 上传

    查看方法上方这三个变量的值,分别为
    value: 1048504
    value: 1114192
    value: 31
    这里应该就是未加密之前的数据,第一个值是返回值,第二个值为明文,第三个值为偏移量,下面重新进入到
    function sign(content) {
        try {
            const retptr = _index_bg_wasm__WEBPACK_IMPORTED_MODULE_0__["__wbindgen_add_to_stack_pointer"](-16);
            var ptr0 = passStringToWasm0(content, _index_bg_wasm__WEBPACK_IMPORTED_MODULE_0__["__wbindgen_malloc"], _index_bg_wasm__WEBPACK_IMPORTED_MODULE_0__["__wbindgen_realloc"]);
            var len0 = WASM_VECTOR_LEN;
            _index_bg_wasm__WEBPACK_IMPORTED_MODULE_0__["sign"](retptr, ptr0, len0);
            var r0 = getInt32Memory0()[retptr / 4 + 0];
            var r1 = getInt32Memory0()[retptr / 4 + 1];
            return getStringFromWasm0(r0, r1);
        } finally {
            _index_bg_wasm__WEBPACK_IMPORTED_MODULE_0__["__wbindgen_add_to_stack_pointer"](16);
            _index_bg_wasm__WEBPACK_IMPORTED_MODULE_0__["__wbindgen_free"](r0, r1);
        }
    }
    方法,然后进入


    image-20250707150023823.png (490.89 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:31 上传

    因为浏览器也是要通过指针进行读值的,可以借助浏览器的方法,查看上方获取到的数据
    function getStringFromWasm0(ptr, len) {
        return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
    }
    在控制台替换值并输入
    cachedTextDecoder.decode(getUint8Memory0().subarray(1114192, 1114192 + 31))
    就可以获取到加密前的明文


    image-20250707150241062.png (69.4 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:31 上传

  • 找到 sign(ptr, len) 所使用的明文地址
  • 用浏览器控制台的 getStringFromWasm0 方法查看明文

    cachedTextDecoder.decode(getUint8Memory0().subarray(1114192, 1114192 + 31))
    ✍️ 第四步:测试提交
    def generate_sign(page, timestamp):
        sign_string = f"{page}|{timestamp}D#uqGdcw41pWeNXm"
        return hashlib.md5(sign_string.encode()).hexdigest()


    image-20250707152209001.png (461.34 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:31 上传



    image-20250707151223926.png (690.02 KB, 下载次数: 0)
    下载附件
    2025-7-7 15:32 上传

    下载次数, 下载附件

  • taizi008   

    坐个沙发 感谢分享
    freesaber   

    666,关键还是看ai,混淆过的,自己分析,头都大了
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部