导语:FLARE团队开发出一个可以动态分析恶意软件的工具——kernel shellcode loader,本文对该工具的原理等进行分析。

虽然许多恶意样本都可以进行静态分析,但FLARE团队有时候会调试这些样本来确认特定的功能。调试是一种非常有效的方式来解决混淆和封装,快速识别kernel shellcode样本被访问的结构,系统路径和进程。

一般来说,我们都是用虚拟机这样的安全环境来分析恶意软件,很少用kernel shellcode loader这样的工具来分析。下面我们对kernel shellcode loader工具进行简单分析。

背景

在基于shellcode样本冲突的分析方法中,分析人员可能并不知道样本要攻击用户空间还是内核空间。一种常见的方法是在shellcode加载器中加载样本代码,然后在用户空间中调试。在kernel shellcode中,就会有意外的结果,比如非法访问,如图1所示。

Fig1.png

图1 shellcode引用空指针造成非常访问

Kernel环境是与用户模式完全不同的环境,不同的寄存器有不同的作用,并指向完全不同的结构。比如,64位Windows的gs段寄存器用户模式指向0x38字节的线程信息块(thread information block,TIB),而在内核模式下指向的是更大的处理器控制区域(Processor Control Region,KPCR)。在图1地址0x2e07d9处,shellcode会尝试访问KPCR的IdtBase成员,但是运行中用户模式下后,gs段0x38的偏移量值是空。这会让下一个指令去尝试访问空页面的无效内存。代码尝试去做的行为在用户模式下手没有意义的,最终的结果就是奔溃。

相对而言,内核模式就更加完美的。图2是用来显示ntoskrnl.pdb中定义的_KPCR类型的WinDbg的dt命令,强调了偏移量为0x38的域IdtBase。

Fig2.png

图2 KPCR结构

根据样本代码的其他部分,访问KPCR的IdtBase域是有意义的。研究人员认为kernel shellcode可以解决他的疑惑,为了确认,研究人员写了一个内核shellcode loader。看起来该工具是用来加载shellcode的小片段。

Kernel Shellcode Loader

研究人员在内核调试器中打开了目标系统,并在shellcode loader相同目录下打开一个cmd窗口。Shellcode loader可以接受磁盘中文件的名称,而shellcode只是一个定位的参数。图3是研究人员用hex编辑器编辑NOP和RET的操作码,并写进了二进制文件中,然后调用kscldr.exe来传递操作码到kernel shellcode loader驱动中。

Fig3.png

图3 用kscldr.exe加载kernel shellcode

shellcode loader显示安全警告弹窗。在点击yes后,kscldr.exe会安装驱动并使用驱动来执行shellcode。系统在此处会保存所有信息,因为kernel驱动发布了断点,而kernel调试器中等待命令。

图4是WinDbg命中断点和相关的kscldr.sys中的源代码

Fig4.png

图4 kscldr.sys

从断点开始,研究人员用WinDbg和源代码级别的调试技术来追踪shellcode缓存。图5是WinDbg的缓存汇编窗口。

Fig5.png

图5 对shellcode进行溯源和汇编

汇编窗口是0x90和0x30的操作码,证明了shellcode的缓存是执行了的。WinDbg就可以调试和分析代码的行为了。

工具使用

如果想要体验FLARE的kernel shellcode loader,首先需要下载源码。

下载和安装Windows驱动套件(WDK),本例中使用的是Windows Driver Kit 7.1.0版本,受用更新版本的WDK也是可以的,但是7.1.0版本与该工具非常匹配。

在下载和安装了WDK后,在开始菜单中浏览WDK目录,选择合适的环境。图6是win 7系统中的WDK程序分组。研究人员计划加载64位的kernel shellcode,所以使用x64 Checked Build环境。

Fig6.png

图6  Windows Driver Kits程序分组

在WDK的命令提示符中,切换到下载的FLARE Kernel shellcode loader目录,输入ez.cmd。脚本会提示需要提供测试签名证书的密码。在环境搭建完成后,访问bin目录,复制kscldr.exe到调试目标中。在这个过程之前还需要对目标系统进行一些修改。

准备调试目标

为了调试kernel shellcode,研究人员写了一个在权限level 0下加载和允许shellcode的Windows软件驱动。正常情况下,Windows只加载特殊交叉主任证书签名的驱动,但Windows允许测试签名来加载用测试证书签名的驱动。所以就可以创建一个免费的测试证书,虽然这个证书不能在生产系统中加载。

除了开启测试签名模式外,还需要开启kernel调试来追踪kernel shellcode执行后发生的情况。在windows Vista之后的版本都可以通过下面的命令来开启测试签名和kernel调试:

bcdedit.exe /set testsigning on
bcdedit.exe /set debug on

在虚拟中调试的话,要安装一个VirtualKD,但是也可以根据厂商的指引连接WinDbg可以理解的序列端口或管道。一旦建立链路,就可以开始下一步了。

如果尝试用shellcode loader然后系统蓝屏,错误代码为0x3B (SYSTEM_SERVICE_EXCEPTION)。这说明并没有成功地连接到kernel调试器。需要注意的是,驱动会在执行shellcode之前发布一个软件中断来控制调试器。如果调试器没有成功附加,Windows就会蓝屏。解决的办法是重启,然后点击Debug -> Break in WinDbg来确认调试器在控制下;然后就可以用g命令来继续执行。

工作原理

用户空间应用(kscldr.exe)从PE-COFF资源中复制驱动来磁盘中并注册为Windows kernel服务。然后驱动就会执行设备写和I/O控制操作来与用户应用交互。驱动的入口点首先会注册dispatch路径来处理CreateFile、 WriteFile、DeviceIoControl和CloseHandle。然后,创建一个名为\Device\kscldr的设备和链接让设备名可以从用户空间访问。当用户应用打开设备文件并调用WriteFile后,驱动会调用ExAllocatePoolWithTag说明NonPagedPool的PoolType,然后将缓存写入新分配的内存中。在写操作完成后,应用应用可以调用DeviceIoControl来访问shellcode。作为响应,驱动会在设备对象中设定适当的标志,发布断点来传递控制到kernel调试器,最后调用shellcode。

驱动开发是打开设备大门的唯一入口。图7是WDK帮助文件中的kernel回调路径,可以追踪系统进程,线程和DLL活动。

Fig7.png

图7 WDK kernel模式驱动参考架构

内核开发是一个非常复杂的工作,但是WDK附带了许多的驱动样本,这些样本说明了正确的Windows内核编程技术。有时间的可以了解一下,这与Windows内部信息,安全研究等都是有关的。

总结

本文分析了FLARE加载特权shellcode的工具——Kernel Shellcode Loader,在该工具的帮助下,我们可以在测试环境中动态地分析kernel shellcode。

源链接

Hacking more

...