windows 如何防止DLL注入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/869320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 06:21:46  来源:igfitidea点击:

How do I prevent DLL injection

windowssecuritycode-injection

提问by Clark Gaebel

So the other day, I saw this:

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

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

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

and it goes over three different methods of DLL injection. How would I prevent these from the process? Or at a bare minimum, how do I prevent the first one?

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

I was thinking maybe a Ring 0 driver might be the only way to stop all three, but I'd like to see what the community thinks.

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

回答by Cthulhon

The best technical solution would be to do something that causes the loader code to not be able to run properly after your process initializes. One way of doing this is by taking the NT loader lock, which will effectively prevent any loader action from taking place. Other options include patching the loader code directly in memory to make calls to LoadLibrary fail for the attacker (e.g. insert an int3 breakpoint and self-debug to handle expected cases)..

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

But speaking as a hacker (one who admins the site you linked to, in fact), you're not going to ever stop people from getting code into your process, one way or another. LoadLibrary just happens to be a handy shortcut, but there are tons of different ways to load code manually that you could never hope to stop entirely, short of some extremely involved ring0 code. And even if you do go to ring0, the hackers will be right there beside you.

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

Also, there are plenty of legitimate uses for DLL injection. Theme programs, accessibility tools, and various programs that extend OS functionality can all potentially use DLL injection to give added functionality to any program.

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

回答by Stephen Kellett

How to defend against those 3 techniques:

如何防御这 3 种技术:

CreateRemoteThread

创建远程线程

You can prevent the first technique (CreateRemoteThread which calls LoadLibrary) by hooking LoadLibrary. In your hook you check against a list of DLL names that you know are part of the process and that may be loaded, or you can check against a list of known DLLs you don't want to load.

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

When you find a DLL you don't want to load SetLastError(ERROR_ACCESS_DENIED) then return NULL. I set the last error so that people that write code looking for an error code get one. This appears to work, perhaps a different code may be more appropriate.

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

That will stop the DLL from loading.

这将阻止加载 DLL。

SetWindowsHookEx

设置WindowsHookEx

I think the same technique for CreateRemoteThread blocking will work for SetWindowsHookEx, but only if you can get your hook installed before the SetWindowsHookEx technique has started loading its code (which is typically when the first Window is created in an app - so early in its lifetime).

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

Code Cave

密码洞

Nice technique. Not seen that before. You can defend against this, but you'll have to hook the LoadLibrary entry point (not the IAT table) as the Code Cave calls LoadLibrary directly.

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

As the author of the article commented - there are many ways you can be attacked and you probably will have a hard time defeating them all. But often you only want to defend against certain DLL loads (such as a particular 3rd party DLL that is incompatible with your software because the 3rd party DLL wasn't written properly to accomodate the fact that another hook may also be present, so you block it from loading).

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

回答by bdonlan

The best way would be to ensure no untrusted process gets Administrator access, or runs as the same user account as your application. Without this access, code injection into your application is not possible; and once such a process gets that access, it can cause all kinds of mischief without needing to inject itself into another process - the injection just makes it easier to hide.

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

回答by unixman83

Since this poster alludes that he is investing game anti-hacking, let me shed some light on what I think. As a ex cheater.

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

Just a pointer about game anti-hacking.

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

The best way is to let the server run the core game logic. e.g. In a first person shooter, monitor movements the clients send to the server. Don't allow them to move around at random. Let the server tell the clients where each player is based on its own logic. Don't ever just forward commands. They could be bogus.

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

Who cares if the hacker hacks his own client? just refuse it on the other ones and all is good. For starcraft maphacks, solution is simple. Don't give out gamestate for areas that should be unknown. It saves bandwidth too.

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

I was a big cheater in Delta Force (its an old game). The main trick I used was to warp anywhere in the game by modifying the process memory directly. No DLL required!

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

回答by mrduclaw

Are you looking for a Ring3 solution then? If so, you're wanting to build additional functionality into the system that is not currently ( at least to my knowledge ) provided out-of-the-box, so it will require some bit of work. Also, this is possible from a driver, in fact most of your AV software performs this type of activity regularly.

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

As for stopping the above methods from user-mode, it gets a bit trickier since you can't just register yourself as a call back to process creation or DLL loading. You can, however, if you assume your process has started before theirs, hook CreateRemoteThread and similar functions globally and perform this type of checking yourself.

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

So in effect you'd want to check where CreateRemoteThread wants to create a thread and return an error if you're not happy with it.

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

This would negate the first two methods. For the third method, if you have valid hashes of the original program on disk, then you could always check the hash before loading it. If you're without hashes, you could at least just check some of the simple places someone would add that type of code and look for DLLs you don't expect to be there (e.g. the IAT, or run strings).

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

It's not fool-proof, but it appears to give the functionality you requested.

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

回答by Greg Domjan

Just brief thoughts for discussion :)

只是讨论的简短想法:)

Using a code cave to inject a CRC check into your own code will perhaps slow down others from using other code caves.

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

Polling the process module list for unknown dll's being loaded might help with slowing down people just injecting any old thing with attach thread and message hooks.

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

回答by Ruben Bartelink

Why do you want to prevent this? Is it an actual 'business' need, or are you just interested in a 'hack' to oppose the 'hack'

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

If the user rights permit this, it's by design - the OS provides the facility to all users that you, the administrator of the system have assigned to the accounts under which they run.

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

Raymond Chen's going to be linking here soon...

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

回答by Josh E

I'm not intimately familiar with the Windows API, but I can give you some more generalized pointers:

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

  1. See if you can use Windows Data Execution Prevention (DEP). It will probably not work for all (read: most) situations, because the process outlined in your link is a valid process from the OS's standpoint. Defense in depth though

  2. Ensure that your process methods assert security permissions throughout the application

  3. Statically allocate your memory space so that any new threads spawned into it will either fail or overwrite existing memory space; you'll need probably a hefty chunk of logic to detect and correct for this though.

  4. Factor your code into a device driver or some other low-level type process that you can get covered under the Windows File Protection umbrella.

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

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

  3. 静态分配你的内存空间,这样任何产生的新线程要么失败,要么覆盖现有的内存空间;不过,您可能需要大量的逻辑来检测和纠正这一点。

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

Just saw Cthulon's answer and I'm afraid he's probably correct: anyone who wants to perform code injection on your application will find a way to do so. The steps above might merely make it a bit more difficult.

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

Hope this helps

希望这可以帮助