内核漏洞概述

内核漏洞的分类

运行在 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. 老oj2146 && Pku2135 Farm Tour

    Description When FJ's friends visit him on the farm, he likes to show them around. His farm comprise ...

  2. All in All

    Crawling in process... Crawling failed Description You have devised a new encryption technique which ...

  3. android 随手记 自定义广播通知栏

    自定义通知栏图标?不是很简单么.自定义布局都不在话下! 是的,有xml布局文件当然一切都很简单,如果不给你布局文件用呢? 听我慢慢道来! 首先怎么创建一个通知呢? 1.new 一个 Notificat ...

  4. 【转】Android:Layout_weight的深刻理解

    原文网址:http://mobile.51cto.com/abased-375428.htm 本文详细介绍了Android布局中Layout_weight的属性,它是用来分配属于空间的一个属性,你可以 ...

  5. SQL中ISNULL的使用

    在敲写相关sql语句时,我们经常会遇到一些空的字符串或者是字段,这就给我们对数据库造成一定的麻烦,系统经常会提示“某值null不能转换”“插入的值不能为空”等等诸如此类的提示,isnull函数会帮助你 ...

  6. ltp工具使用配置

    ltp是一个比较全的自然语言处理工具,可以用它进行分词.词性标注.语法分析等任务. ---- 准备 下载 下载ltp和ltp4j,在cmake官网下载并安装相应版本的cmake,并且下载ant. 构建 ...

  7. #345 div2 D. Image Preview

    Vasya's telephone contains n photos. Photo number 1 is currently opened on the phone. It is allowed ...

  8. C++ static(施工中)

    static 变量 头文件中的static会在引用该头文件的cpp中分别生成副本 //H.h #ifndef _H_H_ #define _H_H_ ; #endif //Ex_2.c #includ ...

  9. POI使用详解

    Apache POI使用详解 1.POI结构与常用类 (1)POI介绍 Apache POI是Apache软件基金会的开源项目,POI提供API给Java程序对Microsoft Office格式档案 ...

  10. 想挑战AlphaGO吗?先和PostgreSQL玩一玩?? PostgreSQL与人工智能(AI)

    1月4日晚,随着古力认输,Master对人类顶尖高手的战绩停留在60胜0负1和,而令人尴尬的是这唯一一场和棋还是因为棋手掉线系统自动判和,并不是棋盘上的局势真的势均力敌了.包括聂卫平.柯洁.朴廷桓.井 ...