从内核到用户-全方位驱动程序安全性测试
如果无法正常显示,请先停止浏览器的去广告插件。
1. 从内核到用户:
全方位驱动程序安全性测试
分享人:杨霄
2. 个人简介
•姓名:杨霄
•所在组织:技术中台-质量工程部
•专业领域:windows客户端安全测试
3. 目录
01 02 03
驱动程序简介 常见安全漏洞和案例分析 驱动安全测试
4. 引言-驱动初印象
驱动是一个用于让操作系统和硬件设备通信的软件组件
5. 引言-驱动初印象
应用程序
假设一个应用程序需要从硬件设备读取一些数据
操作系统
驱动
硬件设备
6. 引言-驱动的扩展
并不是所有的驱动都必须由生产真实设备的厂商所写
一般情况下设备都会按照已发布的硬件标准生产,所以按照标准的协议来开发即可。
并不是所有的驱动程序都会直接与真实的设备进行通信
在和真实硬件设备通信的过程中是一系列驱动配合完成的,中间层的一些驱动并不会直接和硬件
通信,只是做了一些数据的处理和传递。
驱动程序是观察或参与操作系统和设备之间通信的任何软件组件
7. 引言-驱动的扩展
软件驱动程序始终在内核模式下运行。 编写软件驱动程序的主要原因是要获取对仅在内核模式下
可用的受保护数据的访问权限。 但是,设备驱动程序并不总是需要访问内核模式数据和资源。
因此某些设备驱动程序在用户模式下运行。
User mode 应用程序
Kernel mode 软件驱动程序
受保护的数据
8. 驱动程序简介
9. 驱动程序简介-用户模式VS内核模式
用户模式
权限受限的执行环境,通常用于运行应用程序,不能
直接访问操作系统内核和硬件。
内核模式
具有高权限和直接硬件访问能力的执行环境,通常用
于运行操作系统内核和驱动程序。
10. 驱动程序简介 – 驱动分类
文件系统驱动 网络协议驱动
中间层驱动 过滤驱动 WFP
底层驱动 设备驱动 总线驱动
上层驱动
11. 驱动程序简介 – 驱动安全
驱动在安全领域的应用
驱动的安全隐患
• 弹窗和拦截 • 权限滥用
• HOOK • 内存安全
• 绑定与过滤 • 任意读,利用信息泄漏
• 注册回调来监控 • 任意写,污染关键数据结构
12. 驱动程序简介 – 驱动安全示例
CVE-2021-3437 | HP OMEN Gaming Hub 权限升级漏洞影响数百万台游戏设备
漏洞本身源于名为“OMEN命令中心”中的一个组件,该组件预装载惠普 OMEN 品牌的笔记本电脑和台式电脑中,用于控制和优化设备 GPU、风扇速
度、CPU 超频、内存等设置。
惠普的OMEN命令中心包含一个驱动存在漏洞,可以被攻击者利用,在不需要管理员权限的情况下实现权限升级到内核模式。
HpPortIox64.sys
WinRing0.sys
13. 驱动程序简介 – 驱动安全大事件
04
01
02
HP OMEN驱动程序
软件存在漏洞,可以
进行提权利用
勒索软件
利用Windows驱动程
序漏洞关闭杀软
不安全的驱动程序,可能会被利用作为攻击整个系统的跳板。
03
Meltdown&Spectr
e,CPU暴露内存泄
漏风险
NVIDIA Windows
GPU显示驱动中漏洞,
导致信息泄露或权限提
升
14. 常见安全漏洞和案例分析
15. 用户层R3与内核层R0通信
通过DeviceIoControl函数来使应用程序与驱动程序通信:
R3
打开符号链接
IRP请求
驱动程序和应用程序自定义一种IO控制码,然后应用程序调用
DeviceIoControl函数,DeviceIoControl函数会产生此控制码的
IRP请求,系统就调用相应的处理该IRP请求的分发函数,在分发
函数中判断,如果是自定义的控制码就进行相应的处理。
传入控制码
R0
创建符号链接
创建驱动设备
创建驱动对象
执行分发函数
16. 内核漏洞案例分析
缓冲区溢出 --- 漏洞说明
程序向栈中某个变量中写入的字节数超过了这个
变量本身所申请的字节数,因而导致与其相邻的
栈中的变量的值被改变。
示例:RtlCopyMemory函数没有对
KernelBuffer大小进行验证,直接将size大小的
userbuffer传入缓冲区,没有进行大小的限制
17. 内核漏洞案例分析
缓冲区溢出 --- 利用方式
利用驱动与R3通信,能够直接读取R3地址,改写缓冲区地址,
直接将程序跳转到预先设定的目标程序代码上来执行。
18. 内核漏洞案例分析
空指针漏洞 --- 漏洞说明
空指针Null Pointer指向0地址空间,如果不加判断就对其进
行引用,会造成不可预知的后果。攻击者可以在0地址写入
shellcode,调用空指针来执行。
示例:清空指针( NullPointerDereference = NULL;)之
后,未对NullPointerDereference进行检查判断,直接调用
callback。
19. 内核漏洞案例分析
空指针漏洞 --- 利用方式
利用NtAllocateVirtualMemory函数,在0页申请内存,申请
成功后,将攻击代码地址放入
20. 常见内核驱动漏洞
不正确的函数调用
函数调用最为常见的是不正确的 ZwXXX 函数调用:
不能将任何用户态内存通过调用 ZwXXX 函数传递给内核。用户态内存未经过校验,传递给 ZwXXX 会让系统忽略内存检查,即使进行了校验,传递这
样的内存给系统也容易引发崩溃。即便在外部有异常捕获,也可能造成内核内存泄露、对象泄露、甚至权限提升等严重问题 。
21. 常见内核驱动漏洞
不正确的内存操作
譬如:没有在 try_except 内完成对于用户态内存的任何操作
ProbeForRead 只检查在 probe 的那一刻, buff 地址是在用户态地址范围
内。在try,except块之外进行读写,这个时候并不能保证buff还是用户态的地
址。
22. 常见内核驱动漏洞
随意对外暴露接口
小心对注册表、 文件、 内存、 进程线程等操作的功能性接口暴露,如果不能完全杜绝存在被恶意利用的可能,尽量限制对驱动的调用。
打开设备时检查是否保护进程(DisptchCreate)
尽量禁止非 Admin 用户打开设备
如果是服务进程或常驻进程使用的驱动设备,可以在 IoCreateDevice 时对 Exclusive (排他性,只允许一个进程打开)参数传 TRUE,来杜绝其他
进程打开设备
在打开的分发函数中获取调用者的pid,校验签名,禁止一切非受信进程的调用
23. 驱动安全测试方法分享
24. 驱动安全测试方法分享
使用安全清单(Security Checklist)是一种高效的方式,以确保驱动程序开发过程中注意到所有重要的安全方面
01 02 03 04
设计阶段 开发阶段 测试阶段 发布阶段
权限设计最小化
安全更新
限制暴露的攻击面
使用安全的函数 代码审计
防止缓冲区溢出 模糊测试
防止未初始化内存访问 权限测试
安全的I/O操作 接口安全测试
理解测试的功能和设计 分析风险和攻击面
制定测试计划 设计测试用例
测试左移
签名检查
响应策略
监控机制
静态测试 WHQL签名测试
动态测试 金丝雀发布
测试用例覆盖 安全漏洞响应计划
测试右移
25. 驱动安全测试方法分享
驱动安全测试用例设计
26. 驱动安全测试方法分享
驱动安全静态测试
静态分析指的是在源代码的编译期间进行分析,通过词法分析、语法分析、控制流、数据流分析等技术对程序代码进行扫描,验证代码是否满足规范性、安全性、可
靠性、可维护性等指标的一种代码分析技术。
WDK中提供的两种常用技术
PREfast for Drivers: 在每个进程中深度分析可能的违例
Static Driver Verifier: 延执行路径,跨进程间的边界
warning 8103: Leaking the resource stored in
'SpinLock:MyLock‘.
27. 驱动安全测试方法分享
驱动安全静态测试
PREfast 无法发现所有的错误:
Null指针, 未初始化的变量 (延非常规路径)
本地的泄漏 (内存, 资源)
不匹配的参数
未检查返回值
格式/列表不匹配
一些IRQL的误用
容易忽略的各种特殊情况(例如,取消IRQL)
回调/函数指针的恰当使用
PREFAST检测的缺项不仅仅是安全缺陷,但是安全缺陷类型是其检测的
最为重要的部分
28. 驱动安全测试方法分享
驱动安全动态测试 -verifier
29. 驱动安全测试方法分享
驱动安全动态测试 -verifier
驱动校验器可以帮助驱动程序员更容易的发现和定位到错误,建议在所有驱动测试中使用。但是校验器使用不当、测试人员对校验器功能不了解,当做黑盒工具来
使用,可能导致拖延项目进度,给定位问题带来困难。
校验器使用规范
常用的校验项
1,校验器只能在干净的测试环境中使用,不要和任 特殊池
何带非正规驱动的软件共存使用,例如网络游戏、杀 死锁检测
毒软件、安全软件(冰刃等) 强制IRQL检查
I/O验证
2,如果要进行兼容性测试,必须删除原有的Driver 池跟踪
VERIFER设置。删 除 方 法 是 打 开 校 验 工 具 , DMA检查
选 择 “ Delete existing settings”(vista下是“删 安全性检查
除现有设置”),点击完成后重新启动系统 杂项检查
30. 驱动安全测试方法分享
驱动安全动态测试 -fuzz
HOOK FUZZ
`NtFuzz` 是一个专门用于对 Windows NT 内核
API进行模糊测试的工具。通过生成随机或半随机的
输入数据来调用内核API。在驱动程序和操作系统内
核层面,这种测试方法对于提高代码的稳健性和安全
性非常有效。
31. 驱动安全测试方法分享
驱动安全动态测试 -fuzz
IOCTL FUZZ
通过hook ntdeviceiocontrolfile,捕获系统中所
有的ioctl请求,当用户层与内核层发生通信的时
候,就可以监控到这个操作并且可以对其中的输入输
出数据进行修改,再将修改以后的数据传递给原始的
NtDeviceIoControlFile 函数。如果将修改以后的
数据发送给 NtDeviceIoControlFile 函数以后,发
生了内核崩溃或蓝屏,往往预示着该驱动程序可能存
在内核漏洞。
32. 驱动安全测试方法分享
驱动安全WHQL签名测试
WHQL测试
WHQL驱动测试错误排查步骤
检查测试环境是否符合要求
分析测试日志
WHQL驱动测试错误原因所占比例
跟踪解析测试工具的执行结果
微软签名
15%
15%
WHQL驱动测试错误解决
70%
对稳定的测试环境备份系统镜像
对需要填写测试配置的测试项分
系统正常加载
类保存
对重复操作用脚本替代
测试环境布置问题
微软测试工具问题
驱动自身问题
33. THANK YOU