如何防止 DLL 注入

Posted

技术标签:

【中文标题】如何防止 DLL 注入【英文标题】:How do I prevent DLL injection 【发布时间】:2010-10-26 12:59:00 【问题描述】:

所以前几天,我看到了这个:

http://www.edgeofnowhere.cc/viewtopic.php?p=2483118

它介绍了三种不同的 DLL 注入方法。我将如何阻止这些过程?或者至少,我如何防止第一个?

我在想也许 Ring 0 驱动程序可能是阻止所有这三个的唯一方法,但我想看看社区的想法。

【问题讨论】:

【参考方案1】:

最好的技术解决方案是做一些事情,导致加载程序代码在您的进程初始化后无法正常运行。这样做的一种方法是使用 NT 加载程序锁定,这将有效地阻止任何加载程序操作的发生。其他选项包括直接在内存中修补加载程序代码,以使攻击者对 LoadLibrary 的调用失败(例如插入 int3 断点和自调试以处理预期情况)..

但是,作为一名黑客(实际上是您链接的网站的管理员),您永远无法阻止人们以某种​​方式将代码输入您的流程。 LoadLibrary 恰好是一个方便的快捷方式,但是有很多不同的手动加载代码的方法,除了一些极其复杂的 ring0 代码之外,您永远无法完全停止这些方法。即使你去 ring0,黑客也会在你身边。

此外,DLL 注入还有很多合法用途。主题程序、辅助工具和各种扩展操作系统功能的程序都可能使用 DLL 注入为任何程序提供附加功能。

【讨论】:

虽然不可能阻止所有黑客,但我只想阻止列出的这三种技术。这些是最多的命令,一种技术几乎只使用但大多数 leechers 和脚本小子。仅供参考,代码在注入的 dll 中,所以我要做的就是确保一旦我进入,其他人就无法进入。 请注意,装载机锁是一种全球资源,抓住它(应该是)立即终止。 “都可能使用 DLL 注入来为任何程序提供附加功能” - 并且通常会导致程序崩溃(被注入程序的程序被归咎于崩溃由毫无戒心的用户)。【参考方案2】:

如何防御这 3 种技术:

创建远程线程

您可以通过挂钩 LoadLibrary 来阻止第一种技术(调用 LoadLibrary 的 CreateRemoteThread)。在您的钩子中,您可以检查您知道是进程的一部分并且可能已加载的 DLL 名称列表,或者您可以检查您不想加载的已知 DLL 列表。

当您找到一个 DLL 时,您不想加载 SetLastError(ERROR_ACCESS_DENIED) 然后返回 NULL。我设置了最后一个错误,以便编写代码寻找错误代码的人得到一个。这似乎可行,也许不同的代码可能更合适。

这将停止加载 DLL。

SetWindowsHookEx

我认为 CreateRemoteThread 阻塞的相同技术适用于 SetWindowsHookEx,但前提是您可以在 SetWindowsHookEx 技术开始加载其代码之前安装您的钩子(这通常是在应用程序中创建第一个窗口时 - 这么早在其生命周期内)。

代码洞穴

技术不错。以前没见过。您可以对此进行防御,但您必须挂钩 LoadLibrary 入口点(而不是 IAT 表),因为 Code Cave 直接调用 LoadLibrary。

正如文章的作者所评论的 - 有很多方式可以攻击您,您可能很难将它们全部击败。但通常您只想防御某些 DLL 加载(例如与您的软件不兼容的特定 3rd 方 DLL,因为 3rd 方 DLL 没有正确编写以适应另一个钩子也可能存在的事实,因此您阻止它从加载)。

【讨论】:

我使用 CreateRemoteThread 编写挂钩。挂钩 LoadLibrary 不是防御,因为我不调用 LoadLibrary。我在程序集存根中携带 FindLibrary 和 GetProcedure 地址的内部副本。【参考方案3】:

最好的方法是确保没有不受信任的进程获得管理员访问权限,或者以与您的应用程序相同的用户帐户运行。如果没有这种访问权限,就不可能将代码注入到您的应用程序中;一旦这样的进程获得了访问权限,它可能会导致各种恶作剧,而无需将自己注入另一个进程 - 注入只会使其更容易隐藏。

【讨论】:

是的......这没有帮助。我怎样才能从进程中将进程置于新用户帐户下?【参考方案4】:

由于这张海报暗示他正在投资游戏反黑客,让我谈谈我的想法。作为前作弊者。

只是一个关于游戏反黑客的指针。

最好的办法是让服务器运行核心游戏逻辑。例如在第一人称射击游戏中,监控客户端发送到服务器的动作。不要让他们随意走动。 让服务器根据自己的逻辑告诉客户端每个玩家在哪里。永远不要只转发命令。它们可能是假的。

谁在乎黑客是否入侵了自己的客户端?只是拒绝其他人,一切都很好。对于星际争霸地图黑客,解决方案很简单。不要为应该未知的区域提供游戏状态。它也节省了带宽。

我在 Delta Force 中是个大骗子(这是一个老游戏)。我使用的主要技巧是通过直接修改进程内存来扭曲游戏中的任何地方。无需 DLL!

【讨论】:

【参考方案5】:

那么您是否正在寻找 Ring3 解决方案?如果是这样,您希望在当前(至少据我所知)未提供开箱即用的系统中构建附加功能,因此需要一些工作。此外,这也可以通过驱动程序实现,事实上,您的大多数 AV 软件都会定期执行此类活动。

至于从用户模式停止上述方法,它变得有点棘手,因为您不能只将自己注册为对进程创建或 DLL 加载的回调。但是,如果您假设您的进程已在他们之前启动,则可以全局挂钩 CreateRemoteThread 和类似函数并自己执行此类检查。

所以实际上你想检查 CreateRemoteThread 想在哪里创建一个线程,如果你不满意就返回一个错误。

这将否定前两种方法。对于第三种方法,如果您在磁盘上有原始程序的有效哈希,那么您总是可以在加载之前检查哈希。如果你没有散列,你至少可以检查一些简单的地方,有人会添加那种类型的代码,并寻找你不希望在那里的 DLL(例如 IAT,或运行字符串)。

这不是万无一失的,但它似乎提供了您要求的功能。

【讨论】:

【参考方案6】:

只是简短的讨论:)

使用代码洞穴将 CRC 校验注入您自己的代码可能会减慢其他人使用其他代码洞穴的速度。

轮询正在加载的未知 dll 的进程模块列表可能有助于减慢人们使用附加线程和消息挂钩注入任何旧东西的速度。

【讨论】:

参考:“轮询未知 dll 的进程模块列表”。当你走过时,我觉得我正躲在灌木丛中。我编码注入但不是 DLL 注入,所以你什么都看不到。【参考方案7】:

为什么要阻止这种情况?这是实际的“业务”需求,还是您只是对“黑客”感兴趣以反对“黑客”

如果用户权限允许,这是设计使然 - 操作系统为所有用户提供该功能,是系统管理员分配给他们运行的帐户的。

Raymond Chen 很快就会链接到这里...

【讨论】:

DLL 注入是游戏黑客的常见做法。我只是在玩防止它的方法。反过来,还有解决这些问题的方法。我们要不要停止质疑问题的道德性而改为回答它? 完全不质疑道德。 hte 等式两边的可用信息越多越好。我的观点是,该设施是有意提供的操作系统功能,因此实际上并不是“不应该发生”的事情。因此,任何阻止它的尝试首先都是一种“黑客”,而不是“规避”。但我的主要目的是确认一个人正在寻求参加军备竞赛,而不是认为这是一个通常在应用程序级别调整的东西。显然你是,所以这很清楚...... 这并没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。 @NETScape 6 年前,当我回答这个问题时,我对这个事实的欣赏程度较低,如果我今天要解决同样的问题,我肯定会发表评论。有趣的是,这在过去几天中仅第二次获得了投票。【参考方案8】:

我对 Windows API 不是很熟悉,但我可以给你一些更通用的指针:

    查看是否可以使用 Windows 数据执行保护 (DEP)。它可能不适用于所有(阅读:大多数)情况,因为从操作系统的角度来看,链接中概述的过程是有效的过程。纵深防御

    确保您的流程方法在整个应用程序中声明安全权限

    静态分配您的内存空间,以便生成的任何新线程都将失败或覆盖现有内存空间;你可能需要一大块 逻辑来检测和纠正这一点。

    将您的代码放入设备驱动程序或其他一些您可以在 Windows 文件保护保护伞下涵盖的低级类型进程。

刚刚看到 Cthulon 的回答,恐怕他可能是对的:任何想要在您的应用程序上执行代码注入的人都会找到这样做的方法。上述步骤可能只会让它变得更加困难。

希望对你有帮助

【讨论】:

以上是关于如何防止 DLL 注入的主要内容,如果未能解决你的问题,请参考以下文章

ASP程序防止SQL注入的最好办法?

如何彻底防止SQL注入?

ThinkPHP如何防止SQL注入?

v-html防止XSS注入

ASP.NET如何防止SQL注入

SpringMVC如何有效的防止XSS注入?