我如何防止DLL注入
所以有一天,我看到这个:
http://www.edgeofnowhere.cc/viewtopic.php?p=2483118
它通过三种不同的DLL注入方法。 我将如何防止这些过程? 或者至less,我如何防止第一个?
我想也许是一个Ring 0驱动程序也许是唯一的方法来阻止所有这三个,但我想看看社区的想法。
最好的技术解决scheme是做一些事情,导致加载程序代码在你的程序初始化后无法正常运行。 这样做的一种方法是通过使用NT加载器锁,这将有效地防止任何加载器动作发生。 其他选项包括直接在内存中修改加载器代码,以便对攻击者调用LoadLibrary失败(例如插入一个int3断点和自我debugging以处理预期的情况)。
但是作为一个黑客(实际上是pipe理你所链接的站点的人),你永远不会阻止人们以这种或那种方式让代码进入你的程序。 LoadLibrary恰好是一个方便的捷径,但是手动加载代码有很多不同的方法,你永远不可能完全停下来,因为缺less一些极其复杂的ring0代码。 而且,即使你真的去了ring0,黑客也会在你身边。
而且,DLL注入有很多合法的用途。 主题程序,辅助function工具以及扩展操作系统function的各种程序都可能使用DLL注入来为任何程序增加function。
如何防御这三种技术:
远程线程
您可以通过挂钩LoadLibrary来防止第一种技术(调用LoadLibrary的CreateRemoteThread)。 在你的钩子中,你检查一个你知道是进程的一部分并且可能被加载的DLL名字列表,或者你可以检查一个你不想加载的已知DLL列表。
当你find一个DLL你不想加载SetLastError(ERROR_ACCESS_DENIED)然后返回NULL。 我设置了最后一个错误,使编写代码寻找错误代码的人得到一个。 这似乎工作,也许不同的代码可能更合适。
这将停止加载DLL。
调用SetWindowsHookEx
我认为CreateRemoteThread阻塞技术同样适用于SetWindowsHookEx,但是只有在SetWindowsHookEx技术开始加载代码之前,你可以安装你的钩子(通常是在应用程序中创build第一个窗口的时候 – 在它的生命早期)。
代码洞
好的技术。 之前没有见过。 你可以为此辩护,但是当代码洞直接调用LoadLibrary时,你必须钩住LoadLibrary入口点(而不是IAT表)。
正如这篇文章的作者所评论的 – 有很多方法可以被攻击,你可能会很难打败他们。 但是通常你只想防御某些DLL加载(比如与你的软件不兼容的特定的第三方DLL,因为第三方DLL没有被正确写入,以适应另一个钩子也可能存在的事实,所以你阻止它从加载)。
最好的办法是确保没有不受信任的进程获得pipe理员访问权限,或者以与您的应用程序相同的用户帐户运行。 没有这个访问权限,代码注入你的应用程序是不可能的; 一旦这样的过程获得了访问权限,就可能导致各种恶作剧,而不需要将自己注入另一个进程 – 注入只是使其更容易隐藏。
由于这张海报暗示他正在投资游戏反黑客行为,请让我点亮我的想法。 作为一个骗子。
只是一个关于游戏反黑客的指针。
最好的方法是让服务器运行核心游戏逻辑 。 例如,在第一人称射击游戏中,监视客户发送到服务器的移动。 不要让他们随意移动。 让服务器告诉客户每个玩家在哪里基于自己的逻辑 。 永远不要只转发命令。 他们可能是假的。
谁在乎黑客是否侵入了自己的客户呢? 只要拒绝其他的,一切都很好。 对于星际地图,解决scheme很简单。 不要把游戏状态放在不知道的地方。 它也可以节省带宽。
我是三angular洲部队(它是一个老游戏)的大骗子。 我使用的主要技巧是通过直接修改进程内存来改变游戏中的任何位置。 不需要DLL!
你在寻找Ring3解决scheme吗? 如果是这样的话,你需要在系统中增加额外的function,而这些function目前还不是(至less据我所知)是可以提供的,所以需要一些工作。 而且,这可能来自于驱动程序,实际上大多数AV软件都会定期执行此类活动。
至于从用户模式停止上述方法,它有点棘手,因为你不能注册自己作为一个callback进程创build或DLL加载。 但是,如果您假定您的进程已经在他们的进程之前启动了,那么可以全局挂接CreateRemoteThread和类似的函数,并执行这种types的检查。
所以实际上你会想要检查CreateRemoteThread想要创build一个线程的地方,如果你不满意它会返回一个错误。
这将否定前两种方法。 对于第三种方法,如果你在磁盘上有原始程序的有效哈希,那么你可以在加载它之前总是检查哈希。 如果你没有散列,你至less可以检查一些简单的地方有人会添加这种types的代码,并寻找你不希望在那里的DLL(例如,IAT,或运行string)。
这不是傻瓜,但它似乎给你所要求的function。
你为什么要防止这个? 这是一个真正的“商业”需求,还是只是对“黑客”感兴趣,反对“黑客”
如果用户权限允许这样做,那就是devise – 操作系统为系统pipe理员分配给他们运行的帐户的所有用户提供了便利。
Raymond Chen很快就会联系到这里
只是简要的讨论想法:)
使用代码洞向你自己的代码注入一个CRC校验可能会减慢其他代码使用其他代码洞。
轮询进程模块列表的未知DLL正在加载可能有助于减缓人们只是注入任何旧东西附加线程和消息钩子。
我不是很熟悉Windows API,但我可以给你一些更广义的指针:
-
看看你是否可以使用Windows数据执行保护(DPE)。 它可能不适用于所有(大多数情况下),因为链接中概述的过程从操作系统的angular度来看是一个有效的过程。 尽pipe纵深防御
-
确保您的stream程方法在整个应用程序中声明安全权限
-
静态分配您的内存空间,以便任何新的线程产生将失败或覆盖现有的内存空间; 你可能需要大量的逻辑来检测和纠正这个问题。
-
将代码分解为设备驱动程序或其他一些可在Windows文件保护伞下获得的低级types进程。
刚刚看到Cthulon的回答(好名字,顺便说一句),恐怕他可能是正确的:任何人想要在你的应用程序执行代码注入将find一种方法来这样做。 上面的步骤可能只会让它更难一些。
希望这可以帮助