低权限PROCESS_QUERY_LIMITED_INFORMATION下CreateRemoteThread生效的技术疑问
这是个很有意思的问题,我来帮你拆解一下背后的核心原因,以及为什么会出现这种看似矛盾的现象:
1. CreateRemoteThread的“隐式权限处理”
你观察到的现象其实是因为CreateRemoteThread作为Win32高层API,在内部做了额外的权限处理逻辑,而不是仅靠你打开进程时指定的PROCESS_QUERY_LIMITED_INFORMATION权限。
当你调用CreateRemoteThread时,系统会:
- 首先检查当前进程是否拥有
SeDebugPrivilege(如果启用,会跳过部分权限检查) - 如果没有该特权,它会尝试从打开的进程句柄中隐式请求额外的权限(比如
PROCESS_CREATE_THREAD),或者利用系统的权限继承/同用户上下文的特殊性,允许线程创建操作 - 简单来说:CreateRemoteThread并不是直接用你传入的句柄权限去执行操作,它会在内部做一层“兜底”的权限适配
2. NtCreateThreadEx的“严格权限要求”
而NtCreateThreadEx作为原生NT API,完全遵循内核级的权限检查规则,它明确要求打开进程时必须持有PROCESS_CREATE_THREAD权限。
当你仅用PROCESS_QUERY_LIMITED_INFORMATION打开进程时,句柄并不包含创建线程的权限,所以直接调用NtCreateThreadEx会因为权限不足失败——它不会像CreateRemoteThread那样帮你做额外的权限申请或适配。
3. 结合你的代码分析
你的代码中注释掉了PROCESS_QUERY_LIMITED_INFORMATION的打开方式,换成了PROCESS_ALL_ACCESS(这个权限包含了PROCESS_CREATE_THREAD),所以此时无论是CreateRemoteThread还是NtCreateThreadEx都能成功。但当你用低权限打开时,就会出现两者的差异:
- CreateRemoteThread通过内部逻辑绕过了权限限制(在同用户上下文、无UAC限制等场景下)
- NtCreateThreadEx因为严格的权限检查直接失败
结论
并不是仅靠低权限就能创建远程线程,而是CreateRemoteThread作为高层API,帮你处理了权限申请的细节。如果要直接使用NtCreateThreadEx,必须确保打开进程时明确包含PROCESS_CREATE_THREAD权限(或者启用SeDebugPrivilege特权)。
内容的提问来源于stack exchange,提问作者Rapunzel

