JS逆向系列11-反调试与反反调试(续)

admin 2024年11月18日10:36:41评论26 views字数 2646阅读8分49秒阅读模式

0x00 前言

本文是对上期反调试与反反调试文章的补充。

0x01 location

我在上期文章中提到过我无法通过hook解决掉location.href,后来也有师傅在留言区提到了另一个location的方法,那就是replace,href在上期文章中已经介绍过了,所以接下来就给大家介绍一下replace方法:

JS逆向系列11-反调试与反反调试(续)

这个方法可以以给定的URL来替换掉当前的资源,例如 window.location.replace("http://www.baidu.com")执行后就会跳转到百度,还有一个效果类似的方法就是location.assign方法:

JS逆向系列11-反调试与反反调试(续)

使用方法也是一样的,但是这两个方法的效果是有区别的。

location.replace()

调用 replace() 方法后,当前页面不会保存到会话历史中(session History),这样,用户点击回退按钮时,将不会再跳转到该页面。

location.assign()

调用 assign() 方法后,当前页面会保存到会话历史中(session History)。

简单演示一下,以下是执行 window.location.assign("http://www.bing.com")的效果:

JS逆向系列11-反调试与反反调试(续)

可见是可以回退到上一页面的,而执行 window.location.replace("http://www.bing.com")就达不到以上的效果:

JS逆向系列11-反调试与反反调试(续)

而这两个方法同样也重写不了(Chrome):

JS逆向系列11-反调试与反反调试(续)

虽然看的是重写了,但是执行 window.location.replace("http://www.bing.com")依然还是原本的效果,还有之前提到过的href也无法hook掉,至少我目前做不到,这些会在之后的hook深入文章中提到。

不过接下来我在这里分享一个hook脚本,是CC11001100师傅写的(这里感谢一下CC11001100师傅开源提供的思路):

JS逆向系列11-反调试与反反调试(续)

github地址:https://github.com/JSREI/page-redirect-code-location-hook

具体代码:

JS逆向系列11-反调试与反反调试(续)

onbeforeunload:

JS逆向系列11-反调试与反反调试(续)

当浏览器窗口关闭或者刷新时,就会触发 beforeunload 事件。

我就拿上期文章中提到的那个跳转案例看下效果,F12访问网站:

JS逆向系列11-反调试与反反调试(续)

可见此时已经设置了location.href并触发了beforeunload事件,跟下堆栈:

JS逆向系列11-反调试与反反调试(续)

直接跟到了设置window.location.href的位置,所以接下来可以替换掉这段定时器从而防止网站跳转。

我自己的解决方案也是只能给出替换,我上文给出的一个替换方法是抓包替换,不过我这两天抽时间写了一个脚本,就拿上期的那个跳转案例演示一下效果:

JS逆向系列11-反调试与反反调试(续)

JS逆向系列11-反调试与反反调试(续)

大家应该能从中看出来其效果,也就是说我通过mitmproxy抓包,将存在location.href和其他两个方法的js文件下载到本地,其中还会copy一份临时的js文件(copy的js文件名格式为:xxx.temp.js),为什么要copy一份,这是因为我们F12查看的js文件都是格式化后的,例如我这里创建一个测试文档,引入一下压缩后的jquery文件:

JS逆向系列11-反调试与反反调试(续)

JS逆向系列11-反调试与反反调试(续)

F12查看:

JS逆向系列11-反调试与反反调试(续)

可见在F12中显示的js文件都是格式化后的,但实际上加载的js是压缩后的,这是一个很重要的知识点,我在之前的自动化加解密文章中也提到过类似的知识点,也就是说我们一定要保证其 文件或数据要和原本加载的一模一样,所以我特地下了两份js下来,备份的js是我们拿来定位反调试代码的,而另一份则是我们用来替换的。

刚刚我已经演示了定位到那段熟悉的反调试代码,现在就去要替换的js中删掉这段代码:

JS逆向系列11-反调试与反反调试(续)

JS逆向系列11-反调试与反反调试(续)

删掉即可:

JS逆向系列11-反调试与反反调试(续)

记住要替换的js一定 不要格式化,上文已经提到过为什么,这里不再过多赘述。

接下来我讲一下如何不打开网站进行替换,不知道大家有没有发现chrome替换的一个特点,我这里随便拿一个网站演示一下:

JS逆向系列11-反调试与反反调试(续)

如果我要替换掉这个jquery,那么替换的文件夹名就会是这样的:

JS逆向系列11-反调试与反反调试(续)

我猜大家应该能理解到我的意图了,这也是为什么我在脚本中还增加了print出js地址的功能:

JS逆向系列11-反调试与反反调试(续)

所以我们替换后的js文件应该放到这个目录下:

xxx.xxx.com/_nuxt/BfRsNvdj.js

打开存放替换后的js的文件夹:

JS逆向系列11-反调试与反反调试(续)

新建一个文件夹,文件夹就是这个网站的域名:

JS逆向系列11-反调试与反反调试(续)

继续创建一个_nuxt文件夹,将替换后的js放进去即可:

JS逆向系列11-反调试与反反调试(续)

JS逆向系列11-反调试与反反调试(续)

现在就完成了替换,开着F12访问一下网站:

JS逆向系列11-反调试与反反调试(续)

现在进入网站就自动加载了我们替换后的js。

工具我已经开源在github上,地址:https://github.com/0xsdeo/Locate_location

注:该工具适用于没有设类似waf的网站,上文提到的那个案例似乎是每天都会更新一下js文件名,读者可以自行对比一下本期存在反调试的那个js文件名和上期的文件名,显然是不一样的,所以遇到这种情况我还是建议通过抓包替换,这样保险一些。

0x02 Bypass Debugger

其实上期文章中我写的bypass debugger脚本还不是那么好,虽然能够实现想要的效果,但是有些地方还是有点多余了,所以我还是进行了优化,具体看下文。

我还是先拿第一个版本的脚本进行优化,直接上代码:

JS逆向系列11-反调试与反反调试(续)

改写前的:

JS逆向系列11-反调试与反反调试(续)

大家应该立马就能看出来哪里改了,就是最后的那段赋原型,我没再去用Object.create方法,直接去赋值了,这种是可以的,至于为什么我上期没这么写,是我个人原因,因为当时在学Object的一些方法,所以就顺着用了这个方法,导致脚本显得有些臃肿了。

临时变量Bypass_debugger.prototype指向的就是Function的原型,所以这里直接赋给重写后的Function原型即可:

JS逆向系列11-反调试与反反调试(续)

所以优化第二版的代码也是顺手的事:

JS逆向系列11-反调试与反反调试(续)

改写前的:

JS逆向系列11-反调试与反反调试(续)

可见代码清晰了不少,我个人觉得是没有哪里需要解释的,上期文章中都讲到过,如果读者有不懂的地方可以在本文下方留言或私信我。所以目前优化成这样就不需要再改写第三版的了,我当时写第三版的脚本时就是为了想让重写constructor的那段代码放到最后,现在就不需要了,因为已经是放到最后了。

最后就是重写Function为构造函数那段hook脚本:

JS逆向系列11-反调试与反反调试(续)

优化后依然是某些案例用不了,原因还是未知。还是那句话,如果有知道为什么的大佬,可以留言或者私信我,本人洗耳恭听。

代码已同步更新在github上,地址:https://github.com/0xsdeo/Hook_JS

原文始发于微信公众号(Spade sec):JS逆向系列11-反调试与反反调试(续)

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月18日10:36:41
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   JS逆向系列11-反调试与反反调试(续)https://cn-sec.com/archives/3404696.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息