CreateRemoteThread RtlCreateUserThread NtCreateThreadEx

 

函数原型
HANDLE CreateRemoteThread(
  HANDLE hProcess,                          // handle to process
  LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
  SIZE_T dwStackSize,                       // initial stack size
  LPTHREAD_START_ROUTINE lpStartAddress,    // thread function
  LPVOID lpParameter,                       // thread argument
  DWORD dwCreationFlags,                    // creation option
  LPDWORD lpThreadId                        // thread identifier
);
参数说明:
hProcess 
[输入] 进程句柄
lpThreadAttributes 
[输入] 线程安全描述字,指向SECURITY_ATTRIBUTES结构的指针
dwStackSize 
[输入] 线程栈大小,以字节表示
lpStartAddress 
[输入] 一个LPTHREAD_START_ROUTINE类型的指针,指向在远程进程中执行的函数地址
lpParameter 
[输入] 传入参数
dwCreationFlags 
[输入] 创建线程的其它标志
lpThreadId 
[输出] 线程身份标志,如果为NULL,则不返回
返回值
成功返回新线程句柄,失败返回NULL,并且可调用GetLastError获得错误值。

CreateRemoteThread的注入步骤。

1.提权

2.根据进程ID打开对方进程OpenProcess,得到进程句柄

3.根据进程句柄在目标进程中申请内存VirtualAllocEx

4.在目标进程中刚刚申请的内存空间中写入所需参数(Dll的完整路径)WriteProcessMemory

5.用GetProcAddress得到LoadLibraryW的模块加载地址

6.启动远程线程CreateRemoteThread,并在第四参数传入该线程需要执行的函数名(即LoadLibrary)


DWORD EnablePrivilege(HANDLE ProcessHandle, BOOL IsEnable, LPCTSTR RequireLevel)
{

	DWORD LastError = 0;
	HANDLE TokenHandle = NULL;

	if (!OpenProcessToken(ProcessHandle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle))
	{
		LastError = GetLastError();
		if (TokenHandle)
		{
			CloseHandle(TokenHandle);
			TokenHandle = NULL;
			return LastError;
		}
	}
	TOKEN_PRIVILEGES TokenPrivileges = { 0 };

	LUID v1;
	if (!LookupPrivilegeValue(NULL, RequireLevel, &v1))
	{
		LastError = GetLastError();
		CloseHandle(TokenHandle);
		TokenHandle = NULL;
		return LastError;
	}
	TokenPrivileges.PrivilegeCount = 1;
	TokenPrivileges.Privileges[0].Luid = v1;
	if (IsEnable)
	{
		TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	}
	else
	{
		TokenPrivileges.Privileges[0].Attributes = IsEnable = SE_PRIVILEGE_ENABLED;
	}

	AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges,
		sizeof(TOKEN_PRIVILEGES), NULL, NULL);

	LastError = GetLastError();
	CloseHandle(TokenHandle);
	TokenHandle = NULL;
	return LastError;
}
#include "Inject.h"

void _tmain(int argc, TCHAR **argv, TCHAR **envp)
{
	_tsetlocale(LC_ALL, _T("chs"));
	DWORD ProcessId;
	HANDLE ProcessHandle;
	TCHAR DllFullPath[MAX_PATH] = _T("DllPath");
	SIZE_T DllFullPathLength;
	LPVOID VirtualAddress;
	BOOL IsOk = FALSE;
	_tscanf_s(_T("%d"), &ProcessId);
        EnablePrivilege(GetCurrentProcess(), TRUE, SE_DEBUG_NAME);
	ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
	DllFullPathLength = (_tcslen(DllFullPath) + 1) * sizeof(TCHAR);
	VirtualAddress = VirtualAllocEx(ProcessHandle, NULL, DllFullPathLength, MEM_COMMIT, PAGE_READWRITE);
	
	IsOk = WriteProcessMemory(ProcessHandle, VirtualAddress, DllFullPath, DllFullPathLength, NULL);
	
	HANDLE ThreadHandle = CreateRemoteThread(ProcessHandle,
		NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary,     //当前模块中导入函数
		VirtualAddress, 0, NULL);

	if (ThreadHandle == NULL)
	{
		VirtualFreeEx(ProcessHandle, VirtualAddress, DllFullPathLength, MEM_RELEASE);
		goto Exit;
	}
	//等待远程线程结束
	WaitForSingleObject(ThreadHandle, INFINITE);

	if (VirtualAddress != NULL)
	{
		VirtualFreeEx(ProcessHandle, VirtualAddress, DllFullPathLength, MEM_RELEASE);
	}
Exit:
	if (ProcessHandle != NULL)
	{
		CloseHandle(ProcessHandle);
	}

	_tprintf_s(_T("Press Any Key To Continue.\r\n"));
	_gettchar();
}

5.18日更新

因为在整理注入,发现两种和CreateRemoteThread思想基本一致的方法,所以就不再开一篇博客,写在这里吧。

RtlCreateUserThread 这是一个ntdll导出的函数,但是没有公开,需要自己构建函数指针。

typedef DWORD(WINAPI * pRtlCreateUserThread)(
	IN HANDLE 					ProcessHandle,
	IN PSECURITY_DESCRIPTOR 	                SecurityDescriptor,
	IN BOOL 					CreateSuspended,
	IN ULONG					StackZeroBits,
	IN OUT PULONG				        StackReserved,
	IN OUT PULONG				        StackCommit,
	IN LPVOID					StartAddress,
	IN LPVOID					StartParameter,
	OUT HANDLE 					ThreadHandle,
	OUT LPVOID					ClientID
	);
	IsOk = __RtlCreateUserThread(
		ProcessHandle, 
		NULL, 
		0, 
		0, 
		0, 
		0,
		(PTHREAD_START_ROUTINE)LoadLibrary, 
		VirtualAddress, 
		&ThreadHandle, 
		NULL);

NtCreateThreadEx同样是ntdll导出的函数,未公开,自己构建函数指针。

typedef NTSTATUS(WINAPI *LPFUN_NtCreateThreadEx) (
	PHANDLE hThread,
	ACCESS_MASK DesiredAccess,
	LPVOID ObjectAttributes,
	HANDLE ProcessHandle,
	LPTHREAD_START_ROUTINE lpStartAddress,
	LPVOID lpParameter,
	BOOL CreateSuspended,
	ULONG StackZeroBits,
	ULONG SizeOfStackCommit,
	ULONG SizeOfStackReserve,
	LPVOID lpBytesBuffer
	);
	IsOk = __NtCreateThreadEx(
		&ThreadHandle,
		THREAD_ALL_ACCESS, 
		NULL, 
		ProcessHandle, 
		(LPTHREAD_START_ROUTINE)LoadLibrary, 
		VirtualAddress,
		FALSE, 
		NULL, 
		NULL, 
		NULL, 
		NULL);

注入过程和CreateRemoteThread基本类似,只不过这两个函数需要GetProcAddresss获得函数地址。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值