
内核是操作系统的心脏,也是攻击者与防御者的终极战场。
当恶意代码获得内核态执行权限,它便不再受任何用户层安全策略的约束——防火墙形同虚设,杀毒软件无能为力。理解Windows内核安全,不是选修课,而是每个安全从业者的必修课。
Windows采用混合内核(Hybrid Kernel)架构,核心文件为ntoskrnl.exe,整体分为三层:
层级 | 组件 | 职责 |
|---|---|---|
硬件抽象层 | HAL.dll | 屏蔽硬件差异,实现跨平台移植 |
微内核层 | ntoskrnl.exe | 进程调度、中断处理、同步原语、内存管理 |
执行体层 | 各类系统服务 | 对象管理、I/O管理、安全引用监视器(SRM) |
其中安全引用监视器(SRM)是整个安全体系的核心。它驻留在内核中,负责执行对象的安全访问检查、管理用户特权、生成安全审计消息。SRM与用户态的LSASS(本地安全权威子系统)协同工作——LSASS负责身份认证与安全策略管理,通过LPC(本地过程调用)与SRM通信,一旦建立连接便不再接受其他连接请求,从架构上杜绝了中间人攻击。
Windows将所有资源抽象为对象(文件、进程、线程、信号量等),每个对象关联一个安全描述符(SD),包含:
线程访问对象时,必须先通过ObCheckObjectAccess调用SRM进行权限校验。这套以对象为核心的访问控制模型,构成了Windows安全的第一道防线。
2005年,微软在Windows x64架构中引入了Patch Guard(内核补丁保护)——一个不知疲倦的哨兵,时刻守护内核代码的完整性。
系统启动时,PG会记录内核关键区域的"原始样貌"(代码段、IDT、GDT、SSDT、关键API等),存入一个约2-4KB的加密结构体——Context。此后每隔约2分钟(±30秒随机偏移),PG通过DPC在系统线程间"接力传递"这个Context,解密后随机抽取3-5个关键区域进行比对。一旦发现篡改,立即触发蓝屏(错误码0x109)。
Context的设计极其精妙:
攻击手法 | 原理 | PG对抗策略 |
|---|---|---|
扫描内存找Context魔数 | 定位AES加密后的固定特征 | 随机化内存布局,每次启动密钥与CPU微码绑定 |
侧信道分析获取密钥 | 通过功耗/时序推测AES密钥 | 密钥与微码深度绑定,每次启动变化 |
异常接管 | 将Context页面标记为不可执行 | 加强异常处理链保护 |
调度劫持 | 定位所有可能调用PG检测的线程 | 随机化调用源,动态创建线程 |
虚拟化攻击 | VT-x创建影子内存空间 | 虚拟化检测机制可识别 |
时间差攻击 | 检测间隔中快速打补丁 | 随机缩短检测间隔 + 哨兵检查 |
实战建议:与其对抗PG,不如使用微软提供的正规API(如NtSetSystemInformation)修改允许调整的内核参数。调试时使用硬件断点而非软件断点(INT3),避免在检测路径上单步执行。
cNTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) {
DriverObject->DriverUnload = DriverUnload;
// 设置IRP处理函数
return STATUS_SUCCESS;
}
VOID DriverUnload(_In_ PDRIVER_OBJECT DriverObject) {
// 释放所有资源
}驱动运行在内核模式,可访问全部系统资源、执行特权指令。正因如此,驱动程序的任何漏洞都可能导致系统级崩溃或被利用提权。
64位内核将内存管理从"节省"转向"最大化利用率":
内核内存分配通过ExAllocatePoolWithTag系列函数完成,必须考虑内存碎片、泄漏和分配失败等问题。
过滤(Filter)是内核安全编程中极其重要的概念——在不影响上层和下层接口的情况下,在内核中插入新功能层。
典型场景:反病毒程序在文件系统和驱动之间加入过滤层,读取文件时扫描病毒特征码。
核心API:
c// 按设备名绑定(设备必须有名字)
NTSTATUS IoAttachDevice(
IN PDEVICE_OBJECT SourceDevice, // 过滤设备
IN PUNICODE_STRING TargetDevice, // 目标设备名,如 L"\\Device\\Serial0"
OUT PDEVICE_OBJECT *AttachedDevice
);
// 按设备对象指针绑定(更通用,推荐)
NTSTATUS IoAttachDeviceToDeviceStackSafe(
IN PDEVICE_OBJECT SourceDevice,
IN PDEVICE_OBJECT TargetDevice,
OUT PDEVICE_OBJECT *AttachedToDeviceObject
);绑定后,原本发给真实设备的IRP会首先到达过滤设备,处理完再传递下去——上层和下层完全无感知。
不同于Inline Hook或IAT Hook,页表Hook通过操纵MMU核心数据结构实现精准劫持:
现代x64采用四级页表:PXE → PPE → PDE → PTE → 物理页。Windows为每个进程维护独立页表副本,但共享物理内存页——这正是突破口。
攻击者修改目标进程的PTE,将目标API所在页面映射为自定义代码页,实现:
关键函数:
cUINT64 GetPTEBase() {
PUCHAR BaseAddr = (PUCHAR)MmGetVirtualForPhysical;
return *(PUINT64)(BaseAddr + 0x22); // 硬编码偏移,随版本变化
}Rootkit是内核安全领域的"终极Boss"。根据《Rootkits: Windows Kernel Security》的经典分类:
类型 | 攻击层面 | 示例 |
|---|---|---|
用户态Rootkit | 修改用户程序 | DLL注入、API Hook |
内核态Rootkit | 修改内核数据结构 | DKOM隐藏进程、SSDT Hook |
引导加载Rootkit | 修改boot sector | bootkit |
固件Rootkit | 修改UEFI/BIOS | 极难检测 |
DKOM(直接内核对象操作)是最经典的内核Rootkit技术:通过直接修改EPROCESS链表,将恶意进程从活动进程列表中摘除,Task Manager和PsSetCreateProcessNotifyRoutine都无法发现。
内核组件攻击面(按危险度排序):
微软近几年在内核安全上投入巨大,缓解措施层层叠加:
机制 | 全称 | 作用 |
|---|---|---|
CFG | Control Flow Guard | 防止ROP/JOP,验证间接调用目标合法性 |
HVCI | Hypervisor-protected Code Integrity | 虚拟机监控代码完整性,阻止内核代码修改 |
VBS | Virtualization-based Security | 隔离安全关键区域,Credential Guard保护凭证 |
ACG | Arbitrary Code Guard | 禁止从数据页生成可执行页,终结shellcode注入 |
CET | Control-flow Enforcement Technology | 硬件级控制流保护,Shadow Stack + IBT |
RFG | Return Flow Guard | 保护返回地址不被篡改 |
JIT hardening | 浏览器JIT进程隔离 | JIT编译代码只能在独立进程中执行 |
代码完整性(CIG)+ 任意代码保护(ACG)的组合意味着:你不能同时拥有可写+可执行的内存页。浏览器利用JIT编译动态代码?必须通过独立worker进程完成,主进程无法直接执行JIT生成的代码。
攻击链路(典型):
漏洞利用(win32k/NTFS/ALPC)
→ 内核态代码执行
→ 绕过CFG(ROP/COOP)
→ 绕过HVCI(利用合法签名驱动)
→ 提升至System权限
→ DKOM隐藏自身 / 过滤监控软件 / 植入后门
防御链路(对应):
补丁管理 + CFG + HVCI + VBS + ACG + CET + PG
+ 内核签名强制(DSE)+ 驱动隔离(WDAC)
+ 攻击面缩减(w32k重构、字体渲染移至用户态)Windows内核安全是一场永不停歇的军备竞赛。攻击者只需找到一个突破口,防御者必须守住每一条战线。
对于安全研究者而言,理解内核不是为了制造威胁,而是为了在Rootkit潜伏数年不被发现的现实中,具备发现它的能力。
内核不相信眼泪,只相信代码。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。