前言


对某网站加密混淆后的javascript代码也算分析了一段时间了,虽然还没搞出来,但多少有些新得,这里记录一下。

工具和资料


  • https://jq.qq.com/?_wv=1027&k=5Bcu3YU   QQ群 - Javascript高级爬虫 - 作者自建群,欢迎加入!
  • https://github.com/rockswang/awesome-java-crawler  awesome-java-crawler - 我收集的爬虫相关工具和资料
  • https://github.com/rockswang/wsjs.saic.mmewmd 中国商标网加密接口 - 仅做演示
  • https://segmentfault.com/a/1190000017286304  前一篇文章 - 记录了之前尝试的一些初步研究成果
  • https://github.com/rockswang/java-curl  java-curl - java HTTP库,可用来替换chrome网络后端,更方便控制底层行为,如缓存、代理、监控、修改请求和应答等
  • https://github.com/webfolderio/cdp4j cdp4j - java版的Chrome Devtools Protocol实现,用于控制Chrome浏览器。最大的特点就是没有"特点",你懂的.....
  • https://beautifier.io/  beautifier.io - js代码在线格式化
  • https://github.com/estree/estree  estree - ECMAScript抽象语法树(AST)业界标准
  • https://tc39.github.io/ecma262 ECMAScript262语言规范 - 帮助理解estree
  • https://github.com/acornjs/acorn  acornjs - ECMAScript编译器前端,将js源码解析成estree格式的AST
  • https://github.com/davidbonnet/astring  astring - ECMAScript代码生成器,将AST重新还原成js源码
  • https://wiki.openjdk.java.net/display/Nashorn nashorn - java8以上自带的javascript解析器,性能接近原生node
  • https://segmentfault.com/a/1190000017401661  java中调用npm模块 - 我的工作语言是java和kotlin,使用此方案调用js原生库
  • https://zhuanlan.zhihu.com/p/29196829  商标局网站分析 - 类似的加密, 神箭手云的大佬写的
  • http://www.anyun.org/m/view.php?aid=9457&tdsourcetag=s_pcqq_aiomsg  裁判文书网分析 - 另一篇类似网站分析
  • http://www.qingpingshan.com/jb/javascript/239312.html 很早的一篇分析文 - 看特征是这种加密的早期版本

分析过程


获取javascript代码

  • 加密的核心代码只有一小部分是直接写在网页的<script>里面的,大部分代码是eval出来的,还有部分是jsonp方式异步加载的
  • 可以用cdp4j监听Debugger.ScriptParsed事件,并在监听器中调用Debugger.getScriptSource来获取js代码文本
  • 这样是可以获取到所有前端javascript源码的,即使源码在网络应答中是加密的,但用eval执行前也会还原为合法的js源码
  • 为了方便分析,将代码保存为文件。该网站js会用定时器不断重复eval一段代码,因此可以用ScriptParsed.hash作为文件名,避免重复保存文件
  • 这样搞出来的,用一样的混淆方式加密的js代码共有4段,其中两段特别长是核心代码,还有两段应该是编解码算法,一共加起来约5000行

获取常量映射

  • 拿到js之后,格式化一下,发现还是一团乱麻,所有的变量,函数都是"_$xx", 可读性等于0
  • 在Chrome控制台里试了一下,发现全局变量和函数都保存在window中了
  • 一部分无参的函数调用,其实返回的就是常量字符串
  • 还有一些_$xx.call的,看了一下,其实就是系统方法,比如
  • String.formatCharCode,Array.prototype.slice等
  • 因此可以编写一段控制台脚本,遍历window对象中所有形式_$xx的成员,判断其类型和函数执行结果。这样即可将常量字符串映射、系统方法映射等搞出来。在控制台执行下面这段代码就可以把字符串映射表弄到。
(function () }for (var p in window) {if (p.substr(0, 2) !== "_$") continue;if (typeof window[p] !== "function" || window[p].name !== "") continue;try {var s = window[p]();console.log(p + "=" + s)} catch (e) {}}
}){}

可读性还原

  • 拿到映射关系之后是不是简单用正则表达式替换回去就完事大吉了呢?哪有那么简单!函数的局部变量、局部函数有很大可能性和全局变量重名,如果用正则无脑替换回去绝对会被坑死!!要是代码少倒也罢了,这里可有5000行代码,差之毫厘谬以千里!
  • 另外,不同函数的局部变量也存在大量重名,静态分析时干扰严重,因此,应该将局部变量也替换成唯一且更有意义的名字,比如<函数名>_<变量索引>
  • 因此,正确的方法是基于编译原理进行语法级别的替换。看到这里是不是要弃疗了?老子爬点数据还要写编译器?!
  • 还好,js上已经有很成熟的业界标准和若干老练的第三方库了,至少不用从龙书搞起.......
  • 我这里选择了acornjs和astring,前者用于将js源码解析成抽象语法树AST,后者将AST还原成js源码。当然,有了AST就可以上下其手了.....
  • 为了在java代码中运行acornjs和atring,请参见参考中《java中调用npm模块》一文。注意astring换依赖endswith和repeat两个polyfill,均可以npm下载到
  • 简单描述一下AST变换算法。用acorn.parse()搞到AST之后,递归扫描每个节点:

进入每个FunctionDeclaration/FunctionExpression节点前,创建一个新的作用域对象放到栈顶,里面放该域内所有局部变量(含函数参数)和新名称的映射表;退出时将栈顶弹出

遇到Identifier节点,首先在作用域栈中自顶向下一次寻找当前变量名,找到了,则是本方法局部变量或闭包局部变量,用新名字替换之;否则, 则是全局变量,去映射表中查找替换之

注意,遇到CallExpression须特殊处理,前面的AST变换只涉及修改标识符名,而为了将_$xx()变换为"xxx",则涉及到结构变换,要把CallExpression节点修改为Literal节点并添加value属性

  • 全部处理完成后,就可以用astring.generate()产生还原后的代码了
  • 可读性恢复前后的代码可以看看下面的对比:

处理前:一团乱麻,完全不知所云

处理后:虽然还很费劲,起码看得出来这是在挂各种事件监听器。另外,看看人间监听多少种事件啊.......

代码分析

上面步骤完成后,这代码至少勉强能看了,别放松,后面还有无数的坑......

还原前的代码只能是让人一脸懵逼,还原后的代码则足以让人咬牙切齿啊,多大仇啊,满满登登5000行全是正面硬怼的.....

这里记录一部分已经发现的反破解手法吧。

不断主动中断干扰调试,并检测是否有动态分析行为

var eI_v1 = window["eval"]("(function() { var a = new Date(); debugger"; return new Date() - a > 100;}())");
_$n1 = _$n1 || eI_v1;
//这个在上篇文章分析了,在这找到调用来源了。注意,在可读性还原之前这货长这样:
var _$pW = _$u9[_$mz()](_$oi());
_$n1 = _$n1 || _$pW;

js代码动态混淆

  • 上一篇文章已经说过了,每次刷新js代码都会完全变化,包括全局/局部变量名、函数排列顺序等
  • 设断点会被干扰,且代码无法重复执行对于调试意味着什么?

检查关键函数是否被注入替换

function __RW_checkNative(rh_p0, rh_p1) { //函数名是我手动改的try {var rh_v2 = Function["prototype"]["toString"]["apply"](rh_p0);var rh_v3 = new RegExp("{\\s*\\[native code\\]\\s*}");if (typeof rh_p0 !== "function" || !rh_v3["test"](rh_v2) || rh_p1 != undefined && rh_p0 !== rh_p1) __GL_undefined_$sy = true;} catch (_$r0) {}
}
  • 会用这个函数检测eval,Function,setTimeout,setInterval几个系统函数是不是被注入了
  • 知道这块逻辑,就可用一些手段(https://segmentfault.com/a/1190000018742189)骗过去,不知道的话...

检测当前窗口是否隐藏状态

document["addEventListener"]("visibilitychange", _$r0);
  • 会监控当前窗口是否在最上方,如果多开浏览器并行爬取......

检测Selenium,WebDriver,PhantomJS等

var rm_v5 = "_Selenium_IDE_Recorder,_selenium, callSelenium",rm_v6 = "__driver_evaluate,__webdriver_evaluate,__selenium_evaluate,__fxdriver_evaluate,__driver_unwrapped,__webdriver_unwrapped,__selenium_unwrapped,__fxdriver_unwrapped,__webdriver_script_func,__webdriver_script_fn", rm_v7 = ["selenium", "webdriver", "driver"];if (_$un(window, "callPhantom,__phantom")) { ... }
  • 看到这里想必就知道会发生写什么了......

Hook住AJAX

var ec_v4 = window["XMLHttpRequest"];
if (ec_v4) {var ec_v5 = ec_v4["prototype"];if (ec_v5) {__GL_f_open = ec_v5["open"];__GL_f_send = ec_v5["send"];ec_v5["open"] = function () {_$t5();arguments[1] = _$pK(arguments[1]);return __GL_f_open["apply"](this, arguments);};} else { ... }
}
  • 会自动在ajax请求后添加一个加密参数MmEwMD,参数值中可能包括鼠标轨迹等信息

检查navigator是否是伪造的

var hi_v14 = window["navigator"];
for (hi_v11 in hi_v14) {try {hi_v13 = hi_v14["hasOwnProperty"](hi_v11);} catch (_$r0) {hi_v13 = false;}
}
  • 如果你注入的navigator对象使用{...}创建的水货版本,那就露馅了......

检查浏览器特征

  • 这块代码很长很复杂,还没分析完,现在能看出来的包括:
  • navigator.languages - 在headless chrome中是没有这个字段的
  • navigator.plugins - 无头和有头的chrome返回的插件列表不一样

WebGL能力检查

  • 有一大段代码是在canvas上用webgl绘图,没搞过webgl,现在还不明白,但肯定也是检查浏览器特征手段之一

某网站高度加密混淆的javascript的分析相关推荐

  1. 某网站高度加密混淆的javascript的分析 1

    对某网站加密混淆后的javascript代码也算分析了一段时间了,虽然还没搞出来,但多少有些心得,这里记录一下. 工具和资料 前一篇文章 - 记录了之前尝试的一些初步研究成果 awesome-java ...

  2. 在线Javascript加密混淆工具

    在线Javascript加密混淆工具 在线Javascript加密混淆工具 在线Javascript Obfuscator 使 javascript 代码更难阅读以保护它.该工具提供了四种使用工具.你 ...

  3. vue项目配置 webpack-obfuscator 进行代码加密混淆

    背景 公司代码提供给第三方使用,为了不完全泄露源码,需要对给出的代码进行加密混淆,前端代码虽然无法做到完全加密混淆,但是通过使用 webpack-obfuscator 通过增加随机废代码段.字符编码转 ...

  4. 总结10款常用的加密混淆软件,

    加密混淆软件那么多,我们开发者到底用哪个性价比最好?没有最好的性价比只有最合适的选择,今天板砖多角度为您剖析.NETReactor.VMP.Oreans等一众厂商产品,助您选择无压力! 加密对象对比 ...

  5. Java代码加密混淆工具有哪些?

    在Java中,代码加密混淆工具可以帮助开发者将源代码进行加密和混淆处理,以增加代码的安全性和保护知识产权.以下是一些流行的Java代码加密混淆工具: 第一款:ProGuard:ProGuard Pro ...

  6. HTML期末大作业~节日礼品购物商城网站html模板(HTML+CSS+JavaScript)

    HTML期末大作业~节日礼品购物商城网站html模板(HTML+CSS+JavaScript) 临近期末, 你还在为HTML网页设计结课作业,老师的作业要求感到头大?HTML网页作业无从下手?网页要求 ...

  7. HTML5期末大作业:酒店主题网站设计——酒店阳光温馨网站(5页) HTML+CSS+JavaScript web前端课程设计_web前端课程设计代码,web课程设计-HTML网页制作代码...

    常见网页设计作业题材有 ​​个人. 美食. 公司. 学校. 旅游. 电商. 宠物. 电器. 茶叶. 家居. 酒店. 舞蹈. 动漫. 明星. 服装. 体育. 化妆品. 物流. 环保. 书籍. 婚纱. 军 ...

  8. exe一机一码加密工具_Python代码加密混淆

    我多想再见你 哪怕匆匆一眼就别离 python作为一种解释型语言,源代码加密本身比较困难.但有时候我们在发布一款python产品时又必须考虑到代码的加密性,以避免源代码泄露.为此,我查阅了一些资料,研 ...

  9. 关于HTML加密混淆、源码保护、代码安全,防止解压直接看源码

    转载:https://my.oschina.net/1590538xiaokai/blog/478842 摘要: 一直有人问HTML加密混淆怎么做,其实这在业内是早已很多人研究过的课题. 最近闲暇之余 ...

最新文章

  1. L3-010. 是否完全二叉搜索树
  2. 根据网络状态获取Ip地址
  3. vim之好用插件-ctrlp.vim
  4. 神策 2021 数据驱动大会嘉宾阵容首曝 + 精彩观点前瞻
  5. C++返回栈上的数组(局部变量)问题探索
  6. YOLO,VOC数据集标注格式解析
  7. 03-15 截图、日志与录屏
  8. vue企业门户网站模板_6 个火爆 GitHub 的后台管理模板,快来收藏!
  9. Silverlight的依赖属性与附加属性(四)
  10. 客户关系管理系统中对客户及相关数据的导入导出分析处理
  11. 来自联通302的问候
  12. nds linux模拟器下载,NDS模拟器Desmume
  13. 从零开始设计一款APP之Android设计规范篇
  14. mysql中如何批量删除冗余数据库_WordPress清理数据库中的冗余数据加速网站运行速度...
  15. 支持select下拉框选择输入和键盘输入两种输入方式并且支持手动换行
  16. 软件License管理与代码保护技术概述
  17. 三大特殊类(String Object 包装类)与异常
  18. 如何录制屏幕视频?有哪些录制技巧?
  19. 用C语言实现扫雷游戏(详解)
  20. lichee目录+android源码目录制作ROM

热门文章

  1. 树型列表结构宽度调整_如何用Axure画出Web产品的列表组件:基础画法
  2. 正则表达式(Java版整理)
  3. Linux 环境下安装 Golang
  4. 阿里云原生数据库:POLARDB
  5. leetcode -- 303. 区域和检索 - 数组不可变
  6. idea点击表单按钮不做post反应
  7. (*长期更新)软考网络工程师学习笔记——Section 12 Linux系统与文件管理命令
  8. java list 排序_java list排序
  9. 如何快速在CentOS搭建光盘【永久搭载光盘】
  10. MySQL——高阶语句、存储过程(下)