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. OLAP引擎也能实现高性能向量检索,据说QPS高于milvus!

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 随着LLM技术应用及落地,数据库需要提高向量分析以及AI支持能力,向量数据库及向量检索等能力"异军突起& ...

  2. QE01/QA11/QA02屏幕增强

    1.业务需求 需要对来料检验增加"合格数量"和"不合格数量"字段,涉及三个增强开发 2.QE01\QE02\QE03\QE51N屏幕增强 增强表 增强点BADI ...

  3. AtCoder Beginner Contest 180 个人题解(快乐DP场)

    补题链接:Here A - box 输出 \(N - A + B\) B - Various distances 按题意输出 3 种距离即可 #include <bits/stdc++.h> ...

  4. java中除法结果不对。

    今天遇一个非常简单地计算,计算结果居然是不对0,查了一些前辈们的资料动手实验了一下,实验结果和代码分享给大家.需要计算的公式:(7/10)*0.8 结果居然不是0.56 而是 0,最后找到原因(7/1 ...

  5. mybatis-plus-QueryWrapper like的用法

    mybatis-plus 中想写like的语句 一.直接用 QueryWrapper 中的 like String deptLevelCodeTemp = "1000010001" ...

  6. vscode报错Already included file name ‘xxx‘ differs from file name ‘xxx‘ only in casing的解决方法:

    场景:我们创建了一个文件是小写开头的,又改成大写开头的. 比如: relationDemo.vue 改成 RelationDemo.vue 原因:缓存的判重逻辑是不区分大小写导致的.在这种情况下,vs ...

  7. 人人都会Kubernetes(二):使用KRM实现快速部署服务,并且通过域名发布

    1. 上节回顾 上一小节<人人都会Kubernetes(一):告别手写K8s yaml,运维效率提升500%>介绍了KRM的一些常用功能,并且使用KRM的DEMO环境,无需安装就可以很方便 ...

  8. 使用 Woodpecker 与 Gitea 搭建纯开源的 CI 流程|极限降本

    最近开源了一个挂机冒险游戏<模拟龙生>,有热心同学不仅帮忙做优化,还连夜在给游戏加页面,泪目.详见文末小结部分. 一.前言 大家好,这里是白泽.这篇文章是<Woodpecker CI ...

  9. Gradle 出现 Could not resolve gradle

    Gradle 在进行 sync 的时候会出现 Caused by: org.gradle.internal.resolve.ModuleVersionResolveException: Could n ...

  10. P1047 [NOIP2005 普及组] 校门外的树

    1.题目介绍 [NOIP2005 普及组] 校门外的树 题目描述 某校大门外长度为 \(l\) 的马路上有一排树,每两棵相邻的树之间的间隔都是 \(1\) 米.我们可以把马路看成一个数轴,马路的一端在 ...