|
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一下就可以破解了- #eval加密
- 源代码:
- var showmsg="粘贴要加密/解密的javascript代码到这里";
- if(1==1){
- alert(showmsg);
- }
- 加密后的样子:
- 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}('5 4="粘贴要加密/解密的3代码到这里";2(0==0){
- 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类型
压缩类型
常用工具
混淆
这里是从使用工具加密信息方出发,具体工具的使用可以自行学习。
针对JavaScript
具体使用参考:7.8k Star!一个强大的 JS 代码混淆工具 - 掘金 (juejin.cn)
- terser
- uglify-js
- uglify-es
- Google Closure Compiler
- YUI Compressor
针对CSS
- PostCSS
- clean-css
- CSSO
- YUI Compressor
针对HTML
混淆示例
此处使用JavaScript Obfuscator Tool,由JavaScript Obfuscator作者搭建的一个在线混淆网站,直接输入需要混淆的代码输出混淆结果即可
以下面的一个简单hello world为例- ##源代码
- function hi() {
- console.log("Hello World!");
- }
- hi();
复制代码 经过混淆之后- ##混淆后的代码
- (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();}
- ##为了展示直观,经过代码美化处理结果如下
- (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();
- }
复制代码 可以发现代码混淆有几个比较固定的特征,一些变量的命名会赋随机值,而后通过一个数组去进行存储。同时使用一个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
|