内核漏洞概述

内核漏洞的分类

运行在 Ring0 上的操作系统内核、设备驱动、第三方驱动能共享同一个虚拟地址空间,可以完全访问系统空间的所有内存,而不像用户态进程那样拥有独立私有的内存空间。由于内核程序的特殊性,内核程序漏洞类型也更加丰富。(书中收集了近年内公布的内核漏洞,并将相关的分析资料整理打包)

可以从漏洞的严重程度和漏洞的利用原理两个角度来对内核漏洞进行分类。漏洞的严重程度是指漏洞利用后所造成的危害;漏洞的利用原理是指漏洞利用过程中使用的原理和技术。

按照漏洞严重程度可分为以下 4 类:远程拒绝服务、本地拒绝服务、远程任意代码执行和本地权限提升。拒绝服务指能够利用来使得远程系统崩溃或资源耗尽的内核程序 bug 或缺陷。

按照漏洞利用原理可分为以下 4 类:拒绝服务、缓冲区溢出、内存篡改和设计缺陷。

内存篡改又可以分成以下 3 个子类:任意地址写任意数据、固定地址写任意数据、任意地址写固定数据。

内核漏洞的研究过程

漏洞重现环节,需要搭建测试环境,通常为虚拟机环境;另外需要注意有漏洞的内核文件或驱动文件的版本,如果版本不对,是不可能重现的;还要确认该漏洞暂时还未打补丁;最后,如果该漏洞公布有 POC 源码,还需要对 POC 源码进行编译。在漏洞重现环节中,如果最终重现失败,不能说明漏洞不存在,如果环境搭建的没有问题,那可以考虑是否 POC 源码有误,或者该漏洞还依赖于其他条件。因此,建议先进行漏洞分析环节,通过漏洞分析可以加深对漏洞的理解,这样边分析边重现,往往问题就迎刃而解了。从漏洞重现到漏洞分析,是一个"由表及里"的过程。

漏洞分析环节,是整个漏洞学习的核心环节,如果分析不清漏洞的前因后果,那么漏洞利用也无从入手。漏洞分析过程其实是一个"刨根究底"的过程,也可以说是"打破沙锅问到底"的过程,只不过是"问"自己而已。漏洞分析有很多方法,如果有源码的话,可以先对源码进行白盒分析;如果没有源码可以对内核或驱动 PE 文件反汇编分析;如果漏洞公布中有 POC 源码的话,还可以对 POC 源码进行分析(通过阅读 POC 源码和注释,可以很快地对该漏洞有一个准确的认识);如果该漏洞的补丁已经发布了,还可以在打补丁后,提取新版本的内核或驱动文件,通过对比进行分析;另外还可以通过给有漏洞的内核或驱动文件下断点进行调试分析;如果能触发有漏洞的内核或驱动蓝屏,还可以针对蓝屏后的 Memory Dump(完整转储、内核转储、小型内存转储)文件进行蓝屏分析。

漏洞利用环节,是在漏洞分析的基础上,编写出能够利用该漏洞实现特定目标的代码,并进行测试的过程。对于内核漏洞利用而言,主要有 5 种目标:特权提升、远程溢出、本地溢出、远程 DOS 和本地 DOS。在实际漏洞利用过程中,最终达到的目标不外乎这 5 种,但是漏洞利用的细节各有不同,"各显神通"。

漏洞总结环节,是在完成了漏洞重现、漏洞分析和漏洞利用过程后,回过头来审视造成该漏洞的根本原因,并提出修补方法的过程。如果把以上环节比喻为攻击,那么漏洞总结必须站在攻击与防御的对立面,才能有所体会和感悟,才能寻求到突破。通过漏洞总结,能够将学习过程中获取到的知识升华为一种经验和能力。

内核漏洞挖掘的过程实际上就是,通过工具挖掘或手工挖掘,达到触发漏洞的目标,可能是一个蓝屏,也可能是一个内核异常,然后对此进行详细分析和测试,最终编写漏洞 POC 的过程。

编写安全的驱动程序

站在开发者的角度,内核漏洞的原因大体可以归结为:未验证输入和输出未验证调用者代码逻辑错误系统设计存在安全缺陷等。在驱动开发的过程中,注意这些方面就可以大大提高驱动程序的安全性。

输入输出检查

输入输出检查是指对不可信的输入输出地址及数据长度进行合法性检查的过程。这种方法在 Windows 内核 API 中应用的十分广泛。

例如,在 NtReadFile 函数中,如果 PreviousMode 不是 KernelMode,即 NtReadFile 函数是从用户态被调用的,可以使用 ProbeForWrite 函数检测输入输出缓冲区是否可写,参见 ReactOS 中的代码如下:

 NTSTATUS NTAPI NtReadFile(IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL)
{
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
//省略部分代码......
/* Validate User-Mode Buffers */
if (PreviousMode != KernelMode)
{
_SEH2_TRY
{
/* Probe the status block */
ProbeForWriteIoStatusBlock(IoStatusBlock);
/* Probe the read buffer */
ProbeForWrite(Buffer, Length, );
//省略部分代码......

类似地,在 NtWriteFile 函数中当发现 PreviousMode 不是 KernelMode 时,即从用户态调用过来的,可以使用 ProbeForRead 函数进行检测。

此外,在 IoControl 中如果 IoControlCode 指定的 Method 为 METHOD_NEITHER 时,也应当对输入和输出地址使用 ProbeForRead 和 ProbeForWrite 函数进行检验。

验证驱动的调用者

有很多驱动程序加载后,会在驱动程序入口函数 DriverEntry 中创建驱动设备,并创建符号链接,同时还会指定派遣例程。这样一来,所有用户态程序都可以通过 DeviceIoControl 函数,调用该驱动的派遣例程。即存在 Ring3 恶意调用 Ring0 驱动派遣例程的问题,Ring0 程序应该对这种调用进行验证和过滤。

作为不够健壮的第三方驱动程序,更容易因为这种恶意调用被干扰,发生逻辑错误,甚至触发可能存在的内核漏洞。因此需要考虑驱动程序的通信对象和调用来源,在派遣例程中对此进行必要的安全验证和过滤。

验证和过滤的方法有很多,例如检查调用者进程的 PEPROCESS,进程文件的 MD5,等等。除此之外,还可以考虑用户态程序和驱动程序的通信加密,对于解密失败或非法通信数据的情况可以不予处理。

白名单机制的挑战

目前有很多安全软件,为了防止病毒木马进入 Ring0 而提高权限,这样已经防止加载驱动了。然而为了避免影响第三方驱动的正常运行,安全软件大多开设了白名单机制,在白名单中的驱动加载时是不会被拦截的。但是如果白名单中的驱动存在内核漏洞呢?

虽然病毒木马很难加载他们自己的驱动,但是只要白名单中的驱动存在漏洞,利用漏洞进行提权等操作,同样可以实现需要的功能,甚至完全瓦解软件的防御体系,这便是 "白名单机制的挑战"。

要解决这个问题,需要对白名单设立"准入制度"。只有通过了安全评估、检测、分析的驱动才能被加入白名单列表中。另一方面,我们还需要对白名单中的驱动进行定期审计,一旦发现该驱动的漏洞或外部公布了该驱动的漏洞,需要在第一时间通知用户,提供补丁升级服务。

OD: Kernel Vulnerabilities的更多相关文章

  1. OD: Kernel Vulnerabilities Analyze

    内核漏洞大多出没于 ring3 到 ring0 的交互中.从 ring3 进入 ring0 的通道,以及操作系统提供的 API 都有可能存在漏洞.例如:驱动程序中 IoControl 的处理函数,SS ...

  2. OD: Kernel Exploit - 2 Programming

    本节接前方,对 exploitme.sys 进行利用. exploitme.sys 存在任意地址写任意内容的内核漏洞,现在采用执行 Ring0 Shellcode 的方式进行利用. 获取 HalDis ...

  3. OD: Kernel Exploit - 1

    第 22 章,内核漏洞利用技术 首先编写具有漏洞的驱动 exploitme.sys,再展开内核漏洞利用思路和方法: /***************************************** ...

  4. OD: ActiveX Vulnerabilities

    通过一个精心构造的页面 exploit 第三方软件中的 ActiveX 已经成为一种惯用攻击手段,众多知名软件公司都曾被发现其注册的 ActiveX 中存在严重的缓冲区溢出漏洞,一个被广泛使用的第三方 ...

  5. OD: File Vulnerabilities & Protocols & Fuzz

    IE.Office 等软件有个共同点,即用文件作为程序的主要输入,但攻击者往往会挑战程序员的假定和假设. 文件格式 Fuzz 就是利用畸形文件测试软件的稳健性,其流程一般包括: * 以一个正常文件作为 ...

  6. Windows Kernel Security Training Courses

    http://www.codemachine.com/courses.html#kerdbg Windows Kernel Internals for Security Researchers Thi ...

  7. iOS安全相关学习资料

    https://github.com/zhengmin1989/iOS_ICE_AND_FIRE  (冰与火代码) http://weibo.com/zhengmin1989?is_hot=1 (蒸米 ...

  8. Topics

    Topics Introduction (starting with old devices) How to handle a new Firmware How to set up your Mac ...

  9. Android privilege escalation to mediaserver from zero permissions (CVE-2014-7920 + CVE-2014-7921)

    墙外通道:http://bits-please.blogspot.com/2016/01/android-privilege-escalation-to.html In this blog post ...

随机推荐

  1. LCD驱动学习笔记

    通过这几天的学习发现驱动的框架感觉都差不多,一般分为以下几个步骤: 分配一个结构体 struct x *x = amlloc(); 设置结构体的参数 硬件寄存器 file_operations 注册 ...

  2. Mac下搭建php开发环境

    Mac OS X 内置了Apache 和 PHP,这样使用起来非常方便.本文以Mac OS X 10.6.3为例.主要内容包括: 启动Apache 运行PHP 安装MySQL 使用phpMyAdmin ...

  3. 屏蔽手势UIGestureRecognizer 先后响应

    在iOS5一下对于手势的识别能力并不强,比如iOS6上面按钮的一个tap事件,最先接收的是uiview,并相应,而不是最上面的button,这时候就需要判断手势所在的位置和手势所在的控制器了 如下例子 ...

  4. GO:格式化代码

    http://www.ituring.com.cn/article/39380 Go 开发团队不想要 Go 语言像许多其它语言那样总是在为代码风格而引发无休止的争论,浪费大量宝贵的开发时间,因此他们制 ...

  5. EasyPR--开发详解

    我正在做一个开源的中文车牌识别系统,Git地址为:https://github.com/liuruoze/EasyPR. 我给它取的名字为EasyPR,也就是Easy to do Plate Reco ...

  6. OrCAD PSpice仿真库模型

    说明:本介绍包含了\capture\library\pspice和capture\library\pspice\advanls目录下所有库,但由于作者水平有限,介绍得也比较简单,有些说明可能不一定对. ...

  7. LA 3998 Prime k-tuple

    题意:如果K个相邻素数p1,p2,p3.....pk满足pk-p1=s,称这些素数组成一个距离为s的素数K元组,输入a,b,k,s,输出区间[a,b]内距离为s的素数k元组的个数. 思路:先打到500 ...

  8. 蓝牙4.0BLE cc2540 usb-dongle的 SmartRF Packet Sniffer 抓取数据方法

    蓝牙4.0的开发, 现在真热火的很, 但是很多朋友买了我们出品的cc2540 usb-dongle后, 都反馈说不知道如何抓包, 并且, 即使很多朋友到TI官网论坛去找信息,不少朋友依然是无功而返,实 ...

  9. Delphi下的RTTI函数大全

    http://ljz9425.blog.163.com/blog/static/369148572008111635253858/ Delphi下的RTTI(下) 2008-12-16 15:52:5 ...

  10. Android Wear开发 - 数据通讯 - 第二节 : 数据的发送与接收

    本节由介绍3种数据的发送接收:1.Data Items : 比特类型数据,限制100KB以内2.Assets : 资源类型数据,大小无上限3.Message : 发送消息,触发指令 http://de ...