一款 Windows 用户态工具,用于枚举和分类高级本地过程调用(ALPC)端口,包括由 PPL(受保护进程轻量级,Protected Process Light)进程所拥有的端口,即使标准句柄复制在这些端口上失败。
标准枚举工具通常会完全跳过受保护或被拒绝访问的端口,从而造成盲区。本工具动态解析 ALPC 端口对象类型索引,并在端口拒绝标准复制请求时回退到 NtQueryInformationProcess,以准确对其进行分类。
本工具为两类主要受众消除了标准 Windows IPC 枚举中的盲区:
PROCESS_DUP_HANDLE 访问以隐藏其活动。标准工具会静默丢弃这些端口。本工具能够捕获该失败,并转而查询 PS_PROTECTION 结构。如果某个进程拒绝访问,但返回的 Type 和 Signer 均为 0(None),则它不是合法的 Windows PPL 进程,这种情况高度异常,应立即标记并展开调查。在真实 Windows 系统上测试期间,该工具遍历了 58,916 个打开的句柄,并筛选出 2,618 个 ALPC 端口:
原始输出: 本次运行的完整、未经过滤的输出见
alpc_enumerator_output.txt。
关于匿名端口的说明: 为避免终端输出被数千条记录塞满,
main.cpp中默认禁用了匿名端口的控制台打印。如果你需要匿名端口的实时输出,请在编译前取消第 ~451 行checkEntriesVectorForPrint(anonEntries, "Anonymous");的注释。
为了证明用户态枚举的准确性,本工具的输出已与 Windows 内核调试器(WinDbg)进行了手动比对验证。对象地址和 PPL 签名者级别与内核实际情况完全一致。
main.cpp,或通过 MSVC 编译。Release 模式(x64)构建。SeDebugPrivilege 权限)。该工具没有对 ALPC 对象类型索引进行硬编码(硬编码在不同 Windows 构建版本上会失效),而是创建一个临时 ALPC 端口并动态查询其类型,以确定当前主机系统对应的正确索引(例如索引 46)。当标准句柄复制失败时,它会解码 PS_PROTECTION,提取对端口进行分类所需的精确 Type 和 Signer,而无需依赖访问权限。
完整的深度技术解析,请参见这篇 Medium 文章:https://medium.com/@sphinx_321/userland-alpc-enumeration-dynamic-ppl-aware-approach-283541194102
本工具是我正在进行的 ALPC/RPC 与 Windows 内部机制研究的一部分。我将在不久的将来发布更多研究成果以及配套工具。如果你觉得本工具有用,欢迎在 GitHub 或下方列出的社交媒体上关注我,以便第一时间收到后续发布的通知。