驱动程序编写者和架构师应使威胁建模成为任何驱动程序设计过程不可或缺的一部分。 本主题提供为 Windows 驱动程序创建威胁模型的指导。
安全性应该是任何驱动程序的基本设计点。 任何成功的产品都会成为众矢之的。 如果你正在为 Windows 编写驱动程序,则必须假设有时(某处)有人会尝试使用你的驱动程序来损害系统安全性。
设计安全驱动程序涉及:
- 确定驱动程序可能容易受到攻击的点。
- 分析可在每个此类点进行的攻击类型。
- 确保以阻止此类攻击的方式设计驱动程序。
威胁建模是对这些重要设计任务的结构化方法。 威胁模型是对资产的威胁进行分类和分析的方法。 从驱动程序编写器的角度来看,资产是计算机或网络上的硬件、软件和数据。
威胁模型回答以下问题:
- 哪些资产需要保护?
- 资产易受到哪些威胁?
- 每个威胁有多重要或可能?
- 如何缓解威胁?
威胁建模是软件设计的重要组成部分,因为它可确保将安全性内置到产品中,而不是作为事后解决。 良好的威胁模型有助于在设计过程中查找和防止漏洞,从而消除以后可能需要的代价高昂的修补措施,以及可能对组织声誉造成损害。
本部分将威胁建模原则应用于驱动程序设计,并提供驱动程序可能容易受到威胁的示例。 有关软件设计威胁建模的更完整说明,请参阅这些资源。
Microsoft SDL 网站:
Microsoft SDL 的简化实现:
此博客文章介绍如何下载 安全开发生命周期的免费副本:SDL,作者:Michael Howard 和 Steve Lipner:
为驱动程序创建威胁模型
创建威胁模型需要全面了解驱动程序的设计、可能暴露驱动程序的威胁类型以及利用特定威胁的安全攻击的后果。 为驱动程序创建威胁模型后,可以确定如何缓解潜在威胁。
威胁建模在驱动程序设计期间以有条理、结构化的方式执行时,而不是在编码过程中随意执行时,最有效。 结构化方法会增加在设计中发现漏洞的可能性,从而有助于确保模型全面。
组织威胁建模工作的一种方法是执行以下步骤:
- 创建一个结构化关系图,其中显示了通过驱动程序的数据流。 包括驱动程序执行的所有可能任务以及驱动程序的所有输入和输出的源和目标。 正式数据流关系图或类似的结构化关系图可帮助你通过驱动程序分析数据的路径,并确定驱动程序的外部接口、边界和交互。
- 根据数据流关系图分析潜在的安全威胁。
- 评估在上一步中识别的威胁,并确定如何缓解威胁。
创建数据流关系图
数据流图以概念形式展示驱动程序与其交互的外部实体之间的数据流,通常包括操作系统、用户进程和设备。 正式数据流关系图使用以下符号:
下图显示了假设内核模式 Windows 驱动程序模型 (WDM) 驱动程序的示例数据流关系图。 无论特定类型的驱动程序的体系结构如何,概念模型都是相同的:显示所有数据路径并标识进入或退出驱动程序的每个数据源。
注意 上图显示数据直接在用户进程和驱动程序之间流动,并省略任何中间驱动程序。 但是,实际上,所有请求都通过 I/O 管理器,在到达特定驱动程序之前,可能会遍历一个或多个更高级别的驱动程序。 该图省略了这些中间步骤,以强调原始数据源和提供数据的线程上下文的重要性。 内核模式驱动程序必须验证源自用户模式的数据。
信息会进入驱动程序,这可能是因为操作系统的请求、用户进程的请求,或者设备的请求(通常是中断)。
上图中的驱动程序从操作系统接收几种类型请求的数据。
- 通过调用 DriverEntry、 DriverUnload 和 AddDevice 例程为驱动程序及其设备执行管理任务的请求
- 即插即用请求(IRP_MJ_PNP)
- 电源管理请求(IRP_MJ_POWER)
- 内部设备 I/O 控制请求(IRP_MJ_INTERNAL_DEVICE_CONTROL)
为了响应这些请求,数据从驱动程序流回到操作系统,作为状态信息。 图中的驱动程序从用户进程接收以下类型的请求中的数据:
- 创建、读取和写入请求(IRP_MJ_CREATE、IRP_MJ_READ或IRP_MJ_WRITE)
- 公共设备 I/O 控制请求(IRP_MJ_DEVICE_ CONTROL)
为了响应这些请求,输出数据和状态信息从驱动程序流回到用户进程。
最后,驱动程序由于设备 I/O操作或用户操作(如打开 CD 驱动器上的托盘)而从设备接收数据,从而更改设备状态。 同样,驱动程序中的数据在 I/O作期间流向设备,并更改设备状态。
上图显示了驱动数据流的广泛概念级别。 每个圆表示一个相对较大的任务,并且缺少详细信息。 在某些情况下,一级关系图(例如示例)足以理解数据源和路径。 如果驱动程序处理来自不同源的许多不同类型的 I/O 请求,则可能需要创建一个或多个显示更多详细信息的其他关系图。 例如,标记为“处理 I/O 请求”的圆圈可能展开为单独的关系图,如下图所示。
第二个关系图显示了第一个关系图中每种 I/O 请求的不同任务。 (为简单起见,已省略设备的数据路径。
根据设备类型,关系图中显示的外部实体和输入和输出类型可能会有所不同。 例如,Windows 为许多常见设备类型提供类驱动程序。 系统提供的类驱动程序适用于供应商提供的微型驱动程序,该驱动程序通常是包含一组回调例程的动态链接库(DLL)。 用户 I/O 请求将定向到类驱动程序,然后调用微型驱动程序中的例程来执行特定任务。 微型驱动程序通常不会接收作为输入的整个 I/O 请求数据包;相反,每个回调例程只接收其特定任务所需的数据。
创建数据流关系图时,请记住驱动程序请求的各种源。 在用户计算机上运行的任何代码都可以生成对驱动程序的 I/O 请求,从Microsoft Office 等已知应用程序到可能可疑来源的免费软件、共享软件和 Web 下载。 根据你的特定设备,你可能还需要考虑公司随附的媒体编解码器或第三方筛选器来支持其设备。 可能的数据源包括:
- IRP_MJ_XXX驱动程序处理的请求
- 驱动程序定义或处理的 IOCTL
- 驱动程序调用的 API
- 回调例程
- 驱动程序公开的任何其他接口
- 驱动程序读取或写入的文件,包括安装过程中使用的文件
- 驱动程序读取或写入的注册表项
- 驱动程序使用的配置属性页和用户提供的任何其他信息
模型还应涵盖驱动程序安装和更新过程。 包括驱动程序安装过程中读取或写入的所有文件、目录和注册表项。 另请考虑设备安装程序、共同安装程序和属性页中公开的接口。
驱动程序与外部实体交换数据的任何时刻都可能容易受到攻击。
分析潜在威胁
确定驱动程序可能易受攻击的点后,可以确定每个点可能发生哪种类型的威胁。 请考虑以下类型的问题:
- 有哪些安全机制可用于保护每个资源?
- 所有转换和接口是否都得到适当的保护?
- 不当使用某个功能会无意中损害安全性吗?
- 恶意使用功能会泄露安全性吗?
- 默认设置是否提供足够的安全性?
威胁分类的 STRIDE 方法
首字母缩略词 STRIDE 描述了软件的六类威胁。 此首字母缩略词派生自:
- 欺骗
- Tampering
- 否认
- 信息披露
- 拒绝服务
- 权限提升
使用 STRIDE 作为指南,可以就可能针对驱动程序的攻击类型提出详细问题。 目标是确定在驱动程序的每个易受攻击点可能的攻击类型,然后为每个可能的攻击创建方案。
欺骗 是使用其他人的凭据来获取对其他不可访问资产的访问权限。 进程通过传递伪造或被盗凭据来发动欺骗攻击。
篡改 是更改数据以发动攻击。 例如,如果所需的驱动程序文件不受驱动程序签名和访问控制列表(ACL)的充分保护,则驱动程序可能会容易被篡改。 在这种情况下,恶意用户可能会更改文件,从而破坏系统安全性。
当用户否认执行了一项操作,而该操作的对象无法证明其发生,即为否认。 如果驱动程序没有记录可能危及安全性的动作,它可能容易受到否认性威胁的影响。 例如,如果视频设备的驱动程序没有记录更改设备特征的请求(例如焦点、扫描区域、图像捕获频率、捕获图像的目标位置等),则视频设备的驱动程序可能会容易受到否认。 生成的映像可能已损坏,但系统管理员无法确定哪个用户导致了问题。
信息泄露 威胁与名称完全一样:向无权查看信息的用户披露信息。 将信息传递给用户缓冲区或从用户缓冲区传递信息的任何驱动程序都容易受到信息泄露威胁的影响。 为了避免信息泄露威胁,驱动程序必须在写入数据之前验证每个用户缓冲区的长度并零初始化缓冲区。
拒绝服务 攻击威胁有效用户访问资源的能力。 资源可以是磁盘空间、网络连接或物理设备。 性能降低到不可接受的级别的攻击也被视为拒绝服务攻击。 如果资源消耗阻碍其他有效用户执行其任务的能力,则允许用户进程不必要地垄断系统资源的驱动程序可能会容易受到拒绝服务攻击。
例如,驱动程序可能会在 IRQL = PASSIVE_LEVEL 执行时使用信号灯来保护数据结构。 但是,驱动程序必须在 KeEnterCriticalRegion/KeLeaveCriticalRegion 对中获取和释放信号量,这一对操作会禁用并重新启用异步过程调用(APC)。 如果驱动程序无法使用这些例程,APC可能会导致操作系统挂起持有信号量的线程。 因此,其他进程(包括管理员创建的进程)将无法访问结构。
如果非特权用户获得特权状态,可能会发生 特权提升 攻击。 将用户模式句柄传递给 ZwXxx 例程的内核模式驱动程序容易受到特权提升攻击,因为 ZwXxx 例程会绕过安全检查。 内核模式驱动程序必须验证他们从用户模式调用方接收的每个句柄。
如果内核模式驱动程序依赖于 IRP 标头中的 RequestorMode 值来确定 I/O 请求是来自内核模式还是用户模式调用方,则也会发生特权提升攻击。 在从网络或服务器服务(SRVSVC)到达的 IRP 中, RequestorMode 的值是 KernelMode,而不考虑请求的来源。 若要避免此类攻击,驱动程序必须对此类请求执行访问控制检查,而不只是使用 RequestorMode 的值。
驱动程序分析技术
组织分析的一种简单方法是列出易受攻击的区域以及每种威胁的潜在威胁和一个或多个方案。
若要执行彻底分析,必须探索驱动程序中每个潜在易受攻击点的威胁的可能性。 在每个易受攻击点,确定可能存在的每种威胁类别(欺骗、篡改、否认、信息泄露、拒绝服务和特权提升)。 然后为每个合理的威胁创建一个或多个攻击方案。
例如,请考虑IRP_MJ_DEVICE_CONTROL请求的数据流,如上图所示。 下表显示了驱动程序在处理此类请求时可能会遇到的两种类型的威胁:
易受攻击点 | 潜在威胁 (STRIDE) | 情景 |
---|---|---|
IRP_MJ_DEVICE_CONTROL请求 | 拒绝服务 权限提升 |
用户进程会发出导致设备失败的 IOCTL 序列。 用户进程发出允许FILE_ANY_ACCESS的 IOCTL。 |
威胁树和大纲在建模此类复杂方案时非常有用。
威胁树是显示威胁或漏洞层次结构的关系图;从本质上讲,威胁树模仿恶意用户装载攻击的步骤。 攻击的最终目标是树顶。 每个从属级别显示执行攻击所需的步骤。 下图是上述示例中拒绝服务方案的简单威胁树。
威胁树显示装载特定攻击所需的步骤和步骤之间的关系。 大纲是威胁树的替代方案。
大纲只是按分层顺序列出攻击特定威胁的步骤。 例如:
1.0 导致设备停止响应。
1.1 按故障序列发出 IOCTLS。
1.1.1 确定导致设备失败的序列。
1.1.2 获取高权限以发出内部 IOCTL。
任一技术都可以帮助你了解哪些威胁最危险,以及设计中的哪些漏洞最为关键。
快速路径威胁建模
如果资源有限,而不是创建完整的威胁模型关系图,则可以创建摘要大纲来帮助评估驱动程序的安全风险。 例如,下面的文本描述了前一个示例中介绍的示例驱动程序中部分表面区域。
驱动程序从操作系统接收多种类型请求的数据:
- 通过调用 DriverEntry、 DriverUnload 和 AddDevice 例程为驱动程序及其设备执行管理任务的请求
- 即插即用请求(IRP_MJ_PNP)
- 电源管理请求(IRP_MJ_POWER)
- 内部设备 I/O 控制请求(IRP_MJ_INTERNAL_DEVICE_CONTROL)
为了响应这些请求,数据作为状态信息从驱动程序流回至操作系统。 驱动程序在以下类型的请求中从用户进程接收数据:
- 创建、读取和写入请求(IRP_MJ_CREATE、IRP_MJ_READ或IRP_MJ_WRITE)
- 公共设备的 I/O 控制请求(IRP_MJ_DEVICE_CONTROL)
为了响应这些请求,输出数据和状态信息从驱动程序流回到用户进程。
通过对数据流向驱动程序的基本理解,您可以检查每个输入和输出区域可能存在的威胁。
威胁评估的 DREAD 方法
确定驱动程序可能受到攻击的方式和位置是不够的。 然后,必须评估这些潜在威胁,确定其相对优先级,并制定缓解策略。
DREAD 是一个首字母缩略词,描述评估软件威胁的五个条件。 DREAD 代表:
- 损伤
- Reproducibility
- 可利用性
- 受影响的用户
- D可恢复性
若要确定对驱动程序的威胁的优先级,请在 DREAD 评估条件的所有 5 个标准中将每个威胁排名从 1 到 10,然后添加分数并除以 5(条件数)。 结果是每个威胁的数值分数介于 1 和 10 之间。 高分代表存在严重威胁。
损坏。 评估安全攻击造成的损害显然是威胁建模的关键部分。 损坏可能包括数据丢失、硬件或媒体故障、不合格性能,或者适用于设备及其作环境的任何类似度量值。
可重现性 是衡量指定攻击类型成功的频率。 容易被重现的威胁更容易被利用,而不是那些很少发生或不可预测的漏洞。 例如,默认安装的功能或在每个潜在代码路径中使用的功能所面临的威胁高度可重现。
利用性 评估装载攻击所需的工作和专业知识。 对于相对缺乏经验的大学生而言,一种可以被攻击的威胁是易于被利用的。 需要高技能人员并且成本高昂的攻击更难以被利用。
在评估可利用性时,还要考虑潜在攻击者的数量。 任何远程匿名用户都可以利用的威胁比需要现场高度授权的用户更受攻击。
受影响的用户。 受攻击影响的用户数是评估威胁的另一个重要因素。 影响最多一两个用户的攻击在这个指标上的严重程度相对较低。 相反,导致网络服务器崩溃的拒绝服务攻击可能会影响数千个用户,因此会速率更高。
可发现性 是威胁被利用的可能性。 可发现性难以准确估计。 最安全的方法是假设任何漏洞最终都会被利用,因此,依靠其他措施来建立威胁的相对排名。
示例:使用 DREAD 评估威胁
继续上述示例,下表显示了设计人员如何评估假设的拒绝服务攻击:
DREAD 标准 | 得分 | 注释 |
---|---|---|
损伤 | 8 | 暂时中断工作,但不会造成永久损坏或数据丢失。 |
可再现性 | 10 | 使设备每次都会出现故障。 |
可利用性 | 7 | 需要集中精力来确定命令序列。 |
受影响的用户 | 10 | 影响市场上此设备的每个型号。 |
可发现性 | 10 | 假设所有潜在的威胁都会被发现。 |
总: | 9.0 | 缓解此问题是高优先级。 |
缓解威胁
驱动程序设计必须应对和化解模型公开的所有威胁。 但是,在某些情况下,缓解可能并不可行。 例如,假设攻击可能会影响极少数用户,并且不太可能导致数据丢失或系统可用性。 如果缓解此类威胁需要几个月的额外工作量,则可以合理选择花更多的时间来测试驱动程序。 不过,请记住,最终恶意用户可能会发现漏洞并装载攻击,然后驱动程序将需要修补程序来解决问题。
在更广泛的安全开发生命周期过程中包括威胁建模
请考虑在更广泛的安全开发生命周期中包含威胁建模过程 - SDL。
Microsoft SDL 流程提供了许多建议的软件开发过程,可对其进行修改以适应组织的任何大小,包括单个开发人员。 请考虑将 SDL 建议的组件添加到软件开发过程。
有关详细信息,请参阅 Microsoft安全开发生命周期 (SDL) – 过程指南。
培训和组织功能 - 进行软件开发安全培训,以扩大识别和修正软件漏洞的能力。
Microsoft使其四个核心 SDL 培训课程可供下载。 Microsoft安全开发生命周期核心培训课程
有关 SDL 培训的更多详细信息,请参阅此白皮书。 Microsoft SDL 的基本软件安全培训
要求和设计 - 构建受信任的软件的最佳机会是在新版本或新版本的初始规划阶段,因为开发团队可以识别关键对象并集成安全和隐私,从而最大程度地减少计划和计划的中断。
此阶段的关键输出是设置特定的安全目标。 例如,确保您的所有代码都应通过 Visual Studio 代码分析,并且“所有规则”没有任何警告。
实现 - 所有开发团队都应定义和发布已批准的工具及其关联的安全检查的列表,例如编译器/链接器选项和警告。
对于驱动程序开发人员来说,大部分有用的工作都是在此阶段完成的。 编写代码时,会检查可能存在的弱点。 代码分析和驱动程序验证程序等工具用于查找可强化的代码中的区域。
验证 - 验证 是软件功能完成并针对要求和设计阶段概述的安全目标进行测试的点。
其他工具(如 binscope 和模糊测试人员)可用于验证是否已达到安全设计目标,并且代码已准备好交付
发布和响应 - 在准备发布产品时,需要创建事件响应计划,用于描述应对新威胁的作,以及如何在驱动程序发货后为驱动程序提供服务。 提前完成这项工作意味着,如果在已交付的代码中发现了安全问题,你将能够更快地做出响应。
有关 SDL 过程的详细信息,请参阅以下附加资源:
这是 Microsoft SDL 的主要站点,并提供 SDL 的概述。 https://www.microsoft.com/sdl
此博客介绍如何下载由迈克尔·霍华德和史蒂夫·利普纳撰写的《安全开发生命周期:SDL》的免费副本。 https://blogs.msdn.microsoft.com/microsoft_press/2016/04/19/free-ebook-the-security-development-lifecycle/
此页面提供指向其他 SDL 出版物的链接。 https://www.microsoft.com/SDL/Resources/publications.aspx
行动号召
对于驱动程序开发人员:
- 使威胁建模成为驱动程序设计的一部分。
- 采取措施,有效缓解驱动程序代码中的威胁。
- 熟悉适用于驱动程序和设备类型的安全性和可靠性问题。 有关详细信息,请参阅 Windows 设备驱动程序工具包(WDK)的设备特定部分。
- 了解操作系统、I/O 管理器和任何更高级别驱动在用户请求到达您的驱动之前执行的检查以及它们未执行的检查。
- 使用 WDK 中的工具,例如驱动程序验证程序来测试和验证驱动程序。
- 查看已知威胁和软件漏洞的公共数据库。
有关其他驱动程序安全资源,请参阅 驱动程序安全清单。
软件安全资源
书籍
编写安全代码,第二版由迈克尔·霍华德和大卫·勒布兰克
24 软件安全的致命罪:编程缺陷和如何修复它们,第一版由迈克尔·霍华德、大卫·勒布兰克和约翰·维加
软件安全评估的艺术:识别和防止软件漏洞,由马克·道德、约翰·麦当劳和贾斯汀·舒赫
Microsoft硬件和驱动程序开发人员信息
Microsoft Windows 驱动程序开发工具包 (DDK)
请参阅 Kernel-Mode 驱动程序体系结构中的驱动程序编程技术
测试工具
请参阅测试中的 Windows 硬件实验室工具包,了解性能和兼容性
已知威胁和软件漏洞的公共数据库
若要扩展软件威胁的知识,请查看已知威胁和软件漏洞的可用公共数据库。
- 常见漏洞和暴露(CVE): https://cve.mitre.org/
- 常见弱点枚举: https://cwe.mitre.org/
- 常见攻击模式枚举和分类: https://capec.mitre.org/index.html
- NIST 维护一个站点,该站点描述如何对漏洞进行编目: https://samate.nist.gov/BF/