内核基础知识介绍:
内核概述:Interx86系列处理器使用“环”的概念实施访问控制,共4个权限级别。一般情况下,操作系统的内核程序、驱动程序等都在Ring0级别上运行。研究内核漏洞,需要首先掌握一些内核基础知识、例如内核驱动程序的开发、编译和运行,以及内核中重要的数据结构等。
驱动编写之Hello World
代码,保存为Helloworld.c 路径 D: dayHelloWorldhelloworld.c
#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! ")); } // 驱动派遣例程函数 NTSTATUS DrvDispatch(IN PDEVICE_OBJECT driverObject, IN PIRP pIrp){ KdPrint(("Enter DrvDispatch ")); // 设置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
检查安装
安装成功
build后的结果和作者不一样
排查,是细节问题,忘记改文件名后缀了,哈哈,编译成功
不能直接双击运行,使用工具运行,
这不能像exe那样运行,需要作为内核模块来加载和运行
我们可以在用户态使用服务管理器创建服务,将xxx.sys和服务关联在一起,通过启动服务向内核加载xxx.sys
查看代码,与作者代码比对,去掉注释。
驱动可以安装,开启,卸载
派遣例程与IRP结构
IRP“输入/输出请求包”,Ring3通过DeviceIoControl等函数向驱动发出I/O请求,在内核中由操作系统转化为IRP的数据结构,并“派遣”到对应驱动的派遣函数中
XP下打不开,用win8打开的,文档中保函的属性没有书里面说的多,作者说的0x1b,27个
使用PDB辅助工具查阅内核数据结构信息(SymbolTypeViewer,PEB explorer)
S 看完没有成功下载pdb文件,网络没问题
后两节稍微看了看
Ring3打开驱动设备
Ring3访问设备时要求创建符号链接,Ring3可以通过CreateFile函数打开设备。“\.DosDeviceName”格式。
Ring3/Ring0四种通信方式
METHOD_BUFFERED:缓冲区方式、METHOD_IN_DIRECT、METHOD_OUT-DIRECT、:对Ring3的输入缓冲区进行缓冲,对Ring3的输出缓冲区没有缓冲。METHOD_NEITHER:其他方式
缓冲方式,
内核调试入门
创建内核调试环境
《软件调试》一书讲的多。
内核调试主要三种:1,硬件调试。2,内核中插入用于调试的中断处理函数和驱动程序。3,系统内核中加入调试支持,三种链接方式:串行口,1394,usb2.0.
本书“利用命名管道模拟串行端口”:原理:虚拟一个串行端口,映射到宿主机的命名管道上,虚拟机中所有对该串口的读写操作都会被虚拟机管理软件转换为对宿主系统中命名管道的读写。缺点:硬件相关驱动调试不了,涉及底层操作(中断、异常、I/O)函数或指令可能导致虚拟机重启,CPU占用路高,90%以上。
搭建调试内核的环境
需要两个,WinDbg,VMware
设置串口,,
此处打钩
修改启动配置文件
增加系统启动选项
恢复保护属性
关机
设置WinDbg参数 目标后面加上
-b -k com:port=\.pipecom_1,baud=115200,pipe
(需要把打印机移除)
选择调试系统
出现此问题,需要将打印机移除,并重新添加串口模式。
成功
蓝屏分析:(以后学习调试内核的时候补上)
"启动和故障恢复",完整转储,内核转储,小型内存转储。
内核漏洞概述
内核漏洞的分类:
按照严重程度: 远程拒绝服务、本地拒绝服务、远程任意代码执行、本地权限提升。
按漏洞利用原理分类:拒绝服务、缓冲区溢出、内存篡改:任意地址写任意数据,固定地址写任意数据,任意地址写固定数据、设计缺陷。
内核漏洞研究过程:
4个过程:漏洞重现,漏洞分析,漏洞利用,漏洞总结。
内核漏洞挖掘:手工、工具,加上经验与知识。 go on
编写安全的驱动程序:
开发者角度:未验证输入、输出,未验证调用者,代码逻辑错误,系统设计存在安全缺陷等
1,输入、输出检查:对不可信的输入输出地址及数据长度进行合法性检查。
2,验证驱动的调用者
3,白名单机制的挑战