中间人技巧:使用AST自动去除OB混淆的反调试逻辑
大家好,今天分享一个使用 AST 动态去除 OB 混淆反调试的方案。
OB 混淆
OB 混淆已经提过很多次了,就不多说了。OB 混淆自带了大量的反调试手段,有的时候只要控制台一打开,还没做其他操作,浏览器就直接崩溃了。
这种情况下严重影响调试,当然这个时候可以查看这篇文章来替换文件,手动去除反调试后再使用。
动态密钥
但是我之前分析的那个样本,其中有两行密钥是动态的,没看过的小伙伴可以先看一下之前的文章:JS逆向实战:OB 混淆代码分析+快速绕过 OB 混淆的格式化检测的方法。
这个样本中,几百行代码只有这两行赋值语句是有效的,其他的全部都是 OB 的反调试!并且这两行赋值语句还是动态变化的,每次带上 cookie
请求后都会返回一个新的值,这种情况下就无法使用静态替换的方式来调试代码了。因为静态替换是滞后的,无法实时的去除反调试语句,在下载代码替换后请求就已经发出去了,如果密钥不对的话整个请求就失败了。
这个时候我想到的方案就是动态的去除反调试。如果是静态的情况下,可以使用 AST 抠出解密函数然后解密字符串替换回去,但是动态的情况下就无法扣解密函数了,那就只有先忽略字符串解密了,因为目标是去除反调试,让我们可以在浏览器调试代码。
动态 AST
动态 AST 去除反调试使用的是中间人的方式,不了解的小伙伴可以先看这篇文章:中间人的妙用:自动反混淆 JS 代码并移除反调试代码。
大概的思路就是先在 proxyman 中导入 AST 会用到的 babel
库,然后编写 AST 代码去根据特定的规则去除一些反调试函数。
分析代码结构,通过前面的分析可知,除了两行 window
的赋值语句,其他都可以删除,但是又不能删除解密函数,因为解密函数在 window
属性赋值的时候会用到,所以只需要移除除了解密函数以外的所有函数即可。
在移除函数的时候,主要针对的是函数的执行,函数的定义不删除也无所谓,不影响调试。
来看代码:
1 | const {types, parser, traverse, generator} = require('@users/bundle.js') |
主要有三种情况需要移除,一个是自执行函数,注意是无参的自执行函数,有参数的自执行函数是解密函数,不能移除。另一种情况是参数中带有 this 的函数,可以移除。最后一种情况就是整个文件最外层的函数调用需要移除,还有一个 setInterval
比较简单就不多说了。
注:以上情况可按需调整,以上代码仅限我遇到的样本才能生效,如有其他脚本可以自行调整。
将以上代码整体复制到 proxyman 的脚本功能中,重新刷新网页,会发现不会再触发反调试语句了,可以正常调试了。
总结
以后遇到类似情况的小伙伴可以尝试一下,如果可以做到在不扣解密函数的情况下自动解密字符串就更好了。
本文章首发于个人博客 LLLibra146’s blog
本文作者:LLLibra146
更多文章请关注公众号 (LLLibra146):
版权声明:本博客所有文章除特别声明外,均采用 © BY-NC-ND 许可协议。非商用转载请注明出处!严禁商业转载!