翼度科技»论坛 编程开发 JavaScript 查看内容

JS解混淆

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
JS解混淆

最近在整理之前和一些同伴的分享资料,发现时间已经过了好久,特此整理一些有价值的分享记录。
JS混淆

学习js混淆可以逆向分析混淆和加密过程,实战可用于爬虫和渗透信息获取
本文档用于初步介绍js混淆的基础概念以及如何解混淆、调试,便于干掉反爬虫和渗透信息收集思路拓展
概念解释

混淆/加密
降低代码可读性加强安全性,防止被人任意查看,在一定程度保护资源
理想的混淆或加密应该具备如下特点
1、没有确定的破解模式;
2、很难编制自动破解程序(只能手工破解);
3、破解过程繁琐、耗时;
4、“混淆|加密”后的代码,比原始代码长度增加少;
代码里诸如此类就是经过了混淆的结果,可以通过console+断点打出来看看值


js混淆和eval加密
前端虽然开源, 但是由于前端代码量很多,也有一些特殊的保护代码的方法
其中Eval、js混淆是常用的方式,但是在大的互联网产品上用得很少,因为前端加密(RSA、AES、MD5等)是为了保证数据传输中的安全性,而非要让人难以模仿数据传输请求
而前端中的js混淆、eval对于专业的人来说形同虚设,所以也没必要做混淆和eval,并且对于代码维护是及其不利的
eval加密
js中的eval()方法就是一个js语言的执行器
它能把其中的参数按照JavaScript语法进行解析并执行
简单来说就是把原本的js代码变成了eval的参数,变成参数后代码就成了字符串,其中的一些字符就会被按照特定格式“编码”
是最早JS出现的混淆加密,据说第一天就被破解,修改一下代码,alert一下就可以破解了
  1. #eval加密
  2. 源代码:
  3. var showmsg="粘贴要加密/解密的javascript代码到这里";
  4. if(1==1){
  5.   alert(showmsg);
  6. }
  7. 加密后的样子:
  8. eval(function(p,a,c,k,e,d){e=function(c)
  9. {return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?
  10. String.fromCharCode(c+29):c.toString(36))};
  11. if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return
  12. d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new
  13. RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('5 4="粘贴要加密/解密的3代码到这里";2(0==0){  
  14. 1(4);}',62,6,'1|alert|if|javascript|showmsg|var'.split('|'),0,{}))
复制代码
eval()语句还有一个重要用途:在反调试中可以使用该语句来进行一些函数值赋空从而跳出debugger的函数
JS混淆
把其中的变量、方法位置顺序打乱,但是又用一些无关的变量或者方法来保证执行顺序
常见手段
1、去除缩进、空行、换行、注释
2、变量名替换(缩短/改乱)
3、通过自定义变量名引用JS关键字
4、添加大段空白,增加代码前后间隔,干扰阅读
5、混眼法(通过利用[]和["、']及变量定义语句来添加与代码功能无关的字符/增添与代码功能无关的运算语句)
6、对源代码进行加密,同时附上解密的代码(运行时先解密,然后通过document.write()或eval()或innerHTML把代码释放出来执行)
其他混淆类型

hash类型
压缩类型
常用工具

混淆

这里是从使用工具加密信息方出发,具体工具的使用可以自行学习。

  • webassembly
  • esprima
针对JavaScript

  • JavaScript Obfuscator
​        具体使用参考:7.8k Star!一个强大的 JS 代码混淆工具 - 掘金 (juejin.cn)

  • terser
  • uglify-js
  • uglify-es
  • Google Closure Compiler
  • YUI Compressor
针对CSS

  • PostCSS
  • clean-css
  • CSSO
  • YUI Compressor
针对HTML

  • html-minifier
混淆示例
此处使用JavaScript Obfuscator Tool,由JavaScript Obfuscator作者搭建的一个在线混淆网站,直接输入需要混淆的代码输出混淆结果即可
以下面的一个简单hello world为例
  1. ##源代码
  2. function hi() {
  3.   console.log("Hello World!");
  4. }
  5. hi();
复制代码
经过混淆之后
  1. ##混淆后的代码
  2. (function(_0x1522cf,_0x263348){var _0x2bf84c=_0x42bb,_0x47bae4=_0x1522cf();while(!![]){try{var _0x301f10=parseInt(_0x2bf84c(0x11b))/0x1*(-parseInt(_0x2bf84c(0x10f))/0x2)+-parseInt(_0x2bf84c(0x114))/0x3+parseInt(_0x2bf84c(0x112))/0x4*(-parseInt(_0x2bf84c(0x117))/0x5)+-parseInt(_0x2bf84c(0x110))/0x6+parseInt(_0x2bf84c(0x115))/0x7*(parseInt(_0x2bf84c(0x118))/0x8)+parseInt(_0x2bf84c(0x119))/0x9*(parseInt(_0x2bf84c(0x116))/0xa)+parseInt(_0x2bf84c(0x11a))/0xb*(parseInt(_0x2bf84c(0x113))/0xc);if(_0x301f10===_0x263348)break;else _0x47bae4['push'](_0x47bae4['shift']());}catch(_0x2af3c3){_0x47bae4['push'](_0x47bae4['shift']());}}}(_0x22dc,0x1e93e));function hi(){var _0xfdbe99=_0x42bb;console[_0xfdbe99(0x111)]('Hello\x20World!');}hi();function _0x42bb(_0x4a56bb,_0x17e1ee){var _0x22dca2=_0x22dc();return _0x42bb=function(_0x42bb1c,_0x597cba){_0x42bb1c=_0x42bb1c-0x10f;var _0x2ad529=_0x22dca2[_0x42bb1c];return _0x2ad529;},_0x42bb(_0x4a56bb,_0x17e1ee);}function _0x22dc(){var _0x1ca681=['937926xGdCzf','log','344SUuAGG','1124988WMYeGw','111081MLZhWo','35SqOFWp','670aFpiLz','12820fkuEha','108152xzQqbd','15975Prsnjz','44YZHRMa','1oaFebR','44836HvkwgV'];_0x22dc=function(){return _0x1ca681;};return _0x22dc();}
  3. ##为了展示直观,经过代码美化处理结果如下
  4. (function(_0x1522cf, _0x263348) {
  5.         var _0x2bf84c = _0x42bb,
  6.                 _0x47bae4 = _0x1522cf();
  7.         while (!![]) {
  8.                 try {
  9.                         var _0x301f10 = parseInt(_0x2bf84c(0x11b)) / 0x1 * (-parseInt(_0x2bf84c(0x10f)) / 0x2) + -parseInt(_0x2bf84c(0x114)) / 0x3 + parseInt(_0x2bf84c(0x112)) / 0x4 * (-parseInt(_0x2bf84c(0x117)) / 0x5) + -parseInt(_0x2bf84c(0x110)) / 0x6 + parseInt(_0x2bf84c(0x115)) / 0x7 * (parseInt(_0x2bf84c(0x118)) / 0x8) + parseInt(_0x2bf84c(0x119)) / 0x9 * (parseInt(_0x2bf84c(0x116)) / 0xa) + parseInt(_0x2bf84c(0x11a)) / 0xb * (parseInt(_0x2bf84c(0x113)) / 0xc);
  10.                         if (_0x301f10 === _0x263348) break;
  11.                         else _0x47bae4['push'](_0x47bae4['shift']());
  12.                 } catch (_0x2af3c3) {
  13.                         _0x47bae4['push'](_0x47bae4['shift']());
  14.                 }
  15.         }
  16. }(_0x22dc, 0x1e93e));
  17. function hi() {
  18.         var _0xfdbe99 = _0x42bb;
  19.         console[_0xfdbe99(0x111)]('Hello\x20World!');
  20. }
  21. hi();
  22. function _0x42bb(_0x4a56bb, _0x17e1ee) {
  23.         var _0x22dca2 = _0x22dc();
  24.         return _0x42bb = function(_0x42bb1c, _0x597cba) {
  25.                 _0x42bb1c = _0x42bb1c - 0x10f;
  26.                 var _0x2ad529 = _0x22dca2[_0x42bb1c];
  27.                 return _0x2ad529;
  28.         }, _0x42bb(_0x4a56bb, _0x17e1ee);
  29. }
  30. function _0x22dc() {
  31.         var _0x1ca681 = ['937926xGdCzf', 'log', '344SUuAGG', '1124988WMYeGw', '111081MLZhWo', '35SqOFWp', '670aFpiLz', '12820fkuEha', '108152xzQqbd', '15975Prsnjz', '44YZHRMa', '1oaFebR', '44836HvkwgV'];
  32.         _0x22dc = function() {
  33.                 return _0x1ca681;
  34.         };
  35.         return _0x22dc();
  36. }
复制代码
可以发现代码混淆有几个比较固定的特征,一些变量的命名会赋随机值,而后通过一个数组去进行存储。同时使用一个while-try-catch的结构。
再看一下实际环境中经过混淆的代码
[code]// 此处也是经过格式美化,源代码只有一行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;}('4 3(1){2 0=5 8();7 0.6(1)}', 9, 9, 'b|tksl|var|dswejwehxt|function|new|decode|return|Base64'.split('|'), 0, {}));// respondeval(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;}('(c(w){"2O 2E";8 7={};w.7=7;7.21=c(){};8 V=[],1T=(c(){8 16=1E;2t{16=1l w.2s()}2u(e){16=1l w.2w("2v.2o")}l c(){l 16}})(),14=c(1t,22){8 p=1T();5(!p){l}p.2n("2p",1t,1f);p.2r=c(){5(p.1Q!==4||p.2a!==2q&&p.2a!==2D){l}22(p.2C)};5(p.1Q===4){l}p.2G(1b)},1J=c(25){l 25.U(7.f.2g,\'\').I(7.f.1R)};7.14=14;7.2F=V;7.2y=1J;7.f={b:/@b[^\\{]+\\{([^\\{\\}]*\\{[^\\}\\{]*\\})+/17,1j:/@(?:\\-(?:o|2x|2z)\\-)?1j[^\\{]+\\{(?:[^\\{\\}]*\\{[^\\}\\{]*\\})+[^\\}]*\\}/17,2f:/\\/\\*[^*]*\\*+([^/][^*]*\\*+)*\\//17,20:/(1t\\()[\'"]?([^\\/\\)\'"][^:\\)\'"]+)[\'"]?(\\))/g,1U:/@b *([^\\{]+)\\{([\\S\\s]+?)$/,Y:/(Y\\s+)?([a-2e-Z]+)\\s?/,12:/\\(\\s*v\\-19\\s*:\\s*(\\s*[0-9\\.]+)(1o|E)\\s*\\)/,15:/\\(\\s*u\\-19\\s*:\\s*(\\s*[0-9\\.]+)(1o|E)\\s*\\)/,2g:/\\(\\s*m(1h|2B)\\-(2A|19)\\s*:\\s*(\\s*[0-9\\.]+)(1o|E)\\s*\\)/17,1R:/\\([^\\)]*\\)/g};7.2b=w.1s&&w.1s("Y 1M")!==1b&&w.1s("Y 1M").2k;5(7.2b){l}8 h=w.2j,t=h.2m,X=[],F=[],B=[],1i={},1w=30,G=h.1H("G")[0]||t,1z=h.1H("1z")[0],W=G.1H("2l"),1a,1p,1c,T=c(){8 Q,H=h.1k(\'H\'),d=h.d,29=t.q.J,1n=d&&d.q.J,1d=1E;H.q.26="2i:2H;34-33:1Z;19:1Z";5(!d){d=1d=h.1k("d");d.q.36="35"}t.q.J="1S%";d.q.J="1S%";d.27(H);5(1d){t.23(d,t.2Z)}Q=H.2Y;5(1d){t.1r(d)}K{d.1r(H)}t.q.J=29;5(1n){d.q.J=1n}Q=1c=10(Q);l Q},18=c(1X){8 1C="32",1m=t[1C],1u=h.31==="3c"&&1m||h.d[1C]||1m,C={},28=W[W.y-1],1v=(1l 3a()).37();5(1X&&1a&&1v-1a-1?(1c||T()):1)}5(!!u){u=10(u)*(u.1D(E)>-1?(1c||T()):1)}5(!z.1Y||(!1y||!1x)&&(1y||1u>=v)&&(1x||1u

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具