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 程序,并勾选以下选项:

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

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

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

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

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

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

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

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

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

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

1.2 驱动信息

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

3: kd> lm m HEVD
Browse full module list
start end module name
ae46f000 ae4b9000 HEVD (private pdb symbols) e:\mysymbol\HEVD.pdb\8921ACC09C6B46A38CA2F42DA3E21ADA1\HEVD.pdb 3: kd> !drvobj HEVD 2
Driver object (86eb6b98) is for:
\Driver\HEVD
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", '\Device\HackSysExtremeVulnerableDriver',0
    INIT:00448182 ; const WCHAR aDosdevicesHack_0
    INIT:00448182 aDosdevicesHack_0: ; DATA XREF: DriverEntry(x,x)+25↑o
    INIT:00448182 text "UTF-16LE", '\DosDevices\HackSysExtremeVulnerableDriver',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%X\n"
    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:\Users\soma\Downloads\HackSysExtremeVulnerableDriver-master\HackSysExtremeVulnerableDriver-master\Exploit\HackSysEVDExploit.sln

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

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

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

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

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

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

1.5 编写客户端应用程序

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

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

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

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

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

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

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

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

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

1.6 参考

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

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

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

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

[1] HEVD 学习笔记:HEVD 环境搭建的更多相关文章

  1. Android Studio 学习笔记(一)环境搭建、文件目录等相关说明

    Android Studio 学习笔记(一)环境搭建.文件目录等相关说明 引入 对APP开发而言,Android和iOS是两大主流开发平台,其中区别在于 Android用java语言,用Android ...

  2. 我的Java学习笔记 -开发环境搭建

    开始学习Java~ 一.Java简介 Java编程语言是一种简单.面向对象.分布式.解释型.健壮安全.与系统无关.可移植.高性能.多线程和动态的语言. Java分为三个体系: JavaSE(J2SE) ...

  3. Django学习笔记 开发环境搭建

    为什么使用django?1.支持快速开发:用python开发:数据库ORM系统,并不需要我们手动地构造SQL语句,而是用python的对象访问数据库,能够提升开发效率.2.大量内置应用:后台管理系统a ...

  4. cocos2d-x lua 学习笔记(1) -- 环境搭建

    Cocos2d-x 3.0以上版本的环境搭建和之前的Cocos2d-x 2.0 版差异较大的,同时从Cocos2d-x 3.0项目打包成apk安卓应用文件,搭建安卓环境的步骤有点繁琐,但搭建一次之后, ...

  5. SpringData JPA的学习笔记之环境搭建

    一.环境搭建 1.加入jar包   spring jar+jpa jar +springData jar >>SpringData jar包     2.配置applicationCont ...

  6. Mybatis学习笔记之---环境搭建与入门

    Mybatis环境搭建与入门 (一)环境搭建 (1)第一步:创建maven工程并导入jar包 <dependencies> <dependency> <groupId&g ...

  7. 前端框架vue学习笔记:环境搭建

    兼容性 不兼容IE8以下 Vue Devtools 能够更好的对界面进行审查和调试 环境搭建 1.nodejs(新版本的集成了npm)[npm是node包管理 node package manager ...

  8. Web安全测试学习笔记 - vulhub环境搭建

    Vulhub和DVWA一样,也是开源漏洞靶场,地址:https://github.com/vulhub/vulhub 环境搭建过程如下: 1. 下载和安装Ubuntu 16.04镜像,镜像地址:htt ...

  9. 【Django学习笔记】-环境搭建

    对于初学django新手,根据以下步骤可以快速进行Django环境搭建 虚拟环境创建 使用virtualenv创建并启用虚拟机环境 ,关于virtualenv可参考https://www.yuque. ...

  10. go 学习笔记之环境搭建

    千里之行始于足下,开始 Go 语言学习之旅前,首先要搭建好本地开发环境,然后就可以放心大胆瞎折腾了. Go 的环境安装和其他语言安装没什么特别注意之处,下载安装包下一步下一步直到完成,可能唯一需要注意 ...

随机推荐

  1. Solon 开发进阶,三、常用配置说明

    Solon 开发进阶 一.插件扩展机制 二.体外扩展机制 三.常用配置说明 四.启动参数说明 五.全局异常订阅 应用主配置文件为: resources/app.yml( 或 app.propertie ...

  2. 人人都会Kubernetes(一):告别手写K8s yaml,运维效率提升500%

    1. Kubernetes的普及和重要性 随着云计算的迅速发展,容器化技术已成为构建和运行分布式应用程序的关键.而Kubernetes作为容器编排领域的佼佼者,已经成为了云原生应用的标准.它不仅简化了 ...

  3. IIS 设置超时时间

    高级设置 => 限制 => 连接超时(秒),默认120秒,根据实际情况调整

  4. 大数据 - ODS&DWD&DIM-SQL分享

    大数据 ODS&DWD&DIM-SQL分享 需求 思路一:等差数列 断2天.3天,嵌套太多 1.1 开窗,按照 id 分组,同时按照 dt 排序,求 Rank -- linux 中空格 ...

  5. AtCoder ABC 164 (D~E)

    比赛链接:Here ABC水题, D - Multiple of 2019 (DP + 分析) 题意: 给定数字串S,计算有多少个子串 \(S[L,R]\)​ ,满足 \(S[L,R]\) 是 \(2 ...

  6. Codeforces Round #741 (Div. 2) 个人题解 A~D

    比赛链接:Here 1562A. The Miracle and the Sleeper 题意: 给出 \(l,r\) 求出最大化的 \(a\ mod\ b\) (\(l\le b\le b\le a ...

  7. AtCoder Beginner Contest 166 (A~E)

    比赛链接:Here AB水题 C - Peaks 题意: 给出 \(n\) 个观察台的高度,以及 \(m\) 条边,定义"好观察台":比所有直接相连的观测台都高 思路: 因为道路是 ...

  8. L2-010. 排座位(种类并查集)

    布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位.无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他们是否能被安排同席. 输入格式: ...

  9. 2.5D 组态案例合集 | 智慧园区、数据中心、SMT 生产线、汽车制造

    在阅读文章之前,大家可以思考下 2.5D 设计属于哪种界定? 2.5D 是通过二维的元素来呈现出三维的效果.其实在国外并没有 2.5D 这样的称呼,标准说法是 Isometric 风格,翻译过来就是等 ...

  10. 对话开发者:Serverless 落地的困境与破局

    作者 | 阿里云开发者社区.InfoQ 从 2012 年提出 Serverless 到今年 2022 年刚好十年. 过去十年,上云是确定性趋势,在这个阶段企业一开始的关注点在于如何实现平滑上云.随着越 ...