开发技术讲究封装与模块化,安全技术强调底层安全性。安全技术需要打开封装、追根溯源!
《0day 安全:软件漏洞分析技术(第2版)》 第21章 探索 Ring0 笔记
Intel x86 系列处理器使用"环"的概念来实施访问控制,共有 4 个权限级别,由高到低分别为 Ring0、Ring1、Ring2、Ring3,其中 Ring0 权限最高,Ring3 权限最低。Windows(从 NT 开始)和 Linux 等多数操作系统在 Intel x86 处理器上只使用了 Ring0 和 Ring3,其中内核态对应着 Ring0,用户态对应着 Ring3。两个特权级足以实现操作系统的访问控制,况且之前支持的有些硬件体系结构(比如 Compaq Alpha 和 Silicon Graphics MIPS)只实现了两个特权级。本篇所讨论的内核程序漏洞特指 Ring0 程序中的能被利用的 bug 或缺陷。
一般地,操作系统的内核程序、驱动程序等都是在 Ring0 级别上运行的。此外,很多安全软件、游戏软件、工具软件等第三方驱动程序,也会通过系统服务的方式在 Ring0级别上运行。越来越多的病毒、木马、后门、恶意软件也有自己的驱动程序,想方设法的进入 Ring0,以求提高自身的运行权限,与安全软件进行对抗。
时至今日,Ring0 上运行的程序已经不再是单纯的系统内核,内核漏洞也不再是操作系统专属的问题,而是很多安全软件、游戏软件、工具软件等软件厂商共同需要面对的问题。
随着操作系统和安全软件的日益完善,在普通溢出漏洞难以奏效的情况下,容易被人忽略的内核漏洞往往可以作为突破安全防线的切入点。如果病毒木马加载了驱动或进入了 Ring0,是否还能够实施有效的防御呢?这是一个很有趣的问题,因为对抗的双方都处在系统最高权限,我们称之为"内核 PK",也许这种 PK 能成为今后的一个研究热点。
研究内核漏洞,需要首先掌握一些内核基础知识,例如内核驱动程序的开发、编译和运行,内核中重要的数据结构等,后面几节将对这些内容做简单的介绍。
驱动开发 helloworld
1 /******************************************************************** 2 created: 2010/12/06 3 filename: D:\0day\HelloWorld\helloworld.c 4 author: shineast 5 purpose: Hello world driver demo 6 *********************************************************************/ 7 #include <ntddk.h> 8 #define DEVICE_NAME L"\\Device\\HelloWorld" 9 #define DEVICE_LINK L"\\DosDevices\\HelloWorld" 10 11 PDEVICE_OBJECT g_DeviceObject; 12 13 VOID DriverUnload( IN PDRIVER_OBJECT driverObject ) 14 { 15 KdPrint(("DriverUnload: 88!\n")); 16 } 17 /********************************************************************** 18 驱动派遣例程函数 19 输入:驱动对象的指针,Irp指针 20 输出:NTSTATUS类型的结果 21 **********************************************************************/ 22 NTSTATUS DrvDispatch(IN PDEVICE_OBJECT driverObject,IN PIRP pIrp) 23 { 24 KdPrint(("Enter DrvDispatch\n")); //设置IRP的完成状态 25 pIrp->IoStatus.Status=STATUS_SUCCESS; //设置IRP的操作字节数 26 pIrp->IoStatus.Information=0; //完成IRP的处理 27 IoCompleteRequest(pIrp,IO_NO_INCREMENT); 28 return STATUS_SUCCESS; 29 } 30 31 NTSTATUS DriverEntry( IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath ) 32 { 33 NTSTATUS ntStatus; 34 UNICODE_STRING devName; 35 UNICODE_STRING symLinkName; 36 int i=0; 37 //打印一句调试信息 38 KdPrint(("DriverEntry: Hello world driver demo!\n")); 39 //设置该驱动对象的卸载函数 40 driverObject->DriverUnload = DriverUnload; 41 //创建设备 42 RtlInitUnicodeString(&devName,DEVICE_NAME); 43 ntStatus = IoCreateDevice( driverObject, 0, &devName, FILE_DEVICE_UNKNOWN, 0, TRUE, &g_DeviceObject ); 44 if (!NT_SUCCESS(ntStatus)) 45 { 46 return ntStatus; 47 } 48 //创建符号链接 49 RtlInitUnicodeString(&symLinkName,DEVICE_LINK); 50 ntStatus = IoCreateSymbolicLink( &symLinkName,&devName ); 51 if (!NT_SUCCESS(ntStatus)) 52 { 53 IoDeleteDevice( g_DeviceObject ); 54 return ntStatus; 55 } 56 //设置该驱动对象的派遣例程函数 57 for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) 58 { 59 driverObject->MajorFunction[i] = DrvDispatch; 60 } 61 //返回成功结果 62 return STATUS_SUCCESS; 63 }