检测远程线程注入DLL——todo,待深入
检测反射DLL注入
Mick 22 c python windows delphi winapi
在过去几年中,恶意软件(以及Metasploit的计量器有效载荷等一些笔测试工具)已经开始使用反射DLL注入(PDF)将DLL加载到进程的内存中.好处是文件永远不会写入磁盘并且难以检测.我见过的很多例子都是基于Joachim Bauch的工作.
然而,在DEF CON 20中,Andrew King证明他能够使用反射DLL注入来检测DLL的注入.他的演讲被称为" 检测反射注射 ".不幸的是,他没有发布源代码(他当然没有义务这样做).
更新:显然我错过了,但几年前安德鲁做了这项工作的开源:https://github.com/aking1012/dc20
此外,一个名为" Antimeter " 的工具可以在使用反射dll注入加载时检测meterpreter引擎.再一次,闭源.
据我所知,Andrew King的工具和Antimeter都是用Python编写的,并使用pydbg/pydasm来枚举运行可执行文件的内存.
有没有人有他们愿意分享的一些通用源代码(在Python,C,Delphi或其他方面),演示如何检测反射DLL注入?有一些内存取证工具可以分析内存转储并找到它,但我希望在正在运行的系统上执行一个应用程序(比如antimeter),并找到反射注入DLL的进程.
如果您有兴趣了解反射DLL注入的工作原理,可以使用Delphi编写的一些开源代码来说明如何执行此操作.
更新:我测试过,我可以反射性地注入没有管理员权限的DLL(以及作为普通用户),但当然作为用户我只能注入运行在相同完整性级别(以及我的会话中)的进程......但是仍然涵盖Office套件,Internet Explorer等应用程序.
原文:https://blog.csdn.net/a893574301/article/details/80950571
参考GitHub上的AntiInject
1,远程进程注入DLL调用CreateRemoteThread这个API进行注入,而这个API会在目标进程中创建一个进程来调用LoadLibrary来加载自己想注入的DLL从而达到注入效果。
2,在一个进程已经加载的DLL中,每当一个Thread创建的时候就会给每一个加载的DLL发送一个消息DLL_THREAD_ATTACH,我们可以在自己的DLL中来截获每一个线程创建时候的消息,然后判断这个线程起始地址是否是LoadLibraryA/W来判断这个线程是否是通过远程线程注入进来的。
实现代码:
void CheckInject(DWORD dwProcessId);
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_THREAD_ATTACH:
CheckInject(GetCurrentProcessId()); //每次新的线程创建时候检测
break;
}
return TRUE;
}
DWORD GetThreadStartAddr(DWORD dwThreadId)
{
HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION,FALSE,dwThreadId);
DWORD dwStartAddr,dwReturnLen;
if (hThread == NULL)
return 0;
NtQueryInformationThread(hThread, //查询线程起始地址
ThreadQuerySetWin32StartAddress,
&dwStartAddr,
4,
&dwReturnLen);
return dwStartAddr;
}
void Check_StartAddr(DWORD dwStartAddr,DWORD dwThreadId)
{
DWORD dwAddr_LoadLibraryA = (DWORD)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "LoadLibraryA");
DWORD dwAddr_LoadLibraryW = (DWORD)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "LoadLibraryW");
if (dwStartAddr == dwAddr_LoadLibraryA || dwStartAddr == dwAddr_LoadLibraryW)
{
if (MessageBoxA(0, "发现注入的DLL线程,是否杀掉?", "提示", MB_OKCANCEL) == IDOK)
{
TerminateThread(OpenThread(THREAD_ALL_ACCESS,FALSE,dwThreadId),0);
}
}
}
void CheckInject(DWORD dwProcessId)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessId);
THREADENTRY32 te32 = { sizeof(te32) };
Thread32First(hSnapshot, &te32);
do
{
if (te32.th32OwnerProcessID == dwProcessId)
{
Check_StartAddr(GetThreadStartAddr(te32.th32ThreadID),te32.th32ThreadID); //遍历当前进程所有线程的起始地址
}
} while (Thread32Next(hSnapshot, &te32));
}