Windows x64内核学习笔记(七)—— Patch Guard(1)基本概念
- Patch Guard
- context结构体
- 攻击手法
- 参考资料
Patch Guard
描述:Patch Guard(简称PG)是Windows x64系统中用于保护内核代码完整性和安全性的保护机制,能够防止任何不受信任的代码或驱动程序修改内核代码,从而防止系统破坏和恶意软件的传播。Patch Guard在系统启动时进行验证,并在系统运行过程中定期执行检查以确保内核代码的完整性。如果发现任何不正确的修改,Patch Guard会使系统蓝屏并重启系统以确保安全性,蓝屏代码为0x109。
原理:读取内核中的数据,并与系统初始化时的值进行比较。
context结构体
描述:PG (内核补丁保护Patch Guard) 检测通常基于 context 结构体。context 结构体是一个内存数据结构,包含了系统内核的重要信息,包括内核代码的状态、配置和数据。Patch Guard 使用这个 context 结构体来验证内核代码的完整性。在系统启动时,PG 会创建并存储 context 结构体,并在系统运行过程中定期检查这个结构体是否被修改。如果发现任何不正确的修改,Patch Guard 将会重启系统以确保安全性。
微软对Patch Guard的描述如下:
“因为打补丁将内核代码替换为未知的、未经测试的代码,因此无法评估第三方代码的质量或影响……微软对在线崩溃分析(OCA)数据的检查表明,系统崩溃通常是由给内核打补丁的恶意和非恶意软件造成的。”
context基本规则(注意:随着微软更新,以下规则在不同版本的系统中不一定通用):
- context大部分时间处于加密状态
- context的数据源来自系统初始化时的最初数据
- context的地址作为系统线程,随着DPC等调度被传递
- context的执行周期约为2min,但是每次检测的目标区块是随机的
- context采用接力的方式调度,具体流程包括自解密、检测逻辑、复制自身到新的context、加密新的context、销毁旧的context
- context检测逻辑的调用源有随机性,在PG初始化时决定
Context内容包括:
- 一小段自解密代码
- 要用到的系统api指针
- 重要的api代码的copy
- INITKDBG节的copy
- 要检测的目标地址、大小、checksum、构成的结构体数组
- …
context结构体包含以下信息:
- 内核代码的版本信息:用于验证系统内核代码是否是最新版本,以确保安全性。
- 内核代码的配置信息:用于验证系统内核代码的配置是否正确,以确保系统可以正常运行。
- 内核代码的数据信息:包括系统内核代码中使用的全局变量、缓存、内存页面等,用于验证内核代码的数据完整性。
- 内核代码的状态信息:包括系统内核代码的执行状态、挂起的线程和中断处理程序等,用于验证内核代码的状态完整性。
context结构体包含以下代码:
- 初始化代码:在系统启动时,初始化代码将创建并存储 context 结构体。
- 检查代码:定期检查代码将检查 context 结构体是否被修改,以确保内核代码的完整性。
- 重启代码:如果发现任何不正确的修改,重启代码将重启系统以确保安全性。
- 恢复代码:如果重启系统,恢复代码将恢复系统的正常运行。
其他:
- context 结构体在大部分时间处于加密状态,这个过程是通过使用内核级的加密技术实现的,主要使用密钥来对 context 结构体进行加密,并在解密时使用同一密钥。这样,即使恶意代码试图访问或修改 context 结构体,其内容仍然是加密的,因此不可读取。内核级的加密技术在内核空间中实现,因此它需要特殊的权限才能访问。这样,可以保护 - context 结构体不被恶意代码访问。
- context的地址,作为系统线程,DPC等的参数,随着调度被传递
- context的验证逻辑执行周期约为2min,但是每次检测的目标区块随机
- context采用接力的方式调度:自解密->检测逻辑->复制自身到新的context->加密新的context->销毁旧的context
- context检测逻辑的调用源有随机性,在PG初始化时决定
攻击手法
- 静态补丁:如直接将函数入口patch为ret,这种方法是最稳定的,唯一的缺点就是要重启才能生效。
- VT实现读/执行分离:这种方法是通过禁止执行关键的代码段来避免检测。这种方法可以通过使用虚拟化技术来实现,但不是所有系统都支持。
- 定位所有的context调用源,针对性patch:这种方法是通过修改代码的特定部分来避免检测。这种方法需要对系统的代码有较深的了解,否则可能导致严重的后果。
- 基于加密算法分析,攻击context的内容:这种方法是通过对context内容进行解密,并修改检测代码来避免检测。此方法需要深入了解加密算法和检测代码,并可能需要使用特殊工具。
- 搜索内存,粗筛context
- 基于加密算法特性,定位context
- 解密context,patch检测逻辑,加密写回context
- 设置context页面不可执行,接管页面异常处理:这种方法是通过禁止对context页面的访问来避免检测。此方法需要在页面异常处理过程中进行操作,以防止检测逻辑的执行。
- 搜索内存,粗筛context
- hook patch fault,接管执行保护异常
- 在异常处理中定位context,阻止检测逻辑
参考资料
- bilibili - _周壑 - x64内核研究
- github - zzhouhe - PG1903
- 看雪 - blindtiger - Patch Guard三部曲
- github - 9176324 - Shark/Doc/Tetrane_PatchGuard_Analysis_RS4_v1.01.pdf