【问题标题】:Detecting reflective DLL injection检测反射 DLL 注入
【发布时间】:2012-09-23 17:16:37
【问题描述】:

在过去的几年里,恶意软件(以及一些渗透测试工具,如 Metasploit 的 Meterpreter 有效负载)已经开始使用reflective DLL injection (PDF) 将 DLL 加载到进程的内存中。好处是文件永远不会写入磁盘并且很难检测到。我见过的很多例子都是基于Joachim Bauch's work

但是,DEF CON 20 Andrew King demonstrated that he was able to detect DLL's injected using reflective DLL injection。他的演讲被称为“Detecting Reflective Injection”。 很遗憾,他没有发布源代码(他当然没有义务这样做)。

更新:显然我错过了,但 Andrew 几年前就开源了这项工作:https://github.com/aking1012/dc20

此外,一个名为“Antimeter”的工具可以在使用反射 dll 注入加载时检测到 Meterpreter 引擎。再次,封闭源代码。

我了解 Andrew King 的工具和 Antimeter 都是用 Python 编写的,并且使用 pydbg/pydasm 来枚举正在运行的可执行文件的内存。

是否有人愿意分享一些通用的源代码(Python、C、Delphi 或其他)来演示如何检测反射 DLL 注入?有内存取证工具可以分析内存转储并找到它,但我希望在正在运行的系统上执行应用程序(就像 antimeter 一样)并找到反射注入 DLL 的进程。

如果您有兴趣了解反射 DLL 注入的工作原理,有一些 open-source code written in Delphi 说明了如何做到这一点。

更新: 我进行了测试,我可以在没有管理员权限的情况下(并且作为普通用户)反射性地注入 DLL,但是作为用户,我当然只能注入以相同完整性级别(以及在我的会话中)运行的进程......但这仍然涵盖Office 套件、Internet Explorer 等应用程序。

【问题讨论】:

  • 值得注意的是:您链接的论文指出 “要发生这些步骤中的任何一个,您应该在主机进程中执行某种形式的代码,大概是通过利用远程代码执行获得的漏洞。” 所以你正在处理一台已经被入侵的机器,使用更多的“行人”技术。
  • 不一定。我可以在我拥有管理员权限的系统上使用 Delphi(或 C++):code.google.com/p/memorymodule。但是你是正确的,这种攻击需要一些复杂性......或者假设你可以使用 Metasploit 框架并且你的目标至少有 1 个未修补的 Java vuln 或 IE 0-day :)
  • 如果你有管理员权限,你可以做任何事情。
  • @DavidHeffernan:如果我正确阅读链接的文章,反射 DLL 注入不需要管理员权限。该练习的主要目的似乎是允许恶意代码从 AV 软件中隐藏。 (更具体地说,它允许您像编写任何其他 Windows DLL 一样编写隐藏的恶意代码。)
  • 在 Antimeter 页面的 cmets 中,作者解释说他只是在内存中搜索与 Meterpreter 相关的字符串。

标签: python c windows delphi winapi


【解决方案1】:

如何挂钩 VirtualProtect API。因为加载自身的 DLL 肯定会在其内存代码范围内设置执行。这是因为(正如您所提到的)他们使用用户访问权限,因此他们必须使用进程用户空间 API。

NTSYSAPI NTSTATUS NTAPI ZwProtectVirtualMemory(
    IN HANDLE ProcessHandle,
    IN PVOID *  BaseAddress,
    IN SIZE_T *     NumberOfBytesToProtect,
    IN ULONG    NewAccessProtection,
    OUT PULONG  OldAccessProtection 
);

如果您在程序的一开始就挂钩,您可以过滤掉可疑的保护调用(启用代码执行的调用)。然后,我会在请求的页面前扫描 PE 标头等,以了解它是一个可加载的模块... 注意:我认为常规 DLL 不会调用此方法,因为 LoadLibrary 在内核空间内处理此问题。正确的? TODO:验证

通常,PE 标头位于第一个可执行代码前面的 0x1000 (4096) 字节或一页。所以一个非常基本的方法可以是扫描“MZ”标签:

char* pe = ((char*)BaseAddress) - 0x1000;
if ((NewAccessProtection == PAGE_EXECUTE || ... ) & pe[0] == 'M' && pe[0] == 'Z')
{
    // do checks here
}

如果您需要有关 API 挂钩的更多信息,请询问或阅读网络上的大量文章。另一个挂钩候选者是:FlushInstructionCache(...)。但我认为只有暴雪将它用于守望者反作弊模块,因为 x86 架构没有理由调用它。

...只是一个想法,

【讨论】:

  • 这对我来说是全新的,所以是一个很好的学习机会。您是否设法验证了您的TODO
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多