检测远程线程注入DLL——todo,待深入
  ppqNYv0Uugli 2023年11月02日 49 0

检测反射DLL注入

 

在过去几年中,恶意软件(以及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等应用程序.


参考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));
}
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  trFW46kwzceA   2024年01月13日   17   0   0 Delphi
  trFW46kwzceA   2024年01月11日   19   0   0 Delphi
  jl63rPptnaFE   2024年02月21日   18   0   0 Delphi
  trFW46kwzceA   2024年01月10日   21   0   0 Delphi
ppqNYv0Uugli