首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  程序员

前两天有 V 友问一个加密的 JS 怎么解密,于是今天脱壳?解密的脚本出来了。

  •  
  •   imdong · 96 天前 · 5393 次点击
    这是一个创建于 96 天前的主题,其中的信息可能已经有所发展或是发生改变。

    当时追了下代码挺感兴趣,正好还有时间,就开搞了。

    主要是看作者写的 “最牛加密” 挺不爽的...

    用了一下午的时间分析和写脚本,测试能解开普通默认的加密了

    没有去适配所谓的强加密什么的...

    当然,整体思路缕下来还是很简单的,

    就是先把一个数组(最开始的 base64)切开前后对换。

    然后代码部分可能用字符串处理的都用一个方法通过 rc4 解密返回调用。

    大致就是下面这样的了...

    // 此数组的值应该是 base64 为了方便看就明文了
    var arr = ['hello', 'alert', 'test', 'debug', 'world'];
    
    arr = [].concat(arr.splice(1, 3), arr);
    
    window[rc4(0, '密钥 1')](rc4(1, '密钥 2'));
    

    解密效果

    我认为互联网本应开源,而且前端没有真正意义的加密,能执行就一定能解密。

    当然,作者说 “绝对不可逆 / 耶稣也无法 100%还原” 是真的,

    因为 YUI compressor 压缩也是不可逆的...

    变量名都被改掉了,显然无可能还原了...

    解密代码:

    (function (js_body) {
        // 脱壳
        let js_arr = js_body.split("\n").pop().split(';'),
            fun_name = /var\s+(_0x[a-z0-9]+)=/.exec(js_arr[6])[1],
            reg_str = fun_name + '\\(' + "'([^']+)',\s*'([^']+)'" + '\\)',
            js_str = js_arr.slice(54, js_arr.length - 4).join(';'),
            code_shell = js_arr.slice(0, 54).join(';'),
            shell_obj = eval("(function(){" + code_shell + ";return " + fun_name + "})()");
        js_str = js_str.replace(new RegExp(reg_str, 'g'), function (str, id, key) {
            return '"' + shell_obj(id, key) + '"';
        }).replace(/([a-z0-9\-_A-Z)\]]+)\s?\[["']([^"']+)["']\]/g, '$1.$2').replace(/(?<!_)(0x[0-9a-f]+)/g, function (hex) {
            return parseInt(hex).toString();
        });
        // 还原混淆
        let obj = null, name = '';
        js_str = js_str.replace(/{(var\s+(_0x[0-9a-z]+)=(\{(.*)\}));/g, function (str, code_str, _name, obj_str) {
            obj = eval("(function () {return " + obj_str + "})()");
            name = _name;
            return '{';
        });
        if (obj) {
            let i = 5;
            while (js_str.indexOf(name) && --i > 0) {
                for (const key in obj) {
                    if (!obj.hasOwnProperty(key)) continue;
                    if (typeof obj[key] == 'function') {
                        let fun_info = /function\s*_0x[0-9a-z]+\(([^)]*)\){return\s*([^;]+);}/.exec(obj[key].toString());
                        js_str = js_str.replace(new RegExp(name + '\\.' + key + '\\(([^())]*)\\)', 'g'), function (string, args_str) {
                            let args = args_str.split(','),
                                fun_args = fun_info[1].split(','),
                                fun_body = fun_info[2];
                            fun_args.forEach(function (item, index) {
                                fun_body = fun_body.replace(item, args[index]);
                            });
                            return fun_body;
                        });
                    } else if (typeof obj[key] == 'string') {
                        js_str = js_str.replace(name + '.' + key, '"' + obj[key] + '"');
                    } else {
                        js_str = js_str.replace(name + '.' + key, obj[key].toString());
                    }
                }
            }
        }
        return js_str;
    })($('#resultSource').val() || $('#jsdata').val());
    
    

    我的小站:https://www.qs5.org/Post/673.html

    28 回复  |  直到 2019-09-02 09:31:26 +08:00
        1
    shanlan   96 天前
    如果能讲讲解密思路就更好,这样直接上代码的话有点生硬。
        2
    imdong   96 天前   ♥ 1
    @shanlan 嗯 我感觉可以,先去陪女朋友玩游戏,等下抽时间缕缕思路试下写写过程。
        3
    cy97cool   96 天前 via Android
    如果能针对这个 https://obfuscator.io 做个通用的反混淆就更好了
        4
    lneoi   96 天前
    期待思路讲解
        5
    imdong   96 天前
    @cy97cool 卧槽,我怎么看着这俩的加密的核心思路是一毛一样的么?
    只是这个 sojson 自己又包了一点而已?
        6
    unclemcz   96 天前   ♥ 4
    @imdong #2 关爱狗狗健康,请不要随意撒狗粮。
        7
    xiangyuecn   96 天前   ♥ 3
    试了一下这个号称“最牛逼加密”,果然思路清奇

    首先把 eval 拦截一下看看,咦,没有?

    看一下加密后的代码,原来仅仅替换加密了一下变量名 y 和字符串而已。。。想看什么加密内容直接 console.log 就完事了。。。😂😂😂 前端真娱乐
        8
    zsx   96 天前
    简单看了一下,这个加密挺没意思的,就是普通的混淆
    目前碰到过的麻烦并且有点意思的 JS 混淆是这个: https://www.jshaman.com/

    至于 JS 加密,个人认为混淆不算加密,这个比较正经: https://www.v2ex.com/t/549319
        9
    gunjianpan   96 天前
    @cy97cool ym cy dalao
        10
    imdong   96 天前
    @zsx 本帖说的 sojson.v5 和 jshaman、obfuscator 应该是 师出同门。

    因为加(hun)密(xiao)的原理都一模一样,几乎可以断定是同一套代码出来的。
        11
    imdong   96 天前
    至于 SecurityWorker 这个代码,那是真的大牛代码,惹不起...
    都上升到 VM 了,我等辣鸡瑟瑟发抖,不敢缩话。
        12
    cydian   96 天前 via Android
    也想看看分享的思路。
        13
    gamexg   96 天前 via Android
    WebAssembly 现在是什么情况了?
    感觉这个难破解了。
        14
    1981   96 天前 via Android   ♥ 1
    https://github.com/insoxin/sojson.v5

    233,持续关注 sojson 很多年了,,,,
        15
    jawnkuin   96 天前
    第一次听说前端可以加密…………
    几个月前有个公司要跟我们合作,最后方案有个数据要加密传输但是要在前端解密,让我无语了好久。

    最后发现他只是想 base64 转换一下而已,感觉前端很多不了解加签 /对称加密 /非对称加密这些概念……
        16
    shew2356   95 天前 via iPhone
    @jawnkuin 没错,前端应该是各种编码,然后伪加密。
        17
    herotiga   95 天前
    @jawnkuin 只能说好多是培训班出来的,计算机基础不牢
        18
    jaskle   95 天前 via Android
    不涉及解析执行的话都很假,可以混淆一下,搞些 abcd 混淆
        19
    watzds   95 天前 via Android
    是不是每一行都加断点,找到入口就差不多了
        20
    zsx   95 天前
    @imdong #10 没注意才发现 obfuscator.io 里有别的配置项,那应该是一样的了
        21
    fenghuang   95 天前
    网站无法访问
        22
    Nicoco   95 天前
    @xiangyuecn 前端就是庙小妖风大,池浅王八多
        23
    youwo   95 天前 via iPhone
    坐等
        24
    simonv3ex   95 天前
    @imdong #2 现在流行把狗骗进来杀?
        25
    auchan   95 天前
    不过一般的这种程度的混淆和加密够了
        26
    KasuganoSoras   95 天前
    想起来以前听的 base64 加密的笑话
        27
    imdong   95 天前   ♥ 1
    @watzds 额,道理是这样,可是这个没有入口,真实代码就在中间,掐头去尾就能用了...
    但是真实代码中间又混杂了一些花指令。

    @fenghuang 是我的博客不能访问么?能给下网络情况么?
    @auchan 讲道理,需要混淆的混淆也没用,没必要混淆的根本杞人忧天...
        28
    hakono   94 天前 via iPhone
    觉得前端没法加密其实也是井底之蛙了

    其实都不需要用上面大佬的 vm 虚拟机,把你的业务核心逻辑都用 WebAssembly 写了,基本上就能挡下一大部分想反向你代码的人了。
    因为反向 WebAssembly 类似于反向汇编,是需要有反向汇编等级的能力的人才能做好,基于 WebAssembly 你可以轻松把 pc 应用开发上的虚拟机 加壳那一套搬运到前端。啥 请个反向大佬就轻松破解? 太天真了,就算是大佬搞反汇编也是需要 OD 这类工具才能工作的,而就现在前端那狗屎一样调试工具,能保证加载个大点的 js 代码不崩都做不到,你还想有像 OD 种等级的强大反向工具,那是做梦了
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1992 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 56ms · UTC 00:13 · PVG 08:13 · LAX 16:13 · JFK 19:13
    ♥ Do have faith in what you're doing.