js逆向教程
打开浏览器控制台,教程在Sources面板里翻到一个压缩得只剩一行的教程JS文件。光标扫过,教程满屏的教程_0x3f2a、_0x5b8c之类的教程变量名,像被加密过的教程天书。这就是教程JS逆向最常见的起点——混淆代码。
我第一次做逆向时,教程天真地以为能靠肉眼读懂这些。教程结果盯着屏幕半小时,教程只看出代码在疯狂自执行,教程各种数组、教程位移、教程异或运算交织在一起。教程后来才明白,教程对付混淆不能靠硬读,得靠工具和策略。
先说说最基础的:找到目标接口。打开Network面板,刷新页面,看哪个XHR请求返回了你需要的数据。点开它的Initiator,里面会列出调用栈——从事件绑定到函数调用的完整链条。沿着这个链条往下追,就能摸到加密函数的位置。但很多站点会把关键逻辑藏进Webpack打包的模块里,这时候就得在代码里搜索特征字符串。比如data里有个sign字段,就全局搜sign:或者"sign",通常能直接定位到赋值处。
定位到之后,真正的麻烦才开始。有的站点用OB混淆,把整个逻辑拆成无数个小函数塞进数组,运行时再通过位移还原。遇到这种,我一般先找_0x开头的解密函数,把整个数组拉出来跑一遍,还原成可读代码。有的站点用控制流平坦化,把原本的顺序执行搅成switch-case循环,看起来像意大利面。这种就得靠插件,比如JStom或de4js,能自动还原大部分结构。但插件不是万能的,碰上自定义的混淆算法,还是得手动跟。
手动跟的时候,有个技巧特别实用:在关键函数入口打上断点,然后单步执行。观察每个变量的变化,尤其是那些被当作参数传来传去的值。很多加密逻辑其实就是字符串拼接加上几次编码,比如先Base64再RSA。你跟着跟着就会发现,所谓的“加密”可能只是把时间戳和固定密钥拼起来做了个MD5。这时候直接复制算法,在Python里重写一遍就行。
但重写也有坑。有些加密依赖浏览器环境,比如用到了window对象或者navigator.userAgent。直接在Node里跑会报错,因为环境不存在。解决办法是补环境——手动声明这些全局变量,或者用jsdom模拟。更麻烦的是那些检测代码,会检查你是否在DevTools里打开了调试器,一旦检测到就无限debugger。对付这种,可以在代码里搜索debugger关键字,右键选择“Never pause here”,或者直接替换成空语句。
说个真实例子。之前逆向一个电商平台的搜索接口,数据是加密的。刚开始用AST还原混淆,折腾了两天,还原出来的代码还是绕来绕去。后来我换个思路,直接在浏览器里Hook住JSON.stringify,把所有序列化前的对象打印出来。结果发现加密前的数据就是一个普通的字典,加密函数只是把字典转成JSON字符串,再用一个固定的AES密钥加密。密钥就硬编码在代码里,连混淆都没做。那一刻我真觉得,有些开发者的安全意识,比他们的代码质量还差。
逆向做久了,你会发现它不只是技术活,更是一场心理博弈。你在猜对方怎么藏的,对方在猜你会怎么找。有些站点故意放几个假加密函数当诱饵,真逻辑藏在异步回调里。这时候别慌,把整个请求流程梳理一遍,从事件触发到数据返回,每一步都记录下来。画个流程图,比盲目搜代码高效得多。
最后说点实在的。逆向别人的JS,技术上不难,难的是法律边界。个人学习研究没问题,但别拿去爬商业数据或搞黑产。我见过有人因为逆向某支付接口被判了刑,得不偿失。所以,练手的话,找个自己的项目或者开源的靶场,比如reverse-engineering-challenge这类仓库,随便折腾。
工具方面,除了Chrome DevTools,建议装个Requestly来拦截修改请求,Charles抓包也行。代码分析用WebStorm加AST插件,比记事本强一百倍。还有一点,逆向前先确认目标有没有反爬措施,比如IP限制、验证码,这些比JS混淆更麻烦。先处理掉这些,再谈逆向。
写这篇文章时,我特意没提具体的加密算法细节,因为每个站点都不一样。但思路是通用的:找入口、跟调用栈、还原逻辑、补环境、验证结果。遇到卡壳就换个角度,比如从网络层、内存层、甚至渲染层去观察。JS逆向本质是理解别人怎么想,而不是背代码。
本文地址:http://www.79wt.cn/news/743c1299244.html
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。