Remote thread injection
字数 1395 2025-08-06 18:08:11

Windows远程线程注入技术详解

1. 基础知识

1.1 核心API函数

CreateProcessA

BOOL CreateProcessA(
  [in, optional]      LPCSTR               lpApplicationName,
  [in, out, optional] LPSTR                lpCommandLine,
  [in, optional]      LPSECURITY_ATTRIBUTES lpProcessAttributes,
  [in, optional]      LPSECURITY_ATTRIBUTES lpThreadAttributes,
  [in]               BOOL                 bInheritHandles,
  [in]               DWORD                dwCreationFlags,
  [in, optional]      LPVOID               lpEnvironment,
  [in, optional]      LPCSTR               lpCurrentDirectory,
  [in]               LPSTARTUPINFOA       lpStartupInfo,
  [out]              LPPROCESS_INFORMATION lpProcessInformation
);

用途:创建一个新进程及其主线程,主要用于获取目标进程的标识符。

VirtualAllocEx

LPVOID VirtualAllocEx(
  [in]           HANDLE hProcess,
  [in, optional] LPVOID lpAddress,
  [in]           SIZE_T dwSize,
  [in]           DWORD  flAllocationType,
  [in]           DWORD  flProtect
);

用途:在目标进程中申请一块内存空间。

WriteProcessMemory

BOOL WriteProcessMemory(
  [in]  HANDLE  hProcess,
  [in]  LPVOID  lpBaseAddress,
  [in]  LPCVOID lpBuffer,
  [in]  SIZE_T  nSize,
  [out] SIZE_T  *lpNumberOfBytesWritten
);

用途:将数据写入指定进程的内存区域。

2. 经典注入方法

2.1 CreateRemoteThread注入

HANDLE CreateRemoteThread(
  [in]  HANDLE                 hProcess,
  [in]  LPSECURITY_ATTRIBUTES  lpThreadAttributes,
  [in]  SIZE_T                 dwStackSize,
  [in]  LPTHREAD_START_ROUTINE lpStartAddress,
  [in]  LPVOID                 lpParameter,
  [in]  DWORD                  dwCreationFlags,
  [out] LPDWORD                lpThreadId
);

实现步骤:

  1. 使用CreateProcessA创建进程获取标识符
  2. 使用VirtualAllocEx在目标进程申请内存
  3. 使用WriteProcessMemory写入shellcode
  4. 使用CreateRemoteThread创建远程线程执行shellcode

2.2 NtCreateThreadEx注入

NtCreateThreadEx是更底层的API,32位和64位下函数原型不同:

64位:

typedef DWORD(WINAPI* functypeNtCreateThreadEx)(
  PHANDLE ThreadHandle,
  ACCESS_MASK DesiredAccess,
  LPVOID ObjectAttributes,
  HANDLE ProcessHandle,
  LPTHREAD_START_ROUTINE lpStartAddress,
  LPVOID lpParameter,
  ULONG CreateThreadFlags,
  SIZE_T ZeroBits,
  SIZE_T StackSize,
  SIZE_T MaximunStackSize,
  LPVOID pUnkown
);

32位:

typedef DWORD(WINAPI *functypeNtCreateThreadEx)(
  PHANDLE ThreadHandle,
  ACCESS_MASK DesiredAccess,
  LPVOID ObjectAttributes,
  HANDLE ProcessHandle,
  LPTHREAD_START_ROUTINE lpStartAddress,
  LPVOID lpParameter,
  BOOL CreateThreadFlags,
  DWORD ZeroBits,
  DWORD StackSize,
  DWORD MaximumStackSize,
  LPVOID pUnkown
);

2.3 RtlCreateUserThread注入

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
);

3. Session 0注入技术

3.1 权限提升

需要获取SeDebugPrivilege权限才能注入系统进程:

void GetPrivilege() {
  HANDLE TokenHandle = NULL;
  OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &TokenHandle);
  TOKEN_PRIVILEGES tp;
  tp.PrivilegeCount = 1;
  LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
  tp.Privileges[0].Attributes = true ? SE_PRIVILEGE_ENABLED : 0;
  AdjustTokenPrivileges(TokenHandle, FALSE, &tp, sizeof(tp), NULL, NULL);
  CloseHandle(TokenHandle);
}

3.2 ZwCreateThreadEx注入

#ifdef _WIN64
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
  PHANDLE ThreadHandle,
  ACCESS_MASK DesiredAccess,
  LPVOID ObjectAttributes,
  HANDLE ProcessHandle,
  LPTHREAD_START_ROUTINE lpStartAddress,
  LPVOID lpParameter,
  ULONG CreateThreadFlags,
  SIZE_T ZeroBits,
  SIZE_T StackSize,
  SIZE_T MaximumStackSize,
  LPVOID pUnkown
);
#else
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
  PHANDLE ThreadHandle,
  ACCESS_MASK DesiredAccess,
  LPVOID ObjectAttributes,
  HANDLE ProcessHandle,
  LPTHREAD_START_ROUTINE lpStartAddress,
  LPVOID lpParameter,
  BOOL CreateSuspended,
  DWORD dwStackSize,
  DWORD dw1,
  DWORD dw2,
  LPVOID pUnkown
);
#endif

4. 线程劫持注入

4.1 相关API

SuspendThread

DWORD SuspendThread([in] HANDLE hThread);

GetThreadContext

BOOL GetThreadContext(
  [in] HANDLE hThread,
  [in, out] LPCONTEXT lpContext
);

SetThreadContext

BOOL SetThreadContext(
  [in] HANDLE hThread,
  [in] const CONTEXT *lpContext
);

ResumeThread

DWORD ResumeThread([in] HANDLE hThread);

4.2 实现步骤

  1. 创建进程获取标识符
  2. 申请内存并写入shellcode
  3. 挂起目标线程
  4. 获取线程上下文
  5. 修改EIP/RIP指向shellcode
  6. 恢复线程执行

5. APC注入

5.1 核心API

QueueUserAPC

DWORD QueueUserAPC(
  [in] PAPCFUNC pfnAPC,
  [in] HANDLE hThread,
  [in] ULONG_PTR dwData
);

SleepEx

DWORD SleepEx(
  [in] DWORD dwMilliseconds,
  [in] BOOL bAlertable
);

5.2 Early Bird技术

变种APC注入,在线程初始化时利用NtTestAlert执行APC

实现步骤:

  1. 创建进程并挂起主线程
  2. 申请内存并写入shellcode
  3. 向线程APC队列添加APC
  4. 恢复线程执行

6. 映射注入技术

6.1 核心API

CreateFileMappingA

HANDLE CreateFileMappingA(
  [in]           HANDLE                hFile,
  [in, optional] LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
  [in]           DWORD                 flProtect,
  [in]           DWORD                 dwMaximumSizeHigh,
  [in]           DWORD                 dwMaximumSizeLow,
  [in, optional] LPCSTR                lpName
);

MapViewOfFile

LPVOID MapViewOfFile(
  [in] HANDLE hFileMappingObject,
  [in] DWORD  dwDesiredAccess,
  [in] DWORD  dwFileOffsetHigh,
  [in] DWORD  dwFileOffsetLow,
  [in] SIZE_T dwNumberOfBytesToMap
);

MapViewOfFile2

PVOID MapViewOfFile2(
  [in] HANDLE FileMappingHandle,
  [in] HANDLE ProcessHandle,
  [in] ULONG64 Offset,
  [in, optional] PVOID BaseAddress,
  [in] SIZE_T ViewSize,
  [in] ULONG AllocationType,
  [in] ULONG PageProtection
);

6.2 实现步骤

  1. 创建文件映射对象
  2. 映射到调用进程地址空间
  3. 写入shellcode
  4. 创建目标进程并挂起
  5. 映射到目标进程地址空间
  6. 插入APC并恢复线程

7. NtCreateSection & NtMapViewOfSection注入

7.1 实现步骤

  1. 使用NtCreateSection创建Section对象
  2. 使用NtMapViewOfSection映射到本地进程(RW)
  3. 使用NtMapViewOfSection映射到目标进程(RX)
  4. 写入shellcode到本地视图
  5. 使用RtlCreateUserThread创建远程线程

8. 防御措施

  1. 监控CreateRemoteThread等敏感API调用
  2. 检测进程内存中的异常区域
  3. 限制SeDebugPrivilege权限
  4. 监控APC队列操作
  5. 检测线程上下文的异常修改

9. 总结

本文详细介绍了Windows平台下多种远程线程注入技术,从经典的CreateRemoteThread到更底层的NtCreateThreadEx、ZwCreateThreadEx,以及线程劫持、APC注入和映射注入等高级技术。每种技术都有其特点和适用场景,安全研究人员需要全面了解这些技术以便更好地防御此类攻击。

Windows远程线程注入技术详解 1. 基础知识 1.1 核心API函数 CreateProcessA 用途:创建一个新进程及其主线程,主要用于获取目标进程的标识符。 VirtualAllocEx 用途:在目标进程中申请一块内存空间。 WriteProcessMemory 用途:将数据写入指定进程的内存区域。 2. 经典注入方法 2.1 CreateRemoteThread注入 实现步骤: 使用CreateProcessA创建进程获取标识符 使用VirtualAllocEx在目标进程申请内存 使用WriteProcessMemory写入shellcode 使用CreateRemoteThread创建远程线程执行shellcode 2.2 NtCreateThreadEx注入 NtCreateThreadEx是更底层的API,32位和64位下函数原型不同: 64位: 32位: 2.3 RtlCreateUserThread注入 3. Session 0注入技术 3.1 权限提升 需要获取SeDebugPrivilege权限才能注入系统进程: 3.2 ZwCreateThreadEx注入 4. 线程劫持注入 4.1 相关API SuspendThread GetThreadContext SetThreadContext ResumeThread 4.2 实现步骤 创建进程获取标识符 申请内存并写入shellcode 挂起目标线程 获取线程上下文 修改EIP/RIP指向shellcode 恢复线程执行 5. APC注入 5.1 核心API QueueUserAPC SleepEx 5.2 Early Bird技术 变种APC注入,在线程初始化时利用NtTestAlert执行APC 实现步骤: 创建进程并挂起主线程 申请内存并写入shellcode 向线程APC队列添加APC 恢复线程执行 6. 映射注入技术 6.1 核心API CreateFileMappingA MapViewOfFile MapViewOfFile2 6.2 实现步骤 创建文件映射对象 映射到调用进程地址空间 写入shellcode 创建目标进程并挂起 映射到目标进程地址空间 插入APC并恢复线程 7. NtCreateSection & NtMapViewOfSection注入 7.1 实现步骤 使用NtCreateSection创建Section对象 使用NtMapViewOfSection映射到本地进程(RW) 使用NtMapViewOfSection映射到目标进程(RX) 写入shellcode到本地视图 使用RtlCreateUserThread创建远程线程 8. 防御措施 监控CreateRemoteThread等敏感API调用 检测进程内存中的异常区域 限制SeDebugPrivilege权限 监控APC队列操作 检测线程上下文的异常修改 9. 总结 本文详细介绍了Windows平台下多种远程线程注入技术,从经典的CreateRemoteThread到更底层的NtCreateThreadEx、ZwCreateThreadEx,以及线程劫持、APC注入和映射注入等高级技术。每种技术都有其特点和适用场景,安全研究人员需要全面了解这些技术以便更好地防御此类攻击。