BMC 的暗网

摘要 基板管理控制器(BMC)是现代数据中心服务器的隐性管理者,通过 IPMI 协议提供与主操作系统完全隔离的带外控制能力。其串行 over LAN(SOL)通道可在不触发主机 EDR 的情况下,建立直通系统串行控制台的隐蔽通信隧道。然而,IPMI 2.0 的 RAKP+ 认证握手存在根本性设计缺陷——空口令、Cipher 0 旁路及会话状态机混乱,使得攻击者能在数秒内劫持合法会话或自行建立恶意会话。 BMC 与 IPMI BMC 的硬件定位与特权 BMC 是嵌入在服务器主板上的独立片上系统,拥有自己的 CPU、内存、存储和专用网口。它在电源接通后先于主 CPU 启动,即使主操作系统崩溃或被攻陷,BMC 仍可对外提供远程管理功能——包括电源控制、固件更新、虚拟介质挂载和串行控制台重定向。BMC 通过内部总线(LPC/eSPI)与主机的南桥/芯片组连接,可注入键盘、鼠标和视频信号,实现对主机操作系统的完全带外控制。 这一架构意味着:BMC 是主机的“房东”,而主机操作系统只是“租客”。租客无法阻止房东进入房间,甚至无法察觉房东是否在房间里。 IPMI 协议栈与 SOL 通道 IPMI 是 BMC 与外部管理软件通信的标准协议,定义了请求/响应消息格式、会话管理和传输层绑定(RMCP/RMCP+)。IPMI 2.0 引入了增强认证(RAKP+)和加密通信,但保留了向后兼容的 Cipher 0(无认证无加密)模式。 SOL 是 IPMI 2.0 的可选扩展,它将主机的物理串行端口(UART)封装为 IPMI 的 SOL 消息,通过 RMCP+ 会话在 LAN 上传输。对主机操作系统而言,SOL 只是往串口收发数据,完全不知道数据经由 BMC…

WNF 的幽灵状态

摘要 Windows 通知设施(Windows Notification Facility)是内核向用户态分发系统事件的异步通道,负责传递诸如电池状态、网络连接变化、Shell 执行触发等大量低延迟通知。WNF 的状态数据以键值对形式存储在内核池中,并按临时或永久两种生命周期管理。然而,这一设计隐藏了一个鲜为人知的反取证库房:永久性 WNF 状态即使关联进程退出,其数据依然存活于内核内存中,且重启后仍可从注册表或其他持久化位置恢复。攻击者可通过 NtCreateWnfStateName 与 NtUpdateWnfStateData 在内核池中建立隐形存储,将 Shellcode、C2 配置或加密密钥藏匿于传统取证工具无法触及的角落,并在特定系统事件触发时通过 WNF_SHELLEXECUTE 等 Shell 触发器在用户态启动恶意进程。 WNF架构 轻量级通知引擎 Windows 内核需要向用户态组件推送大量异步事件,例如电源管理通知、Shell 文件关联变更、网络地址变化等。早期实现主要依赖 ETW 提供者和回调,但 ETW 的启用和解析较为笨重。Windows 8 引入 WNF 作为更轻量的替代方案,其设计目标是在内核与用户态之间提供高效、基于状态的订阅通知机制,且无需用户态主动轮询。 WNF 的整体组件架构与交互过程如下: +——————————————————-+ | 用户态层 | | +——————–+ +———————+ | | | Publisher (发布者) | | Subscriber (订阅者) | | | +———+———-+ +———-+———-+ | +————|—————————|————–+ | | NtUpdateWNFStateData| |NtSubscribeWNFStateChange…

单向链表缺陷与 AuthzBasep SecurityDescriptor 传播攻击

摘要 Windows 安全引用监视器是对象访问的最后仲裁者,其访问检查逻辑沿 AuthzBasep 单向链表回溯安全描述符,为用户态权限评估提供“足够快”的缓存答案。然而,该缓存与内核态真实安全描述符之间存在可被精确操纵的传播延迟。攻击者通过在 NtSetSecurityObject 修改 DACL 与 AuthzAccessCheck 读取缓存之间制造 TOCTOU 窗口,可迫使 SRM 基于过期的权限授予访问令牌,造成“用户态通过、内核态拒绝”的悖论权限提升。 Windows 访问检查的分裂模型 安全引用监视器的两条路径 Windows 对对象(文件、注册表、进程)的访问控制由内核模式安全引用监视器集中裁决。当用户态应用程序请求 CreateFile 时,最终会调用 SeAccessCheck(内核态)进行权限评估。然而,大量的用户态授权框架(如 AuthzAccessCheck、AccessCheckByType)并不直接发起内核调用,而是依赖 AuthzBasep 内部的“安全描述符缓存”来模拟访问判断。 这种设计产生了天然的时间裂隙:内核真实安全描述符(位于 OBJECT_HEADER->SecurityDescriptor)由内核线程在 ObpReferenceSecurityDescriptor 中同步更新,而用户态缓存(AuthzBasepCachedSecurityDescriptor)的刷新是异步、节流的,甚至受制于单向链表遍历效率。 AuthzBasep 的单向链表缓存架构 AuthzBasep 是 Windows authz.dll 的核心引擎,内部维护一个单向链表(AuthzBasepSecurityDescriptorList),每个节点包含对象的引用名称、缓存的安全描述符副本、以及上一次刷新时间戳。当应用程序调用 AuthzAccessCheck 时,它遍历该单向链表,查找同名对象的最新缓存描述符,然后基于缓存执行访问检查,不会实时查询内核状态。 单向链表的天然缺陷在于:查找与刷新操作为 O(n) 复杂度,且没有原子性保证。刷新线程(AuthzBasepUpdateThread)周期性唤醒,逐个节点检查 LastUpdateTime,若超过阈值(默认 15 秒)则重新从内核拉取安全描述符。如果攻击者在刷新线程遍历到目标节点之前修改内核安全描述符并触发用户态访问检查,旧版缓存仍然被信任。 传播延迟 内核 SeAccessCheck 与 SepAccessCheck 的调用链分裂 理解分裂链条对于攻击窗口的精准打击至关重要。 用户态请求 →SeAccessCheck (ntoskrnl.exe):直接读取对象内核安全描述符,基于调用者 Token 进行即时权限判定。任何修改(如 NtSetSecurityObject)均立即在此路径中体现。 用户态 Authz 请求 →SepAccessCheck (authz.dll):是 SeAccessCheck 的用户态模拟。它使用缓存的 SecurityDescriptor 副本,并与内核 Token 句柄交互。SepAccessCheck 不与 SeAccessCheck 同步。 分裂意味着:同一对象在同一时刻,SeAccessCheck 可能返回“拒绝”,而 SepAccessCheck 可能返回“允许”。这正是缓存延迟攻击的根基。 AuthzBasepCachedSecurityDescriptor 的刷新触发器 AuthzBasepCachedSecurityDescriptor 结构的关键字段: typedefstruct _AUTHZ_BASEP_CACHED_SD { LIST_ENTRY Link;…

PAC 绕过新维度

摘要 ARM64 的指针认证通过 PACIA/PACIB 指令为返回地址和函数指针附加密码学签名,阻断了传统 ROP/JOP 攻击。然而,PAC 的密钥分域——指令地址用 A-key,数据地址用 B-key——留下了裂隙。攻击者可以在 JavaScript JIT 编译过程中喷射精心构造的 shellcode,利用 JIT 引擎生成混合了返回指令序列的代码,在指令域签名却在数据域校验,从而绕过 PAC 验证。 ARM64 PAC密钥分域与签名 PAC 指令与密钥 ARMv8.3-A 引入了指针认证(PAC),使用基于 QARMA 的轻量级 MAC 算法为 64 位指针生成认证码,嵌入指针的高位。核心指令: PACIA Xd, Xn:使用指令 A-key 对 Xn 生成签名,存储到 Xd。 PACIB Xd, Xn:使用指令 B-key 对 Xn 签名。 AUTIA Xd, Xn:验证 A-key 签名,若失败则将 Xd 设为无效指针。 AUTIB Xd, Xn:验证 B-key 签名。 A-key 用于指令地址(如返回地址、函数指针),B-key…

Mojo IPC 的序列化陷阱

摘要 Chromium 的多进程架构将高风险渲染器囚禁于受限沙箱,所有特权操作必须通过 Mojo IPC 向浏览器进程发起请求。Mojo 接口定义语言(.mojom)自动生成序列化代码,以 C++ 模板的 StructTraits 和 UnionTraits 实现高效编解码。然而,正是这种自动生成的序列化逻辑隐藏了一类致命的陷阱——接口参数校验与调用者能力假设之间的裂缝。攻击者在获得渲染器代码执行权限后,可构造跨越沙箱边界的畸形 Mojo 消息:向 FileSystemManager 接口注入路径遍历序列,利用 Blob 存储系统绕过站点隔离,或通过 WindowOpen 等接口制造幽灵窗口。 Chromium 沙箱架构与 Mojo IPC 基础 站点隔离与进程模型 Chromium 采用 Site Isolation 策略,每个源(origin)被分配到独立的渲染器进程。渲染器运行在受限沙箱中,无法直接访问文件系统、网络或系统调用。任何此类操作必须通过 Mojo 接口向浏览器进程(Browser Process)发出请求,浏览器进程进行权限验证后代理执行。 Mojo 是 Chromium 自研的 IPC 框架,替代了早期的 Legacy IPC 和 ChannelProxy。它提供跨进程的消息传递、接口定义、自动生成绑定代码以及版本控制。Mojo 的核心抽象是 Message Pipe(消息管道),两端由 mojo::Remote 和 mojo::Receiver 持有,分别用于发送和接收接口方法的调用。 Mojo 接口定义与代码生成 Mojo 接口使用 .mojom IDL 定义,例如: // FileSystemManager.mojom (简化) interface FileSystemManager { OpenFile(string path, OpenFlags flags) => (file.File file);…