当前位置 博文首页 > KOOKNUT的博客:RtlCreateUserThread实现Dll注入

    KOOKNUT的博客:RtlCreateUserThread实现Dll注入

    作者:[db:作者] 时间:2021-07-02 18:37

    RtlCreateUserThread函数当然也是ntdll导出的函数,这个比之前的NtCreateThreadEx是要强点的,最起码还能看得见参数有几个,hhhhh,难顶啊。
    在这里插入图片描述
    在这里插入图片描述
    其实CreateRemote和Nt系列和Rtl系列的注入方式和思路基本是一致的,但是这里还是按照惯例,bb一下我的实现思路(这思路我愿意称之为套娃):

    • 从控制台得到想要实施注入的目标进程名字
    • 得到当前进程所在的目录(GetCurrentDirectory),并保存
    • 得到当前进程的位数 (IsWow64Process)
    • 根据进程名字得到当前进程的Id
    • 根据进程Id得到当前进程的完整路径
    • 通过进程完整路径对PE文件解析得到目标进程位数
    • 目标与当前进程的位数进行匹配,决定加载哪一个dll(x86 or x64)
    • 根据当前进程目录,得到dll完整路径
    • 通过GetModuleHandle得ntdll和kernel32模块得句柄
    • 通过GetProcAddress分别从ntdll和kernel32中得到RtlCreateUserThread和LoadLibraryA
    • 通过目标进程Id,打开目标进程,获得进程句柄
    • 在目标进程中申请内存
    • 在申请好的内存中写入Dll完整路径
    • 利用RtlCreateUserThread启动远程线程执行加载Dll,完成注入

    重要部分源码(Win 7 Win10测试):

    #include"RtlCreateUserThread.h"
    #include"Helper.h"
    
    #ifdef UNICODE
    LPFN_LOADLIBRARYW __LoadLibrary = NULL;
    #else
    LPFN_LOADLIBRARYA __LoadLibrary = NULL;
    #endif
    LPFN_RTLCREATEUSERTHREAD __RtlCreateUserThread = NULL;
    
    
    int _tmain()
    {
    	//控制台识别中文
    	setlocale(LC_ALL, "Chinese-simplified");
    
    	TCHAR ProcessImageName[MAX_PATH] = { 0 };//保存进程名字
    
    	TCHAR CurrentFullPath[MAX_PATH] = { 0 }; //当前进程的完整路径
    
    	TCHAR TargetProcessFullPath[MAX_PATH] = { 0 };//目标进程的完整路径
    	ULONG_PTR TargetProcessPathLength = MAX_PATH;
    
    	ULONG ProcessId = 0;//目标进程Id
    
    
    	HANDLE ProcessHandle = INVALID_HANDLE_VALUE;//进程句柄
    	LPVOID VirtualAddress = NULL;
    
    	SIZE_T ReturnLength = 0;
    
    	BOOL  IsOk = FALSE;
    
    	//注入的启动程序和目标程序的位数
    	BOOL  SourceIsWow64 = FALSE;
    	BOOL  TargetIsWow64 = FALSE;
    
    
    	_tprintf(_T("输入一个进程ImageName\r\n"));
    
    
    	TCHAR RcceiveChar = _gettchar();//接受字符串
    	int i = 0;//用来偏移ProcessName字符数组
    	while (RcceiveChar != '\n')
    	{
    		ProcessImageName[i++] = RcceiveChar;
    		RcceiveChar = _gettchar();
    		//ProcessImageName = 0x000000db28fceed0 "Taskmgr.exe"
    	}
    
    	GetCurrentDirectory(MAX_PATH, CurrentFullPath);//保存当前进程的完整路径
    
    	IsWow64Process(GetCurrentProcess(), &SourceIsWow64);//得到当前进程位数
    	//SourceIsWow64 = 0x00000000
    	ProcessId = KtGetProcessIdentify(ProcessImageName);//通过进程名得到进程Id
    	//ProcessId = 0x00003aa0
    	if (ProcessId == 0)
    	{
    		return 0;
    	}
    	IsOk = KtGetProcessFullPath(TargetProcessFullPath,
    		&TargetProcessPathLength, ProcessId, FALSE);
    
    	if (IsOk == FALSE)
    	{
    		return 0;
    	}
    	//判断目标进程位数
    	KtIsWow64Process(TargetProcessFullPath, &TargetIsWow64);
    	//TargetIsWow64 = 0x00000000
    	if (SourceIsWow64 == TRUE && TargetIsWow64 == TRUE)
    	{
    		_tcscat_s(CurrentFullPath, _T("\\Dll.dll"));
    	}
    	else if (SourceIsWow64 == FALSE && TargetIsWow64 == FALSE)
    	{
    		_tcscat_s(CurrentFullPath, _T("\\Dll.dll"));
    	}
    	//_tcscat_s(CurrentFullPath, _T("\\Dll.dll"));//Win 7 32位测试用  因为我的32位虚拟机这函数IsWow64Process得不到正确值
    
    	//CurrentFullPath = 0x000000db28fcf000 "Z:\\Ring3层代码\\[2]Ring3注入\\RtlCreateUserThread\\RtlCreateUserThread\\Dll.dll"
    	HMODULE  NtdllModuleBase = NULL;
    	HMODULE  Kernel32ModuleBase = NULL;
    	NtdllModuleBase = GetModuleHandle(_T("NTDLL.DLL"));
    	//NtdllModuleBase = ntdll.dll!0x00007ffe84160000 (加载符号以获取其他信息) {unused=0x00905a4d }
    	Kernel32ModuleBase = GetModuleHandle(_T("KERNEL32.DLL"));
    	//Kernel32ModuleBase = kernel32.dll!0x00007ffe83fa0000 (加载符号以获取其他信息) {unused=0x00905a4d }
    	if (NtdllModuleBase == NULL || Kernel32ModuleBase == NULL)
    	{
    		KtCloseHandle(ProcessHandle);
    		return 0;
    	}
    	//获取Native API函数的地址
    	__RtlCreateUserThread = (LPFN_RTLCREATEUSERTHREAD)GetProcAddress(NtdllModuleBase,
    		"RtlCreateUserThread");
    	//__RtlCreateUserThread = ntdll.dll!0x00007ffe84166080 (加载符号以获取其他信息)
    	if (__RtlCreateUserThread == NULL)
    	{
    		return 0;
    	}
    #ifdef UNICODE
    	__LoadLibrary = (LPFN_LOADLIBRARYW)GetProcAddress(Kernel32ModuleBase, "LoadLibraryW");
    #else
    	__LoadLibrary = (LPFN_LOADLIBRARYA)GetProcAddress(Kernel32ModuleBase, "LoadLibraryA");
    #endif
    
    	if (__LoadLibrary == NULL) {
    
    		KtCloseHandle(ProcessHandle);
    		return 0;
    	}
    
    
    	ProcessHandle = KtOpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
    	ULONG BufferLength = 0;
    	//在目标进程空间中申请内存
    	BufferLength = (_tcslen(CurrentFullPath) + 1) * sizeof(TCHAR);
    
    	//目标进程空间中申请内存
    	VirtualAddress = VirtualAllocEx(ProcessHandle, NULL, BufferLength, MEM_COMMIT, PAGE_READWRITE);
    
    	if (VirtualAddress == NULL)
    	{
    		KtCloseHandle(ProcessHandle);
    		return 0;
    	}
    	//目标进程空间中写入数据
    	if (KtProcessMemoryWriteSafe(ProcessHandle, VirtualAddress, CurrentFullPath, BufferLength, &ReturnLength) == FALSE)
    	{
    		KtCloseHandle(ProcessHandle);
    		return 0;
    	}
    
    	HANDLE ThreadHandle = INVALID_HANDLE_VALUE;
    	CLIENT_ID ClientId;
    	NTSTATUS Status = __RtlCreateUserThread(
    		ProcessHandle,
    		NULL, 
    		0,
    		0,
    		0,
    		0,
    		(PTHREAD_START_ROUTINE)__LoadLibrary,
    		VirtualAddress,
    		&ThreadHandle,
    		&ClientId);
    	if (Status >= 0)
    	{
    		WaitForSingleObject(ThreadHandle, INFINITE);
    		VirtualFreeEx(ProcessHandle, VirtualAddress, BufferLength, MEM_RELEASE);
    		KtCloseHandle(ProcessHandle);
    	}
    	else
    	{
    
    		VirtualFreeEx(ProcessHandle, VirtualAddress, BufferLength, MEM_RELEASE);
    		KtCloseHandle(ProcessHandle);
    		return 0;
    	}
    	return 0;
    }
    
    // dllmain.cpp : 定义 DLL 应用程序的入口点。
    #include "stdafx.h"
    #include <tchar.h>
    BOOL APIENTRY DllMain(HMODULE hModule,
    	DWORD  ul_reason_for_call,
    	LPVOID lpReserved
    )
    {
    	switch (ul_reason_for_call)
    	{
    	case DLL_PROCESS_ATTACH:
    	{
    		MessageBox(NULL, _T("RtlCreateUserThread"), _T("RtlCreateUserThread"), NULL);
    	}
    	case DLL_THREAD_ATTACH:
    	case DLL_THREAD_DETACH:
    	case DLL_PROCESS_DETACH:
    		break;
    	}
    	return TRUE;
    }
    
    
    

    测试通过Win7 x86(Explorer.exe)和Win10 x64(Taskmgr.exe)
    在这里插入图片描述
    在这里插入图片描述
    今日自勉:永远不要停下自己前进的脚步。

    cs
    下一篇:没有了