[1] HEVD 学习笔记:HEVD 环境搭建

1. HEVD 概述 + 环境搭建

​ HEVD作为一个优秀的内核漏洞靶场受到大家的喜欢,这里选择x86的驱动来学习内核漏洞,作为学习笔记记录下来

实验环境

环境 备注
调试主机操作系统 Windows 10 x64(随便什么操作系统都行)
被调试主机的操作系统 Windows 7 x86 SP1
编译 HEVD 项目的 IDE VS 2017
安装驱动的工具 Kernel Mode Driver Manager
反编译工具 IDA Pro 7.6
其他工具 DebugView

从以下的 github 可以下载 Release 版本的驱动文件,下载之后就是安装了

github 地址GitHub - hacksysteam/HackSysExtremeVulnerableDriver: HackSys Extreme Vulnerable Windows Driver (HEVD)

1.1 安装驱动

  1. HEVD和专项利用工具以调试字符串的形式打印大量的信息。我们既可以从调试方主机(使用WinDbg调试器),也从被调试方主机(使用DebugView工具)查看这些信息。

    在调试方输入:ed nt!Kd_Default_Mask 8 启动打印调试字符串的功能,然后输入 g

    在虚拟机中使用管理员身份运行 dbgView 程序,并勾选以下选项:

    image-20221212225900802

  2. 将预构建的程序包(驱动+漏洞)下载到被调试方(即被攻击主机),选择有漏洞的 x86 驱动

    image-20221212230006076

  3. 使用加载驱动的软件安装该驱动,我这里使用 KMD:以管理员身份运行该程序,点击即可安装并启动服务

    image-20221212230150223

  4. 启动服务成功后,DebugView 和 Windbg 都打印出如下的字符串即为安装成功

    image-20221212230227549

    image-20221212230359780

  5. 验证HEVD模块是否已加载,其符号是否已成功映射

    输入 lm m H* 可以看到 HEVD 模块已被成功加载

    image-20221213012104400

    输入 x /D HEVD!a* 发现该符号文件并未被加载:

    image-20221213012153209

    为了加载该符号文件,需要弄清楚该符号文件应该存放的路径,输入 !sym noisy,此时再输入 x /D HEVD!a*

    image-20221213012316165

    从上面的调试信息可以看出,该符号文件在我的电脑中的所在路径为:e:mysymbolHEVD.pdb8921ACC09C6B46A38CA2F42DA3E21ADA1HEVD.pdb

    在我的电脑上创造该路径,并将 HEVD.pdb 文件复制到这个文件夹下:

    image-20221213012711720

    输入 .reload 重新加载一下,再输入 x /D HEVD!a*,即可看到列出的函数,说明此时的符号文件已经被加载

    image-20221213012921056

1.2 驱动信息

​ 按以下调试信息输入命令查看驱动信息:

3: kd> lm m HEVD
Browse full module list
start    end        module name
ae46f000 ae4b9000   HEVD       (private pdb symbols)  e:mysymbolHEVD.pdb8921ACC09C6B46A38CA2F42DA3E21ADA1HEVD.pdb

3: kd> !drvobj HEVD 2
Driver object (86eb6b98) is for:
 DriverHEVD
DriverEntry:   ae4b70ea HEVD!GsDriverEntry
DriverStartIo: 00000000 
DriverUnload:  ae4b3000 HEVD!DriverUnloadHandler
AddDevice:     00000000 

Dispatch routines:
[00] IRP_MJ_CREATE                      ae4b3048    HEVD!IrpCreateCloseHandler
[01] IRP_MJ_CREATE_NAMED_PIPE           ae4b35c2    HEVD!IrpNotImplementedHandler
[02] IRP_MJ_CLOSE                       ae4b3048    HEVD!IrpCreateCloseHandler
[03] IRP_MJ_READ                        ae4b35c2    HEVD!IrpNotImplementedHandler
[04] IRP_MJ_WRITE                       ae4b35c2    HEVD!IrpNotImplementedHandler
[05] IRP_MJ_QUERY_INFORMATION           ae4b35c2    HEVD!IrpNotImplementedHandler
[06] IRP_MJ_SET_INFORMATION             ae4b35c2    HEVD!IrpNotImplementedHandler
[07] IRP_MJ_QUERY_EA                    ae4b35c2    HEVD!IrpNotImplementedHandler
[08] IRP_MJ_SET_EA                      ae4b35c2    HEVD!IrpNotImplementedHandler
[09] IRP_MJ_FLUSH_BUFFERS               ae4b35c2    HEVD!IrpNotImplementedHandler
[0a] IRP_MJ_QUERY_VOLUME_INFORMATION    ae4b35c2    HEVD!IrpNotImplementedHandler
[0b] IRP_MJ_SET_VOLUME_INFORMATION      ae4b35c2    HEVD!IrpNotImplementedHandler
[0c] IRP_MJ_DIRECTORY_CONTROL           ae4b35c2    HEVD!IrpNotImplementedHandler
[0d] IRP_MJ_FILE_SYSTEM_CONTROL         ae4b35c2    HEVD!IrpNotImplementedHandler
[0e] IRP_MJ_DEVICE_CONTROL              ae4b3064    HEVD!IrpDeviceIoCtlHandler
[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL     ae4b35c2    HEVD!IrpNotImplementedHandler
[10] IRP_MJ_SHUTDOWN                    ae4b35c2    HEVD!IrpNotImplementedHandler
[11] IRP_MJ_LOCK_CONTROL                ae4b35c2    HEVD!IrpNotImplementedHandler
[12] IRP_MJ_CLEANUP                     ae4b35c2    HEVD!IrpNotImplementedHandler
[13] IRP_MJ_CREATE_MAILSLOT             ae4b35c2    HEVD!IrpNotImplementedHandler
[14] IRP_MJ_QUERY_SECURITY              ae4b35c2    HEVD!IrpNotImplementedHandler
[15] IRP_MJ_SET_SECURITY                ae4b35c2    HEVD!IrpNotImplementedHandler
[16] IRP_MJ_POWER                       ae4b35c2    HEVD!IrpNotImplementedHandler
[17] IRP_MJ_SYSTEM_CONTROL              ae4b35c2    HEVD!IrpNotImplementedHandler
[18] IRP_MJ_DEVICE_CHANGE               ae4b35c2    HEVD!IrpNotImplementedHandler
[19] IRP_MJ_QUERY_QUOTA                 ae4b35c2    HEVD!IrpNotImplementedHandler
[1a] IRP_MJ_SET_QUOTA                   ae4b35c2    HEVD!IrpNotImplementedHandler
[1b] IRP_MJ_PNP                         ae4b35c2    HEVD!IrpNotImplementedHandler

​ 驱动装载的地址是 0xae46f000,DriverEntry 的地址是 0xae4b70ea,所以 DriverEntry 的偏移地址是 0x480EA,IRP_MJ_DEVICE_CONTROL 的分发函数偏移地址 0x44064

1.3 IDA 分析

  1. 使用IDA对驱动进行分析,可以看到在DriverEntry首先是创建了设备对象

    INIT:00448036                 push    eax             ; DeviceObject
    INIT:00448037                 push    edi             ; Exclusive
    INIT:00448038                 push    FILE_DEVICE_SECURE_OPEN ; DeviceCharacteristics
    INIT:0044803D                 push    FILE_DEVICE_UNKNOWN ; DeviceType
    INIT:0044803F                 lea     eax, [ebp+DestinationString]
    INIT:00448042                 push    eax             ; DeviceName
    INIT:00448043                 push    edi             ; DeviceExtensionSize
    INIT:00448044                 push    ebx             ; DriverObject
    INIT:00448045                 call    ds:IoCreateDevice
    
  2. 随后就是对分发函数的赋值以及符号链接的创建

    INIT:00448075                 push    1Ch
    INIT:00448077                 pop     ecx
    INIT:00448078                 mov     eax, offset DispatchCommon
    INIT:0044807D                 lea     edi, [ebx+DRIVER_OBJECT.MajorFunction]
    INIT:00448080                 rep stosd
    INIT:00448082                 mov     eax, offset DispatchCreateAndClose
    INIT:00448087                 mov     dword ptr [ebx+70h], offset DispatchIoCtrl
    INIT:0044808E                 mov     [ebx+38h], eax
    INIT:00448091                 mov     [ebx+40h], eax
    INIT:00448094                 mov     eax, [ebp+DeviceObject]
    INIT:00448097                 mov     [ebx+_DRIVER_OBJECT.DriverUnload], offset DriverUnload
    INIT:0044809E                 or      [eax+DEVICE_OBJECT.Flags], DO_DIRECT_IO
    INIT:004480A2                 mov     eax, [ebp+DeviceObject]
    INIT:004480A5                 and     [eax+DEVICE_OBJECT.Flags], 0FFFFFF7Fh
    INIT:004480AC                 lea     eax, [ebp+DestinationString]
    INIT:004480AF                 push    eax             ; DeviceName
    INIT:004480B0                 lea     eax, [ebp+SymbolicLinkName]
    INIT:004480B3                 push    eax             ; SymbolicLinkName
    INIT:004480B4                 call    ds:IoCreateSymbolicLink
    
  3. 根据IDA识别的结果就可以得知符号名,根据符号名就可以完成和驱动的连接与通信

    INIT:00448134 aDeviceHacksyse:                        ; DATA XREF: DriverEntry(x,x)+14↑o
    INIT:00448134                 text "UTF-16LE", 'DeviceHackSysExtremeVulnerableDriver',0
    INIT:00448182 ; const WCHAR aDosdevicesHack_0
    INIT:00448182 aDosdevicesHack_0:                      ; DATA XREF: DriverEntry(x,x)+25↑o
    INIT:00448182                 text "UTF-16LE", 'DosDevicesHackSysExtremeVulnerableDriver',0
    
  4. 在 DispatchIoCtrl 中,程序将 IoControlCode 取出减去 0x222003 以后得到下标,在用这个下标从 Index_Table 中取出函数地址表的下标。在根据这个地址表的下标从 Func_Table 中获得函数地址以后跳转到该函数执行

    PAGE:00444064 ; int __stdcall DispatchIoCtrl(int, PIRP Irp)
    PAGE:00444064 DispatchIoCtrl  proc near               ; DATA XREF: DriverEntry(x,x)+87↓o
    PAGE:00444064
    PAGE:00444064 Irp             = dword ptr  0Ch
    PAGE:00444064
    PAGE:00444064                 push    ebp
    PAGE:00444065                 mov     ebp, esp
    PAGE:00444067                 push    ebx
    PAGE:00444068                 push    esi
    PAGE:00444069                 push    edi
    PAGE:0044406A                 mov     edi, [ebp+Irp]
    PAGE:0044406D                 mov     ebx, STATUS_NOT_SUPPORTED
    PAGE:00444072                 mov     eax, [edi+60h]  ; 取出CurrentStackLocation指针赋给eax
    PAGE:00444075                 test    eax, eax
    PAGE:00444077                 jz      loc_4444C5
    PAGE:0044407D                 mov     ebx, eax
    PAGE:0044407F                 mov     ecx, [ebx+IO_STACK_LOCATION.Parameters.DeviceIoControl.IoControlCode]
    PAGE:00444082                 lea     eax, [ecx-222003h] ; switch 109 cases
    PAGE:00444088                 cmp     eax, 6Ch
    PAGE:0044408B                 ja      loc_4444AD      ; jumptable 00444098 default case
    PAGE:00444091                 movzx   eax, ds:Index_Table[eax]
    PAGE:00444098                 jmp     ds:Func_Table[eax*4] ; switch jump
    
  5. 这两张表的内容如下,其中的FuncTable中的每一个地址都代表了不同的漏洞

    PAGE:004444E0 Func_Table      dd offset loc_44409F, offset loc_4440CF, offset loc_4440F1
    PAGE:004444E0                                         ; DATA XREF: DispatchIoCtrl+34↑r
    PAGE:004444E0                 dd offset loc_444113, offset loc_444135, offset loc_44415A ; jump table for switch statement
    PAGE:004444E0                 dd offset loc_44417F, offset loc_4441A4, offset loc_4441C9
    PAGE:004444E0                 dd offset loc_4441EE, offset loc_444213, offset loc_444238
    PAGE:004444E0                 dd offset loc_44425D, offset loc_444282, offset loc_4442A7
    PAGE:004444E0                 dd offset loc_4442CC, offset loc_4442F1, offset loc_444316
    PAGE:004444E0                 dd offset loc_44433B, offset loc_444360, offset loc_444385
    PAGE:004444E0                 dd offset loc_4443AA, offset loc_4443CF, offset loc_4443F4
    PAGE:004444E0                 dd offset loc_444419, offset loc_44443E, offset loc_444463
    PAGE:004444E0                 dd offset loc_444488, offset loc_4444AD
    PAGE:00444554 Index_Table     db      0,   1Ch,   1Ch,   1Ch
    PAGE:00444554                                         ; DATA XREF: DispatchIoCtrl+2D↑r
    PAGE:00444554                 db      1,   1Ch,   1Ch,   1Ch ; indirect table for switch statement
    PAGE:00444554                 db      2,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db      3,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db      4,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db      5,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db      6,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db      7,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db      8,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db      9,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    0Ah,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    0Bh,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    0Ch,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    0Dh,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    0Eh,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    0Fh,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    10h,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    11h,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    12h,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    13h,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    14h,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    15h,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    16h,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    17h,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    18h,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    19h,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    1Ah,   1Ch,   1Ch,   1Ch
    PAGE:00444554                 db    1Bh
    PAGE:004445C1                 align 2
    
  6. 如果取出的函数地址表的下标是0x1C,那么对应的就是最后一个跳转地址,也就是loc_4444AD。而这个地址中的代码是在告知用户,发送的IOCTL是不合法的IOCTL

    PAGE:004444AD loc_4444AD:                             ; CODE XREF: DispatchIoCtrl+27↑j
    PAGE:004444AD                                         ; DispatchIoCtrl+34↑j
    PAGE:004444AD                                         ; DATA XREF: ...
    PAGE:004444AD                 push    ecx             ; jumptable 00444098 default case
    PAGE:004444AE                 push    offset aInvalidIoctlCo ; "[-] Invalid IOCTL Code: 0x%Xn"
    PAGE:004444B3                 push    3               ; Level
    PAGE:004444B5                 push    DPFLTR_IHVDRIVER_ID ; ComponentId
    PAGE:004444B7                 call    ds:DbgPrintEx
    PAGE:004444BD                 add     esp, 10h
    PAGE:004444C0                 mov     ebx, STATUS_INVALID_DEVICE_REQUEST
    PAGE:004444C5
    PAGE:004444C5 loc_4444C5:                             ; CODE XREF: DispatchIoCtrl+13↑j
    PAGE:004444C5                                         ; DispatchIoCtrl+66↑j
    PAGE:004444C5                 and     [edi+_IRP.IoStatus.Information], 0
    PAGE:004444C9                 xor     dl, dl          ; PriorityBoost
    PAGE:004444CB                 mov     ecx, edi        ; Irp
    PAGE:004444CD                 mov     [edi+_IRP.IoStatus.anonymous_0.Status], ebx
    PAGE:004444D0                 call    ds:IofCompleteRequest
    PAGE:004444D6                 pop     edi
    PAGE:004444D7                 pop     esi
    PAGE:004444D8                 mov     eax, ebx
    PAGE:004444DA                 pop     ebx
    PAGE:004444DB                 pop     ebp
    PAGE:004444DC                 retn    8
    PAGE:004444DC DispatchIoCtrl  endp
    
  7. 总结:要触发不同的漏洞,IOCTL是从0x222003开始,每次都要增加4,最多可以增加0x1B次

1.4 测试漏洞利用工具

​ 相同的程序包中还包含一组专项利用工具,我们可以通过执行适当的命令来运行其中每一个工具。

  1. 下载 github 中的 HEVD 项目,使用 VS 2017 打开 C:UserssomaDownloadsHackSysExtremeVulnerableDriver-masterHackSysExtremeVulnerableDriver-masterExploitHackSysEVDExploit.sln

  2. 重新生成,得到 HackSysEVDExploit.exe

    image-20221213163006145

  3. 将生成的程序拖入虚拟机,下面我们尝试使用其中一些工具,并将cmd.exe设置为待运行的程序,如下图所示

    1)以管理员身份运行 cmd.exe

    image-20221213185249880

    2)进入以下页面即为启动成功

    image-20221213185355599

    3)输入 HackSysEVDExploit.exe -c cmd -p 使用Pool Overflow漏洞利用工具,如下图所示:

    image-20221213190759962

    4)如果整个漏洞利用过程运行成功,目标程序(cmd.exe)将被分配更高的权限。通过执行命令“whoami”可以确认,该程序确实提权运行了,结果如下图所示。

    image-20221213193218058

1.5 编写客户端应用程序

​ 根据 1.2 和 1.3 我们获得了应用程序和驱动交流的所有必要数据,可以将其全部放入一个头文件中,现在我们开始编写客户端的应用程序,基本步骤如下:

  1. 使用CreateFile函数来打开设备
  2. 然后,使用DeviceIoControl函数来发送IOCTL信号

这部分的代码可以参考:wke_exercises/task1 at master · hasherezade/wke_exercises · GitHub

将代码重新生成项目,编译一下就可以在后面的学习过程中进行测试了:(注意要编译成 Release 版本)

[1] HEVD 学习笔记:HEVD 环境搭建

使用该程序进行通信测试:

  1. 将生成的 Ring3ToHEVD.exe 拖入虚拟机中

  2. 双击运行该程序,输入漏洞的对应索引和要传入的数据大小

    [1] HEVD 学习笔记:HEVD 环境搭建

  3. 输出调试字符串如下:

    [1] HEVD 学习笔记:HEVD 环境搭建

  4. 在后面测试的时候,输入了 0x1000 的 Size 后引起了系统蓝屏,这个在后面的 poc 测试会经常用到

    [1] HEVD 学习笔记:HEVD 环境搭建

1.6 参考

GitHub - hacksysteam/HackSysExtremeVulnerableDriver: HackSys Extreme Vulnerable Windows Driver (HEVD)

Windows内核漏洞学习-HEVD的使用_Wwoc的博客-CSDN博客_jshevdjshevdjsjsvevd

初学Windows内核漏洞利用(二):熟悉HEVD (qq.com)

​ [原创]HEVD学习笔记之概述-二进制漏洞-看雪论坛-安全社区|安全招聘|bbs.pediy.com

原文链接: https://www.cnblogs.com/XiuzhuKirakira/p/16980747.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    [1] HEVD 学习笔记:HEVD 环境搭建

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/383738

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月8日 下午6:30
下一篇 2023年3月15日 上午9:57

相关推荐