【JS逆向】某土地市场网逆向分析

查看 111|回复 11
作者:littlewhite11   
逆向目标
  • 网址:aHR0cHM6Ly93d3cubGFuZGNoaW5hLmNvbS8jLw==
  • 目标:反调试及请求头Hash

    反调试
    进入网站,我们会发现F12无法打开控制台。那就换一种方式,以谷歌浏览器为例设置 -> 更多工具 -> 开发者工具,然后网页就会跳到空白页了,这是除了debugger外一种经典的反调试手段。
    那么我们如何过掉这个反调试呢?目前,我遇到的就两种情况,第一种就是window.close(),第二种就是location.href = '',还有其他情况的话欢迎各位大佬补充。
    下面直接开始分析:
    我们用无痕浏览器分析(因为在Script断点时不会加载插件的JS代码),打开控制台,勾上Script断点,输入网址,成功断住。


    1.png (49.12 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:29 上传

    然后我们先搜索window.close,F8一直走,之后某个文件出现了相关代码,直接下断。


    2.png (20.34 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:29 上传

    然后放开Script断点,直接F8过掉,成功在断点处停住。


    3.png (18.62 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:29 上传

    我们往前跟栈,看网站通过什么手段进行的反调试。可以看到,是e > 10 * this.maxPrintTime这个条件成立才触发this.onDevToolOpen,从而触发后续的window.close


    4.png (45.25 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    那我们就看看代码具体做了什么,我们在前面的e和r处下断,重新请求,成功断住。


    5.png (18.78 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    然后我们单步跟进去m函数,可以看到,先取了一下时间戳,然后调用传进的参数,最后再返回参数调用的时间差,那猫腻肯定是出现在传入的函数中了。


    6.png (10.61 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    我们直接进入被调用的参数函数中,可以看到t.largeObjectArray是一个大对象,b其实是console.table函数,也就是在控制台打印一个大对象。


    7.png (21.27 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    那反调试的逻辑大体清楚了:如果打开了控制台,就会通过console.table打印一个很大的对象,这就需要消耗时间,后续e > 10 * this.maxPrintTime就成立,就会进入最终window.close的逻辑。
    我们可以通过hook,返回一个固定的时间戳来过掉反调试(油猴或者直接在控制台注入都可以)。
    Date.prototype.getTime = function(){
        return 1741067137856
    }
    hook掉时间戳之后,我们会发现控制台一直会被清空,也不利于调试,我们直接把清空控制台的代码置为空函数E = function(){}。


    8.png (14.33 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    同理,再把和控制台打印相关的b和w函数也置空(在对应函数断住的时候去置空)。


    9.png (14.49 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    最后,能够在控制台输入并输出表示我们成功过掉了反调试。


    10.png (17.9 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    抓包分析
    我们直接点击土地供应 -> 供地计划,会发一个list的包,请求头中的Hash参数就是需要逆向的参数。


    11.png (63.27 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    逆向分析
    一般请求头参数加密,我们可以通过hook的手段去找加密位置(可以去找现成的hook代码)。我选择直接从启动器去找了,一般都会看异步之前的request。


    12.png (42.16 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    下断,发包,然后找请求拦截器。


    13.png (31.77 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    很显然,下图大概率就是加密参数的生成位置。


    14.png (25.14 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    我们在控制台输出一下结果,可以看到密文的长度为64,看起来很像SHA256。


    15.png (14.9 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    那我们就去尝试一下,看是否为标准的SHA256,字符串'1'的摘要为6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b。


    16.png (79.52 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    再去控制台对字符串'1'进行摘要,经对比,算法是标准的,没有魔改。


    17.png (8.71 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    那加密过程大概清楚了,对userAgent、今天的日期(日)以及list进行SHA256得到Hash。


    18.png (15.13 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    那我们直接对接口进行请求模拟。


    19.png (44.55 KB, 下载次数: 0)
    下载附件
    2025-3-4 15:30 上传

    成功!!!

    下载次数, 下载附件

  • pxq   

    感谢佬分享,其实也可以直接搜[JavaScript] 纯文本查看 复制代码interceptors.request,一般用axios 都有这个关键词
    KaliHt   

    [JavaScript] 纯文本查看 复制代码let r = n(2966)
                      , a = e.url.split("/");
                    return console.log(navigator.userAgent + (new Date).getDate() + a[a.length - 1]),
                    t["Hash"] = r(navigator.userAgent + (new Date).getDate() + a[a.length - 1]),
                    e
    请教一下,这个n是否为webpack加载器?[JavaScript] 纯文本查看 复制代码 function n(r) {
            var a = t[r];
            if (void 0 !== a)
                return a.exports;
            var o = t[r] = {
                id: r,
                loaded: !1,
                exports: {}
            };
            return e[r].call(o.exports, o, o.exports, n),
            o.loaded = !0,
            o.exports
        }
    格式好像不太一样,这个需要怎么改写?
    meet52   

    学到了,又逮到大佬更新
    nicholas7372427   

    不明觉厉,看的一脑袋浆糊,但是感觉热血沸腾。
    st0rm   

    感觉学到了一些东西,谢大佬
    sdieedu   

    非常厉害啊
    ChaChaL   

    现在反爬真的是套路多
    HEA7528   

    厉害了,不错的方法
    fhlfxtd   

    现在反爬真的是套路多
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部