前两天有 V 友问一个加密的 JS 怎么解密,于是今天脱壳?解密的脚本出来了。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
imdong
V2EX    程序员

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

  • &nbp;
  •   imdong
    imdong 2019-08-31 18:52:01 +08:00 11083 次点击
    这是一个创建于 2242 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

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

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

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

    至于 JS 加密,个人认为混淆不算加密,这个比较正经: t/549319
    gunjianpan
        9
    gunjianpan  
       2019-08-31 21:33:29 +08:00
    @cy97cool ym cy dalao
    imdong
        10
    imdong  
    OP
       2019-09-01 00:05:42 +08:00
    @zsx 本帖说的 sojson.v5 和 jshaman、obfuscator 应该是 师出同门。

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

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

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

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

    其实都不需要用上面大佬的 vm 虚拟机,把你的业务核心逻辑都用 WebAssembly 写了,基本上就能挡下一大部分想反向你代码的人了。
    因为反向 WebAssembly 类似于反向汇编,是需要有反向汇编等级的能力的人才能做好,基于 WebAssembly 你可以轻松把 pc 应用开发上的虚拟机 加壳那一套搬运到前端。啥 请个反向大佬就轻松破解? 太天真了,就算是大佬搞反汇编也是需要 OD 这类工具才能工作的,而就现在前端那狗屎一样调试工具,能保证加载个大点的 js 代码不崩都做不到,你还想有像 OD 种等级的强大反向工具,那是做梦了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2467 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 15:38 PVG 23:38 LAX 08:38 JFK 11:38
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86