目录
内核基础知识
内核态 Ring0
用户态 Ring3
那么内核漏洞是Ring0程序中能被利用的bug或缺陷
除了操作系统内核程序,驱动程序也是运行在Ring0,一些安全软件,游戏软件,工具软件等第三方驱动程序都是在Ring0级别上运行的
驱动编写之Hello World
编写代码
#include <ntddk.h> #define DEVICE_NAME L"\\Device\\HelloWorld" #define DEVICE_LINK L"\\DosDevices\\HelloWorld" // 创建的设备对象指针 PDEVICE_OBJECT g_DeviceObject; // 驱动卸载函数 VOID DriverUnload(IN PDRIVER_OBJECT driverObject){ // 什么都不用做,打印一句话,helloword就这套路 KdPrint(("DriverUnload: 88!\n")); } // 驱动派遣例程函数 NTSTATUS DrvDispatch(IN PDEVICE_OBJECT driverObject, IN PIRP pIrp){ KdPrint(("Enter DrvDispatch\n")); // 设置IRP的完成状态 pIrp->IoStatus.Status = STATUS_SUCCESS; // 设置IRP的操作字节数 pIrp->IoStatus.Information = 0; // 完成IRP处理 IoCompleteRequest(pIrp, IO_NO_INCREMENT); return STATUS_SUCCESS; } // 驱动入口函数(相当于main函数) NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath){ NTSTATUS ntStatus; UNICODE_STRING devname; UNICODE_STRING symLinkName; int i; // 打印一句调试信息 KdPrint(("DriverEntry: Hello world driver demo!")); // 设置该驱动对象的卸载函数 //driverObject->DriverUnload = DriverUnload; // 创建设备 RtlInitUnicodeString(&devname, DEVICE_NAME); ntStatus = IoCreateDevice(driverObject, 0, &devname, FILE_DEVICE_UNKNOWN, 0, TRUE, &g_DeviceObject); if (!NT_SUCCESS(ntStatus)) { return ntStatus; } // 创建符号链接 RtlInitUnicodeString(&symLinkName, DEVICE_LINK); ntStatus = IoCreateSymbolicLink(&symLinkName, &devname); if (!NT_SUCCESS(ntStatus)){ IoDeleteDevice(g_DeviceObject); return ntStatus; } // 设置该驱动对象的派遣例程函数 for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++){ driverObject->MajorFunction[i] = DrvDispatch; } // 返回成功结果 return STATUS_SUCCESS; }
之后安装WDK
继续
跟着抄的程序,这应该影响不大
作者给的源码编译的结果,perfect
看到驱动文件了
这不能像exe那样运行,需要作为内核模块来加载和运行
我们可以在用户态使用服务管理器创建服务,将xxx.sys和服务关联在一起,通过启动服务向内核加载xxx.sys
初学还是用工具
不知为啥不能卸载驱动
看看代码原来是注释了
就是用比对软件看看自己敲的跟作者的差别时加了注释
注释删掉就可以啦
派遣例程与IRP结构
IRP(I/O Request Package):输入输出请求包
Ring3通过DeviceControl等函数向驱动发出I/O请求后,在内核中由操作系统将其转化为IRP的数据结构,并“派遣”到对应驱动的派遣函数中
一个驱动还有多个派遣函数,具体要派遣到哪个派遣函数
由RIP结构中的MajorFunction属性决定
但现在文档只有下面的属性
不知道是不是这里显示不全,作者说是0x1b,即27个
那个helloworld全都设置成同一个函数了
为了更灵活查询内和数据结构,还要其他工具,比如下载符号文件的
以前分析漏洞下断点时,符号文件在ida,windbg调试的时候也是很有用的
那个看pdb文件的在xp打开不了
win7就可以打开软件,但是!!打开失败,就不截图了,打得开别的也看不到符号
之后发现是在xp下载的符号文件有问题
终于可以了,很清晰了这样就
后面两小节就看看书就好了
继续前行
内核调试入门
内核调试3中方法,这里使用虚拟机还是比较方便的
首先设置虚拟机添加硬件,串行端口
继续
继续
我的还要这个
要打钩哦
之后修改虚拟机的boot.ini文件
首先去除保护属性
增加一个系统启动项恢复保护属性
重启选择调试系统
好像卡住了似的,不用怕,它是等待调试器
windbg搞个快捷方式
在目标后加上
-b -k com:port=\\.\pipe\com_1,baud=115200,pipe
之后发现打开那个快捷方式竟然连不上,搜了一下,原来打印机占用了串口1,我们建的变2了
果断删掉,之后串口再建,就行了
下面是蓝屏分析,应该是没有设置转存文件,以后知道怎么做再补上
内核漏洞概述
内核漏洞分类:
按照严重程度分类:
-
远程拒绝服务
-
本地拒绝服务
-
远程任意代码执行
-
本地权限提升
按照漏洞利用类型分类:
-
拒绝服务
-
缓冲区溢出
-
内存篡改
-
任意地址写任意数据
-
固定地址写任意数据
-
任意地址写固定数据
-
设计缺陷
内核漏洞研究过程
-
漏洞重现:环境搭建,POC编译
-
漏洞分析:源码对比,反汇编分析,POC分析,补丁对比,内核调试跟踪,蓝屏分析
-
漏洞利用:特权提升,远程溢出,本地溢出,远程DOS,本地DOS
-
漏洞总结:根本原因,修补方法
内核漏洞挖掘:手工和工具咯,加上你的经验和知识
好,继续学吧,敲敲文字也挺好的
编写安全的驱动程序
-
输入输出检查
-
验证驱动调用者:可以检查调用者进程文件的md5,等,还可以用户态程序和驱动程序通信加密,解密失败和非法通信数据直接不处理
-
白名单机制的挑战:就是安全软件为了避免第三方驱动运行出现问题,大多开设了白名单机制,假如白名单中的驱动存在漏洞,那么木马不用加载自己的驱动也能提权什么的,所以加入白名单需要经过安全评估才能加入