浏览器如何阻止进程注入的 RWX 执行

admin 2025年1月11日23:04:44评论7 views字数 1931阅读6分26秒阅读模式

How is my Browser blocking RWX execution

在测试 payload 时,我偶然发现了一个流行浏览器实现的安全功能,它的行为类似于 EDR。通过钩取关键的 Windows API,它在运行时检查线程创建,然后决定是否允许执行。

在常见浏览器中执行 RWX shellcode 失败

我一直在测试一种新型的进程注入技术。这项技术可能会在不久的将来发布在这个博客上,但这里的重点不是特定的注入技术,而是我如何偶然发现了浏览器中一个类似 EDR 的机制。

虽然成功地向像notepad.exe这样的简单程序注入和执行是一个不错的开始,但真正的测试在于确认这种技术是否能在更复杂的应用程序(.NET、像浏览器这样的大型多线程应用等)中正常工作。

浏览器如何阻止进程注入的 RWX 执行

这对注入技术特别重要,因为它们会以某种方式干扰目标进程。因此,确保稳定性是关键。

为此,我编写了一个简单的 shellcode 放在RWX内存区域中,然后尝试使用新技术在多个常见应用程序中执行它。它在我测试的所有应用程序中都能正常工作,除了一个浏览器。

注:为避免法律问题,我不会指明是哪个浏览器或涉及的文件/函数名称

即使尝试以非常简单的方式执行 shellcode(使用CreateRemoteThread()),它仍然会静默失败,线程虽然创建但 shellcode 从未执行。

起初我以为这是由目标进程的技术细节造成的(浏览器可能实现一些特殊功能,修改原生 DLL 等),但后来发现这实际上看起来像是一个有意实现的安全功能,非常类似于 EDR 的行为。

钩取线程创建

与许多安全产品在用户模式通过钩子[1]所做的类似,该浏览器钩取了BaseThreadInitThunk()以获得对进程内部活动的可见性(和控制权)。这个BaseThreadInitThunk调用是线程创建早期步骤之一,你可以在 Process Hacker 中的大多数调用栈中找到它,例如这是我现在的 Sublime 应用程序的调用栈:

浏览器如何阻止进程注入的 RWX 执行

这是kernel32.dll中的正常 API:

浏览器如何阻止进程注入的 RWX 执行

这是我们的浏览器使用的修改版本:

浏览器如何阻止进程注入的 RWX 执行

任何线程创建都会通过那个jmp指令重定向,跳转到浏览器加载的自定义第三方 DLL 中的某个位置,我在网上找到的关于这个 DLL 的信息很少(这促使我深入研究)。

请注意,此时,预期的线程创建地址(我们的 shellcode 在内存中的位置)存储在rdx寄存器中。

逆向工程分析钩子

如上所述,浏览器内的任何线程创建都会首先通过其第三方 DLL 中的自定义检查。该 DLL 相当大,有很多导出函数。这让我很好奇,但就我们这里关心的而言,只有一个例程真正重要。它相当简单,主要包含对VirtualQuery()的调用(红色标记),用于获取我们的 shellcode 所在地址的内存属性:

浏览器如何阻止进程注入的 RWX 执行

关于这个 API 调用的参数提醒[2],它需要三个参数,将 shellcode 地址移入rcx(第一个参数,绿色标记)。

在后续代码中,一些检查会验证这个内存地址是否是PAGE_EXECUTE_READ类型(0x20值,参见这里[3])。

浏览器如何阻止进程注入的 RWX 执行

根据结果(这包含在cmovnz指令中),会发生以下情况:

  • 如果是,它不会干扰预期的执行流程,rdx(包含线程启动时要执行的 shellcode)保持不变供下游代码使用。

  • 如果不是,它会改变线程起始点并用r8中的值覆盖rdx,在这种情况下是一种会立即返回的陷阱:

    浏览器如何阻止进程注入的 RWX 执行

总结:如果尝试执行RWX线程,它将被阻止。

结论

这个检查相当简单且容易绕过(不要在RWX地址中运行),但我发现这种类型的功能相当出人意料,值得写一篇博文,因为我在网上没有找到任何其他相关参考。我不能 100% 确定这纯粹是一个安全控制,但这似乎是唯一合理的解释。浏览器是那些在内存中有RWX区域的应用程序之一(请查看这篇之前的博文[4]...),所以这可能是一个缓解控制,在漏洞利用链试图利用这些RWX区域进行执行时,会使漏洞利用开发变得更加困难。

参考资料

[1] 

在用户模式通过钩子: https://winternl.com/memfuck/

[2] 

关于这个 API 调用的参数提醒: https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualquery

[3] 

这里: https://learn.microsoft.com/en-us/windows/win32/memory/memory-protection-constants

[4] 

这篇之前的博文: https://rwxstoned.github.io/2024-12-06-GimmeShelter/

原文始发于微信公众号(securitainment):浏览器如何阻止进程注入的 RWX 执行

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

发表评论

匿名网友 填写信息