目录
笔记
驱动:Windows设备驱动的简称,是第三方开发商在Windows内核模式下运行代码,常在内存中,负责响应用户态程序的请求。
设备对象不一定是真实的物理设备
应用程序不能直接访问驱动程序
当一个驱动程序首次加载到内核空间中时,会调用DriverEntry函数被调用。驱动程序通过注册回调函数来提供功能,回调函数在DriverEntry中被注册。
恶意驱动不控制硬件设备,而是与Windows系统中的主要内核组件ntoskrnl.exe(包含操作系统的核心功能代码),hal.dll(包含与主要硬件设备交互的代码)进行交互。
安装内核调试:安装教程:1.配置win7设置
之后重启
2.设置windbg
https://blog.csdn.net/qq429205464/article/details/51064763
Windbg的使用:内存读取
dx----->读取程序数据或堆栈等内存位置的命令
da----->读取内存数据并以ASCII文本显示
du----->读取内存数据并以Unicode文本显示
dd----->读取内存数据并以32位双字显示
ex----->改变内存的值(ex addresssToWrite dataToWrite)
算术运算符
加,减,乘,除可以直接作用到指针上
dwo (esp+4)----->获得esp+4的地址
du dwo (esp+4)----->获得esp+4的地址处的宽字符
设置断点
bp----->设置断点
go----->继续执行,不等待用户
bp GetProcAddress "da dwo(esp+8);8"----->在每次调用GetProcAddress函数时,打印函数名。
列举模块
lm----->列举当前进程空间中的所有模块,包括用户模式下的可执行模块,DLL以及内核模式下的内核驱动
符号表
调试符号表提供一个地址名称来标识一个函数
moduleName!symbolName
moduleName表示exe,dll,sys格式文件的文件名
u nt!exportedFunction------>汇编nt模块部分的exportedFunction函数
bu----->用符号在没有加载代码的地方设置延迟断点
bu newMoudle!exportedFunction------>在newModule模块的exportedFunction函数位置设置断点
x nt !*CreateProcess*----->搜索ntoskernl.exe中包含的字符串CreateProcess的所有函数
Ln----->列出最接近给定内存地址的符号
ln 805717aa----->地址805717aa的函数调用
查看结构信息
dt nt!_DRIVER_OBJECT----->查看数据结构
dt nt!_DRIVER_OBJECT 828b2648----->查看828b2648位置的驱动对象对应的结构和数据
配置Windows符号表
1.File->Symbol->File path 来设置
2.在线符号服务器 :SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols
c:\websymbols符号信息的本地缓存,http://msdl.microsoft.com/download/symbols微软符号服务器
内核调试:在内核模式下的恶意代码,可以绕过一些安全产品,同时可以误导那些试图寻找用户空间的函数,并通过函数名来识别恶意代码的功能。
实例:用户空间代码
使用CreateService函数创建驱动,其中1处的参数值是1,表示创建的是一个内核驱动
调用CreateService函数创建一个文件,以此来获得内核设备句柄
获取设备句柄后,调用DeviceIoControl,向内核驱动发送数据
内核空间代码
在内核调试窗口可以看到FileWriter被加载,这可能是一个恶意驱动程序
找驱动对象,确定一下调用了恶意驱动程序的哪些函数
根据驱动的名字找到驱动对象,得到驱动对象的地址,查看数据结构
MajorFunction项指向主函数表首项的一个指针。例如:要找DeviceIoControl在调用表的位置,先索引IRP_MJ_DEVICE_CONTROL值为0xe,主函数表的偏移是0x38,所以函数的偏移值为827e3698+0x38+e*4
找到函数的调用位置,u f7b0da66来查看这里的代码
查找驱动对象:用户态应用程序可以识别设备对象,设备对象提供一个指向驱动对象的指针,通过这个对象指针就可以获得驱动程序的分发函数表。
获得设备对象 827e3698,根据这个句柄,!devhandles命令获得拥有这个设备句柄的所有用户态应用程序列表。
FilWriterApp.exe正在使用这个恶意驱动程序
Rootkit:通过改变操作系统内部函数,来隐藏自己的痕迹。可以隐藏正在运行的文件,进程,网络连接和其他资源。
系统调用表
系统调用表又称系统服务表或者服务描述符表,是Windows 内核在进行各种系统操作时所需的一个函数指针表。也就是说,这个表中存放的是提供系统服务的各种函数的地址。当然,该表所指向的都是系统自身的一些函数,但是,如果我们对它做了手脚后,就可以让它指向我们自己的函数。
钩子函数通常调用初始的原生API,然后在原生API将结果返回到用户态程序之前将其输出结果改变.这种技术可以使核心态rootkit隐藏文件,进程或者阻止恶意进程被结束。
分析实践:1.直接查看SSDT是否被挂钩(nt!KeServiceDescriptorTable),来查看函数的偏移量是否在NT模块的范围内
2.然后找出那个驱动程序包含了这个地址(lm)
3.IDA分析找出安装挂钩代码函数和执行挂钩代码函数。
安装挂钩代码函数第一步会获取NtCreateFile和KeServiceDescriptorTable两个字符串,第二步根据MmGetSystemRoutineAddress函数获取这个两个函数的地址。NtCreateFile地址----->把这个地址当做覆盖恶意函数地址的目标地址,KeServiceDescriptorTable地址----->得到SSDT的地址。第三步循环遍历SSDT,找到NtCreateFile的地址的值。第四步安装挂钩函数。
执行挂钩代码函数过滤一些特殊请求,其他直接转发给NtCreateFile
中断:Rootkit会使用中断来干扰系统事件,当系统发送一条指令到硬件,硬件处理完请求事件会中断处理器。驱动程序调用IoConnectInterrupt函数为特定中断注册一个处理程序,并指定一个中断服务例程(ISR)。可以用命令!idat查看ISR的信息。
其中没有名字,没有签名的比较可疑
加载驱动:OSR Driver Loader
实验
Lab10-1
Lab10-1对Lab10-01.sys创建了个服务
使用strings查看这个Lab10-01.sys中的字符串,IDApro中的Strings窗口查不出这些字符串。上述的字符串像是注册表的信息,但和一般的注册表不一样。