JavaScript逆向:过某气体质量监测网站的(无效内容+无限debugger)反调试

声明:案例分析仅供学习交流使用,勿用于任何非法用途。如学习者进一步逆向并对版权方造成损失,请自行承担法律后果,本人概不负责。

该页面用于调试的F12,鼠标右键,CTRL + S都被禁用了。
在这里插入图片描述
从别的页面打开控制台过来,会遇到两道防御机制:
1.页面被改为无效内容。
2.控制台无限打开VMXX页面卡调试。
在这里插入图片描述
摸排源码发现两个可疑函数 endebug()txsdefwsw()
在这里插入图片描述
endebug()函数会在调试模式下篡改页面内容。

function endebug(off, code) {
    if (!off) {
        !function(e) {
            function n(e) {
                function n() {
                    return u
                }
                function o() {
                    window.Firebug && window.Firebug.chrome && window.Firebug.chrome.isInitialized ? t("on") : (a = "off",
                    console.log(d),
                    console.clear(),
                    t(a))
                }
                function t(e) {
                    u !== e && (u = e,
                    "function" == typeof c.onchange && c.onchange(e))
                }
                function r() {
                    l || (l = !0,
                    window.removeEventListener("resize", o),
                    clearInterval(f))
                }
                "function" == typeof e && (e = {
                    onchange: e
                });
                var i = (e = e || {}).delay || 500
                  , c = {};
                c.onchange = e.onchange;
                var a, d = new Image;
                d.__defineGetter__("id", function() {
                    a = "on"
                });
                var u = "unknown";
                c.getStatus = n;
                var f = setInterval(o, i);
                window.addEventListener("resize", o);
                var l;
                return c.free = r,
                c
            }
            var o = o || {};
            o.create = n,
            "function" == typeof define ? (define.amd || define.cmd) && define(function() {
                return o
            }) : "undefined" != typeof module && module.exports ? module.exports = o : window.jdetects = o
        }(),
        jdetects.create(function(e) {
            var a = 0;
            var n = setInterval(function() {
                if ("on" == e) {
                    setTimeout(function() {
                        if (a == 0) {
                            a = 1;
                            setTimeout(code)
                        }
                    }, 200)
                }
            }, 100)
        })
    }
}

txsdefwsw()函数将混淆的“debugger”指令还原后放入无限递归的函数中执行,导致控制台不停打开VMXX并自动断点。虽然可以用值为false的条件断点跳过,但不停执行这段代码也会导致卡顿。

function txsdefwsw() {
    var r = "V"
      , n = "5"
      , e = "8";
    function o(r) {
        if (!r)
            return "";
        for (var t = "", n = 44106, e = 0; e < r.length; e++) {
            var o = r.charCodeAt(e) ^ n;
            n = n * e % 256 + 2333,
            t += String.fromCharCode(o)
        }
        return t
    }
    try {
        var a = [
            "r",
            o("갯"), //e
            "g", 
            o("갭"), //g
            function(t) { //u
                if (!t)
                    return "";
                for (var o = "", a = r + n + e + "7", c = 45860, f = 0; f < t.length; f++) {
                    var i = t.charCodeAt(f);
                    c = (c + 1) % a.length,
                    i ^= a.charCodeAt(c),
                    o += String.fromCharCode(i)
                }
                return o
            }("@"), 
            "b", 
            "e", 
            "d"
        ].reverse().join(""); //debugger
        !function c(r) {
            (1 !== ("" + r / r).length || 0 === r) && function() {} .constructor(a)(), //等价于 !function(){a}()
            c(++r) //无限递归
        }(0)
    } catch (a) {
        setTimeout(txsdefwsw, 100)
    }
}

那么,我们只要在函数处下断,待其加载后将其制空是不是就可以了呢。
在这里插入图片描述
结果还是没有有效内容。
在这里插入图片描述
又经过一段排查,居然发现其第三方库jquery.min.js中居然被做了手脚。
在这里插入图片描述
这两个函数初看上去叫人摸不着头脑,但仔细看最后的字符串不难发现端倪——这两就是混淆后的endebug()与txsdefwsw()代码。也就是说该网页在jquery.min.js中用eval()函数再次激活自己的反调试机制,并且由于代码的混淆存储,这段很难被定位和静态分析。

eval(function (p, a, c, k, e, d) {
    e = function (c) {
        return (c < a ? "" : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
    };
    if (!''.replace(/^/, String)) {
        while (c--) d[e(c)] = k[c] || e(c);
        k = [
            function (e) {
                return d[e]
            }
        ];
        e = function () {
            return '\\w+'
        };
        c = 1;
    };
    while (c--)
        if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
    return p;
}('2 M(g,y){h(!g){!2(e){2 n(e){2 n(){j u}2 o(){4.8&&4.8.m&&4.8.m.H?t("9"):(a="g",v.G(d),v.F(),t(a))}2 t(e){u!==e&&(u=e,"2"==7 c.5&&c.5(e))}2 r(){l||(l=!0,4.I("k",o),L(f))}"2"==7 e&&(e={5:e});3 i=(e=e||{}).K||J,c={};c.5=e.5;3 a,d=B z;d.D("C",2(){a="9"});3 u="E";c.A=n;3 f=s(o,i);4.S("k",o);3 l;j c.N=r,c}3 o=o||{};o.x=n,"2"==7 6?(6.P||6.R)&&6(2(){j o}):"O"!=7 b&&b.p?b.p=o:4.q=o}(),q.x(2(e){3 a=0;3 n=s(2(){h("9"==e){w(2(){h(a==0){a=1;w(y)}},Q)}},T)})}}', 56, 56, '||function|var|window|onchange|define|typeof|Firebug|on||module|||||off|if||return|resize||chrome|||exports|jdetects||setInterval|||console|setTimeout|create|code|Image|getStatus|new|id|__defineGetter__|unknown|clear|log|isInitialized|removeEventListener|500|delay|clearInterval|endebug|free|undefined|amd|200|cmd|addEventListener|100'.split('|'), 0, {}));

eval(function (p, a, c, k, e, d) {
    e = function (c) {
        return (c < a ? "" : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
    };
    if (!''.replace(/^/, String)) {
        while (c--) d[e(c)] = k[c] || e(c);
        k = [
            function (e) {
                return d[e]
            }
        ];
        e = function () {
            return '\\w+'
        };
        c = 1;
    };
    while (c--)
        if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
    return p;
}('3 l(){2 r="v",n="5",e="8";3 o(r){m(!r)4"";h(2 t="",n=w,e=0;e<r.6;e++){2 o=r.9(e)^n;n=n*e%u+p,t+=k.j(o)}4 t}q{2 a=["r",o("z"),"g",o("x"),3(t){m(!t)4"";h(2 o="",a=r+n+e+"7",c=y,f=0;f<t.6;f++){2 i=t.9(f);c=(c+1)%a.6,i^=a.9(c),o+=k.j(i)}4 o}("@"),"b","e","d"].B().E("");!3 c(r){(1!==(""+r/r).6||0===r)&&3(){}.D(a)(),c(++r)}(0)}C(a){A(l,s)}}', 41, 41, '||var|function|return||length|||charCodeAt||||||||for||fromCharCode|String|txsdefwsw|if|||2333|try||100||256|V|44106|갭|45860|갯|setTimeout|reverse|catch|constructor|join'.split('|'), 0, {}));

把jquery.min.js拿下来,注释掉反调试部分,替换掉原响应。
在这里插入图片描述
但是替换掉之后,还是会被反调试挡住,明明被置空的函数又“复活”了。
在这里插入图片描述
再次调试,发现其子页面还有相同的代码执行,注意最开始的反调试函数在 (index) 中,现在是 /city_realtime.php?v=2.3 中,其实左侧的每个子Tab页都有这段反调试。
在这里插入图片描述
只要再次置空这两个函数,就能正常打开调试模式了。
在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值