如何停止DLL注入
于是有一天,我看到了这个:而且会被注入三个dll。我如何防止这些过程?或者最起码,我怎样才能防止优先权?我在想,也许一个0环驱动可能是阻止这三个的唯一方法,但我想看看我的想法。
-
1.最好的技术解决方案会做到这一点。你的程序初始化后加载代码无法正常运行。一种方法是采用NT loader lock,它将有效地阻止任何加载操作的发生。其他选项包括直接给加载代码时未能调用LoadLibrary的攻击者打补丁(如插入INT3断点和自调试)以应对预期情况...然而,作为一名黑客(实际上是链接到您网站的管理员),您永远无法阻止获取代码的人以这样或那样的方式进入您的进程。调用LoadLibrary恰好是一种方便快捷的CodeGo.net,但是有大量的代码可以通过不同的方式手动加载。你永远不可能完全停下来,短时间参与ring0代码。即使你去了ring0,hacker也会陪在你身边。另外还有大量的DLL注入。计划、辅助工具和扩展操作系统功能的程序都可以通过DLL注入到任何具有附加功能的程序中。
2.如何应对那3种技术防御:CreateRemoteThread的你可以通过链接的LoadLibrary(在CreateRemoteThread中调用LoadLibrary)来阻止优先级技术。在您的钩子上,您检查您知道是进程的一部分并且可以加载的dll的列表,或者您可以检查您不想加载的已知dll的列表。当你找到一个DLL并且不想加载setlasterror(error _ access _ denied)时,它返回NULL。我设置的最后一个错误,让人写代码找到错误代码,得到一个。这好像是一份工作。也许不同的代码可能更合适。这将停止加载DLL。SetWindowsHookEx函数我认为阻止CreateRemoteThread技术将会使SetWindowsHookEx函数起作用,但只有当您可以在SetWindowsHookEx技术开始加载其代码之前调用它时(通常在优先级窗口中,它是在应用程序中创建的,以使您的钩子安装到位——在这样一个早期代码漏洞中,这是一项很好的技术。从来没见过。您可以抵制这种做法,但是您必须调用LoadLibrary入口点(不是IAT表)作为代码洞来直接调用LoadLibrary。正如文章作者所说——被攻击的方式有很多种,你可能觉得很难打败它们。但往往你只是想加载一些DLL(比如某个特定的第三方DLL,这是软件中第三方DLL写的不对的事实,也就是可能存在另一个钩子来防御你加载)。
3.最好的方法是确保没有任何进程具有管理员访问权限,或者作为应用程序的运行用户帐户。没有这个访问权,就不可能把代码注入到应用中,而这样的进程一旦被访问,就可以玩各种恶作剧,而不会把自己注入到其他进程中——注入只能更容易隐藏。
4.你为什么阻止它?这是一个实际的“业务”需要,或者你短时间内对“黑客”感兴趣,反对“黑客”。如果权限允许,它是由设计操作系统提供的一个工具,您的系统管理员分配它们在帐户下运行。Raymond Chen的将很快链接到这里...
由于这张海报暗示他正在投资反黑客,我认为它揭示了什么?作为一个前骗子。关于反黑客只是一个指针。最好的方法是让服务器运行核心逻辑。比如优先射击游戏,监控客户端发送给服务器。不要让他们随意走动。让服务器按照自己的逻辑告诉每个玩家客户端。如果hackerhacker是自己的客户,谁会在乎呢?只是和其他人在一起,一切都很好。对于星际地图黑客来说,解决方法很简单。如果不给出来,应该是未知领域。它节省了带宽。我是三角洲部队里的一个大伪造者(它的一个老的主要招数是通过直接改装在任何地方翘曲。没有所需的DLL!
6.您是否正在寻找环3下的解决方案?如果是这样,你需要在系统中增加额外的功能。它目前(至少据我所知)是现成的吗,所以它需要一个工作位置?另外,从一个驱动程序来说是可能的,其实大部分杀毒软件都会定期进行这种类型的活动。至于停止它,这就变得有点棘手了,因为你不能仅仅把自己注册成一个回调来创建一个进程或者DLL加载。但是,如果您的进程在它们之前启动,您可以全局勾选CreateRemoteThread和类似的函数,然后自己执行这种类型的检查。所以其实你是想检查CreateRemoteThread创建一个线程,不喜欢就返回一个错误。如果您在磁盘上,这将否定对原程序有效的哈希值,因此您可以在加载前检查哈希值。如果你没有散列,你至少可以只检查将添加这种类型的代码的简单位置,并寻找你不期望在那里的dll(如IAT,或运行字符串)。这不是很简单,但似乎给了你需要的功能。
7.我不太熟悉Windows的API,但我可以给你一个更广泛的指针:看看你的Windows数据执行保护(DPE)。可能并不适合所有(阅读:大部分)工作,你链接中列出的流程从OS的角度来看是有效的流程。纵深防御,尽管确保整个应用程序的断言安全权限静态分配空间,因此任何新主题都会产生一个空间,该空间要么失败,要么被覆盖,但您可能需要大量逻辑来检测和纠正这一点。将您的代码分解到设备驱动程序或其他低级类型的进程中,您就可以在Windows文件中获得全面的覆盖。刚刚看到克苏伦的回答(对了,是的!恐怕他是对的:任何愿意在您的应用程序中执行代码注入的人都会找到这样做的方法。上面的步骤让难度增加了一点。我希望这有所帮助。
8.只是一个简单的想法:)给自己的代码注入代码洞CRC校验可能会拖慢其他代码洞。在轮询进程模块列表中加载未知的DLL可能有助于减慢人们的速度,只需用额外的线程钩子注入任何旧的东西。
9.可以阻止优先级技术(CreateRemoteThread,需要LoadLibrary)通过钩子LoadLibrary。在您的钩子上,您检查您知道是进程的一部分并且可以加载的dll的列表,或者您可以检查您不想加载的已知dll的列表。ü如何检查下面的代码基注入器[DllImport("kernel32")],它可以被siurce代码C #检测或检查
公共静态外部IntPtr CreateRemoteThread(
IntPtr hProcess,
IntPtr lpThreadAttributes,
uint dwStackSize,
UIntPtr lpStartAddress,//指向远程进程的原始指针
IntPtr lpParameter,
uint dwCreationFlags,
out IntPtr lpThreadId
);
[DllImport("kernel32.dll")]
公共静态extern IntPtr OpenProcess(
UInt32 dwDesiredAccess,
Int32 bInheritHandle,
Int32 dwProcessId
);
[DllImport("kernel32.dll")]
公共静态extern Int32 CloseHandle(
IntPtr hObject
);
[DllImport("kernel32.dll ",SetLastError = true,ExactSpelling = true)]
静态外部布尔值虚拟自由(
IntPtr hProcess,
IntPtr lpAddress,
UIntPtr dwSize,
uint dwFreeType
);
[DllImport("kernel32.dll ",CharSet = CharSet。Ansi,ExactSpelling = true)]
公共静态外部UIntPtr GetProcAddress(
IntPtr hModule,
字符串procName
);
[DllImport("kernel32.dll ",SetLastError = true,ExactSpelling = true)]
静态extern IntPtr VirtualAllocEx(
IntPtr hProcess,
IntPtr lpAddress,
uint dwSize,
uint flAllocationType,
uint flProtect
);
[DllImport("kernel32.dll")]
静态外部bool WriteProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
字符串lpBuffer,
UIntPtr nSize,
out IntPtr lpnumberofbytes written
);
[DllImport("kernel32.dll ",CharSet = CharSet。自动)]
公共静态外部IntPtr GetModuleHandle(
字符串lpModuleName
);
[DllImport("kernel32 ",SetLastError = true,ExactSpelling = true)]
内部静态extern Int32 WaitForSingleObject(
IntPtr句柄,
Int32毫秒
);
public Int32 GetProcessId(字符串过程)
{
process[]proc list;
ProcList =进程。GetProcessesByName(proc);
返回ProcList[0]。id;
}
public void inject dll(IntPtr hProcess,String strDLLName,Process proc)
{
IntPtr bytesout = IntPtr。零;
IntPtr hThread = IntPtr。零;
//包含DLL文件名的字符串长度+1字节填充
Int32 LenWrite = strDLLName。长度+1;
//在目标进程的虚拟地址空间内分配内存
IntPtr AllocMem = IntPtr。零;
UIntPtr注射器= UIntPtr。零;
//在进程中分配一些内存来加载我们的。动态链接库
AllocMem =(int ptr)VirtualAllocEx(h process,(IntPtr)null,(uint)LenWrite,0x1000,0x 40);//分配pour WriteProcessMemory
//写下。dll到我们新分配的空间。
WriteProcessMemory(hProcess,AllocMem,strDLLName,(UIntPtr)LenWrite,out bytes out);
//函数指针“注入器”
//加载dll
injector =(UIntPtr)GetProcAddress(GetModuleHandle(" kernel 32 . dll ")," loadlibrary a ");
if(注入器==空)
{
控制台。WriteLine("注射器错误!\ n ");
//返回失败
返回;
}
//在目标进程中创建线程,并将句柄存储在hThread中
//加载我们的DLL
hThread =(int ptr)CreateRemoteThread(h process,(IntPtr)null,0,Injector,AllocMem,0,out bytes out);
//确保线程句柄有效
if (hThread == null)
{
//不正确的线程句柄...退货失败
控制台。WriteLine(" hThread [ 1 ]错误!\ n ");
返回;
}
//超时是10秒...
int Result = WaitForSingleObject(hThread,10 * 1000);
//检查线程是否超时...
if(Result = = 0x 00000080 l | | Result = = 0x 00000102 l | | Result = = 0x ffffffff)
{
/*线程超时...*/
控制台。WriteLine(" hThread [ 2 ]错误!\ n ");
//关闭前确保线程句柄有效...防止崩溃。
如果(hThread!=空)
{
//关闭目标进程中的线程
close handle(hThread);
}
返回;
}
//睡眠线程1秒
线程。睡眠(1000);
//清除分配的空间(Allocmem)
VirtualFreeEx(hProcess,AllocMem,(UIntPtr)0,0x 8000);
//关闭前确保线程句柄有效...防止崩溃。
如果(hThread!=空)
{
//关闭目标进程中的线程
close handle(hThread);
}
//返回成功
返回;
}
公共表单1()
{
initialize component();
}
私有void Form1_Load(对象发送方,EventArgs e)
{
}
私有void button1_Click(对象发送方,EventArgs e)
{
string strDLLName = @ " C:\ Users \ Muhammad . QA sim \ Desktop \ QA sim \ testdll inject \ testdll inject \ bin \ Debug \ testdll inject . dll ";
string str process name = " windows forms application 9 ";
int 32 ProcID = GetProcessId(strProcessName);
Process proc =进程。GetProcessById(ProcID);
if(ProcID & gt;= 0)
{
int ptr h process =(int ptr)open process(0x 1 f0fff,1,ProcID);
if (hProcess == null)
{
MessageBox。Show("OpenProcess()失败!");
返回;
}
其他
{
InjectDLL(hProcess,strDLLName,proc);
MessageBox。显示(“注入”);
}