NtCreateUserProcess 初探与玩法
字数 1478 2025-08-25 22:58:29
NtCreateUserProcess 深入解析与实战应用
1. 基本概念与背景
NtCreateUserProcess 是 Windows 系统底层用于创建用户模式进程的系统调用。相比传统的 CreateProcess API,它提供了更底层的进程创建控制能力。
1.1 历史演变
-
在 XP 时代,创建进程需要执行四个系统调用:
- NtOpenFile
- NtCreateSection
- NtCreateProcess(Ex)
- NtCreateThread(Ex)
-
现代 Windows 系统中,NtCreateUserProcess 整合了这些功能,只需一个系统调用即可创建新进程
1.2 与 CreateProcess 的关系
CreateProcess 是用户态 API,其内部调用链为:
kernel32.dll!CreateProcessW
→ CreateProcessInternalW
→ ntdll.dll!NtCreateUserProcess
2. NtCreateUserProcess 函数原型与参数详解
NTSTATUS NTAPI NtCreateUserProcess(
_Out_ PHANDLE ProcessHandle,
_Out_ PHANDLE ThreadHandle,
_In_ ACCESS_MASK ProcessDesiredAccess,
_In_ ACCESS_MASK ThreadDesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES ProcessObjectAttributes,
_In_opt_ POBJECT_ATTRIBUTES ThreadObjectAttributes,
_In_ ULONG ProcessFlags,
_In_ ULONG ThreadFlags,
_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
_Inout_ PPS_CREATE_INFO CreateInfo,
_In_ PPS_ATTRIBUTE_LIST AttributeList
);
2.1 关键参数解析
2.1.1 句柄与访问权限
ProcessHandle和ThreadHandle:存储创建的进程和线程句柄ProcessDesiredAccess和ThreadDesiredAccess:进程和线程的访问权限- 常用值:
PROCESS_ALL_ACCESS和THREAD_ALL_ACCESS
- 常用值:
2.1.2 对象属性
ProcessObjectAttributes和ThreadObjectAttributes:指向OBJECT_ATTRIBUTES结构
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES;
2.1.3 进程和线程标志
ProcessFlags和ThreadFlags:控制创建行为
常用进程标志:
#define PROCESS_CREATE_FLAGS_BREAKAWAY 0x00000001
#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT 0x00000002
#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES 0x00000004
#define PROCESS_CREATE_FLAGS_SUSPENDED 0x00000200
常用线程标志:
#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001
#define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004
#define THREAD_CREATE_FLAGS_INITIAL_THREAD 0x00000080
2.1.4 进程参数
ProcessParameters:指向RTL_USER_PROCESS_PARAMETERS结构
typedef struct _RTL_USER_PROCESS_PARAMETERS {
BYTE Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
使用 RtlCreateProcessParametersEx 初始化:
RtlCreateProcessParametersEx(&ProcessParameters, &ImagePath, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
RTL_USER_PROCESS_PARAMETERS_NORMALIZED);
2.1.5 创建信息
CreateInfo:指向PS_CREATE_INFO结构
typedef struct _PS_CREATE_INFO {
SIZE_T Size;
PS_CREATE_STATE State;
// ...
} PS_CREATE_INFO;
基本初始化:
CreateInfo.Size = sizeof(CreateInfo);
CreateInfo.State = PsCreateInitialState;
2.1.6 属性列表
AttributeList:指向PS_ATTRIBUTE_LIST结构
typedef struct _PS_ATTRIBUTE {
ULONG_PTR Attribute;
SIZE_T Size;
union {
ULONG_PTR Value;
PVOID ValuePtr;
};
PSIZE_T ReturnLength;
} PS_ATTRIBUTE, *PPS_ATTRIBUTE;
typedef struct _PS_ATTRIBUTE_LIST {
SIZE_T TotalLength;
PS_ATTRIBUTE Attributes[1];
} PS_ATTRIBUTE_LIST, *PPS_ATTRIBUTE_LIST;
初始化示例:
PPS_ATTRIBUTE_LIST AttributeList = (PS_ATTRIBUTE_LIST*)RtlAllocateHeap(
RtlProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PS_ATTRIBUTE));
AttributeList->TotalLength = sizeof(PS_ATTRIBUTE_LIST) - sizeof(PS_ATTRIBUTE);
AttributeList->Attributes[0].Attribute = PS_ATTRIBUTE_IMAGE_NAME;
AttributeList->Attributes[0].Size = NtImagePath.Length;
AttributeList->Attributes[0].Value = (ULONG_PTR)NtImagePath.Buffer;
3. 实战应用
3.1 基本进程创建
// 初始化UNICODE_STRING
UNICODE_STRING ImagePath;
RtlInitUnicodeString(&ImagePath, (PWSTR)L"\\??\\C:\\Windows\\System32\\calc.exe");
// 创建进程参数
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
RtlCreateProcessParametersEx(&ProcessParameters, &ImagePath, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
RTL_USER_PROCESS_PARAMETERS_NORMALIZED);
// 初始化创建信息
PS_CREATE_INFO CreateInfo;
CreateInfo.Size = sizeof(CreateInfo);
CreateInfo.State = PsCreateInitialState;
// 初始化属性列表
PPS_ATTRIBUTE_LIST AttributeList = (PS_ATTRIBUTE_LIST*)RtlAllocateHeap(
RtlProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PS_ATTRIBUTE));
AttributeList->TotalLength = sizeof(PS_ATTRIBUTE_LIST) - sizeof(PS_ATTRIBUTE);
AttributeList->Attributes[0].Attribute = PS_ATTRIBUTE_IMAGE_NAME;
AttributeList->Attributes[0].Size = ImagePath.Length;
AttributeList->Attributes[0].Value = (ULONG_PTR)ImagePath.Buffer;
// 调用NtCreateUserProcess
HANDLE hProcess, hThread;
NtCreateUserProcess(&hProcess, &hThread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS,
NULL, NULL, NULL, NULL, ProcessParameters, &CreateInfo,
AttributeList);
// 清理资源
RtlFreeHeap(RtlProcessHeap(), 0, AttributeList);
RtlDestroyProcessParameters(ProcessParameters);
3.2 父进程欺骗(PPID Spoofing)
PPID欺骗是一种使恶意进程看起来像是由合法进程产生的技术,用于规避检测。
实现步骤:
- 获取目标父进程句柄
OBJECT_ATTRIBUTES oa;
InitializeObjectAttributes(&oa, 0, 0, 0, 0);
CLIENT_ID cid = { (HANDLE)5644, NULL }; // 5644为目标父进程ID
HANDLE hParent = NULL;
NtOpenProcess(&hParent, PROCESS_ALL_ACCESS, &oa, &cid);
- 检查父进程完整性级别(可选)
HANDLE hToken;
OpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
DWORD cbTokenIL = 0;
PTOKEN_MANDATORY_LABEL pTokenIL = NULL;
GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &cbTokenIL);
pTokenIL = (TOKEN_MANDATORY_LABEL)LocalAlloc(LPTR, cbTokenIL);
GetTokenInformation(hToken, TokenIntegrityLevel, pTokenIL, cbTokenIL, &cbTokenIL);
DWORD dwIntegrityLevel = GetSidSubAuthority(pTokenIL->Label.Sid, 0);
// dwIntegrityLevel 值对应: LOW, MEDIUM, HIGH, SYSTEM
- 添加父进程属性
AttributeList->Attributes[1].Attribute = PS_ATTRIBUTE_PARENT_PROCESS;
AttributeList->Attributes[1].Size = sizeof(HANDLE);
AttributeList->Attributes[1].ValuePtr = hParent;
// 注意增加TotalLength以容纳新属性
4. 优势与应用场景
4.1 优势
- 规避检测:相比CreateProcess,NtCreateUserProcess更底层,不易被安全产品Hook
- 更细粒度控制:直接控制进程创建的各个阶段
- 隐蔽性:可实现PPID欺骗等高级技术
4.2 应用场景
- 恶意软件开发中规避检测
- 渗透测试中实现隐蔽进程创建
- 安全产品开发中监控进程创建行为
- 系统工具开发中需要精细控制进程创建
5. 注意事项
- 内存管理:正确释放分配的资源(RtlFreeHeap, RtlDestroyProcessParameters)
- 错误处理:检查NTSTATUS返回值
- 权限要求:某些操作需要高权限(如SeTcb)
- 兼容性:不同Windows版本可能有细微差异
6. 扩展学习
- 研究NtCreateProcessEx与NtCreateUserProcess的区别
- 探索更多PS_ATTRIBUTE类型及其用途
- 结合进程注入技术实现更复杂的攻击链
- 研究如何检测此类隐蔽的进程创建行为