内核漏洞学习—熟悉HEVD
一直以来内核漏洞安全给很多人的印象就是:难,枯燥。但是内核安全是否掌握是衡量一个系统安全工程师水平的标准之一,也是安全从业人员都应该掌握的基本功。本文通过详细的实例带领读者走进内核安全的大门。难度系数:四颗星
原文地址:https://hshrzd.wordpress.com/2017/06/05/starting-with-windows-kernel-exploitation-part-2/
本文默认读者已经配置好了基本实验环境,因为环境配置网络上有大量详细资源,在此编者不再单独成文介绍环境。此文章供参考:https://hshrzd.wordpress.com/201 … setting-up-the-lab/
1.本文所使用的环境:
§ 环境配置 the previous part
§ HackSys Extreme Vulnerable Driver(HEVD) – prebuild version + the source code
§ DebugView (from SysInternals Suite)
§ Visual Studio 2012 (版本随意)
安装并测试HEVD首先,我将展示如何安装HEVD。我们将会配置Debugee和调试器,以查看调试字符串和HEVD的符号。我们也会用一些专用的漏洞来玩。
油管视频(我也很无奈啊~):
查看调试字符串HEVD和一些专门的行为利用了大量的信息作为调试字符串。我们可以从调试器(使用WinDbg)和被调试程序(使用调试器)来观察它们。
安装HEVD之前,我们将设着一些内容来查看驱动程序初始化期间打印的字符串。
在调试器上:为了获得kd标识,我们需要中断调试器的执行(WinDbg->Debug->Break)。然后,我们可以通过命令打印调试字符串:
ed nt!Kd_Default_Mask 8
之后,我们可以通过执行命令进一步运行调试器:
g
Warning: Enabling this slows down the Debugee. So, whenever possible, try to watch DebugStrings locally (on the Debugee only).
这个警告大概是说这个命令会减慢调试器的速度,所以优先选择在本地仅在被调试程序上观察调试字符。
在被调试程序上:
我们需要以管理员身份运行DebugView。然后我们从菜单中依次选择:
Capture->Capture Kernel
安装驱动程序首先,我们将在被调试方(靶机)上下载预构建包(驱动程序+exploit)安装并且进行测试。我们可以在GitHub上找到HackSysTem,https://github.com/hacksysteam/HackSy**tremeVulnerableDriver/releases
这个包包含两个易受攻击的版本的驱动程序,我们将选一个比较脆皮的进行构建(
32位i386)
我们选择自启动。然后我们点击[RegisterService]成功后点击[StartService]
我们应该可以在调试方的WinDbg和靶机的WbgView上看到打印出的HEVD。
添加标识符HEVD的预编译包带有符号(sdb文件),我们还可以将其添加到调试器中。首先,我们通过发送一个中断信号来停止调试器,并查看所有已加载的模块。
我们可以设置一个过滤器来找到HEVD模块
lm m H*
我们可以看到它没有任何标识符,我们可以很容易的将其固定。首先,打开:
!sym_noisy
–用来打印所有和WinDbg引用路径的信息以找到标识符。然后试着重载这些标识符:
.reload
再试着再次提引用。你将看到路径,我们可以复制pdb文件。在将pdb文件移动到调试器机器上的适当位置之后,再次重载标识符。你可以试着打印HEVD的所有功能来进行测试。
x HEVD!*利用测试同一个包中还包含了一组专用的漏洞。我们可以通过执行一个适当的命令来运行它们。我们来尝试进行一些部署,并执行cmd.exe
池溢出利用部署:
如果利用成功,请求的应用程序将会被部署到更高的权限。
通过命令:
whoami
我们可以确定,它的权限升高。
与此同时,我们可以调试机上看到由expolit打印的调试字符串:
所有的攻击,除了双重取回,都应该在一个核心上运行良好。如果我们想要利用这个,则需要在调试器机器上启用两个核心。
警告:有些exp并不是100%可靠的,我们在部署它们之后可能会遇到系统崩溃。别担心,一切不以格盘为目的的崩溃信息都是纸老虎。
与驱动进行一场扎心的交流就像在用户层的情况下一样,在内核方面的开发利用中,从寻找点开始,我们可以为程序提供一个输入。然后,我们需要找到能够破坏执行的输入(与用户层相反——在内核层面上,崩溃将直接导致蓝屏!)最后,我们将尝试以一种控制脆弱程序执行的方式来构造输入。
为了与来自用户模式的驱动程序进行通信,我们将发送一些IOCTL-输入-输出控制。IOCTL允许我们从用户向驱动程序发送一些内容到缓冲区。这是我们可以尝试利用的点。
HEVD包含各种各样的漏洞的演示。每一个都可以使用不同的IOCTL触发,并被所提供的缓冲区所利用。有些(但不是全部)会导致系统在触发时崩溃。
查找设备名称和IOCTL
在我们尝试与设备连接之前,我们需要知道两件事:
驱动程序创建的设备(如果它不创建任何东西,我们将无法进行通信)
驱动程序接受的IOCTL(输入-输出控制)列表
HEVD是开源的,因此我们可以直接从源代码中读取所有必需的数据。在黑盒测试过程中,我们可能要通过逆向驱动程序来读取所需数据。
让我们来看看HEVD创建一个设备的代码片段。
上面提到了这个设备的名称。
现在,我们通过从IRP数组来找IOCTL列表
连接到IRP_MJ_DEVICE_CONTOL的函数将会分配IOCTL发送给驱动程序。所以,我们需要看一下这个函数。
这里有一个switch循环,调用一个特定的处理IOCTL的函数,我们可以对这些switch的case进行转换以获取我们所需要的IOCTL列表。常量的值在header中被忽视。
编写一个客户端应用程序
好的,我们现在已经搞到了所有需要用到的数据,我们可以用我们自己的程序与驱动程序进行通信。我们可以把它们放在头文件中,也就是:hevd_constants.h
#pragma once
#include <windows.h>
const char kDevName[] = "\\\\.\\HackSy**tremeVulnerableDriver";
#define HACKSYS_EVD_IOCTL_STACK_OVERFLOW CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HACKSYS_EVD_IOCTL_STACK_OVERFLOW_GS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HACKSYS_EVD_IOCTL_ARBITRARY_OVERWRITE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HACKSYS_EVD_IOCTL_POOL_OVERFLOW CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HACKSYS_EVD_IOCTL_ALLOCATE_UAF_OBJECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HACKSYS_EVD_IOCTL_USE_UAF_OBJECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HACKSYS_EVD_IOCTL_FREE_UAF_OBJECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HACKSYS_EVD_IOCTL_ALLOCATE_FAKE_OBJECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HACKSYS_EVD_IOCTL_TYPE_CONFUSION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HACKSYS_EVD_IOCTL_INTEGER_OVERFLOW CTL_CODE(FILE_DEVICE_UNKNOWN, 0x809, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HACKSYS_EVD_IOCTL_NULL_POINTER_DEREFERENCE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80A, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HACKSYS_EVD_IOCTL_UNINITIALIZED_STACK_VARIABLE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80B, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HACKSYS_EVD_IOCTL_UNINITIALIZED_HEAP_VARIABLE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80C, METHOD_NEITHER, FILE_ANY_ACCESS)
#define HACKSYS_EVD_IOCTL_DOUBLE_FETCH CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80D, METHOD_NEITHER, FILE_ANY_ACCESS)
IOCTL的数目是由一个标准的Windows头文件winioctl.h中定义的宏所创建的。
如果你引用了windows.h文件,上面的宏将被自动添加。现在,我们不需要操心特定常量的含义——我们只需要使用已定义的元素就可以了。
因此,我们准备编写一个简单的用户层应用程序,该应用程序将与驱动程序进行对话。首先,我们使用函数CreateFile打开设备。然后,我们可以使用DeviceIoControl.来发送IOCTL。
下面你可以看到一个小例子。这个应用程序将STACK_OVERFLOWIOCTL 发送给驱动程序: send_ioctl.cpp
#include <stdio.h>
#include <windows.h>
#define HACKSYS_EVD_IOCTL_STACK_OVERFLOW CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS)
const char kDevName[] = "\\\\.\\HackSy**tremeVulnerableDriver";
HANDLE open_device(const char* device_name)
{
HANDLE device = CreateFileA(device_name,
GENERIC_READ | GENERIC_WRITE,
NULL,
NULL,
OPEN_EXISTING,
NULL,
NULL
);
return device;
}
void close_device(HANDLE device)
{
CloseHandle(device);
}
BOOL send_ioctl(HANDLE device, DWORD ioctl_code)
{
//prepare input buffer:
DWORD bufSize = 0x4;
BYTE* inBuffer = (BYTE*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufSize);
//fill the buffer with some content:
RtlFillMemory(inBuffer, bufSize, 'A');
DWORD size_returned = 0;
BOOL is_ok = DeviceIoControl(device,
ioctl_code,
inBuffer,
bufSize,
NULL, //outBuffer -> None
0, //outBuffer size -> 0
&size_returned,
NULL
);
//release the input bufffer:
HeapFree(GetProcessHeap(), 0, (LPVOID)inBuffer);
return is_ok;
}
int main()
{
HANDLE dev = open_device(kDevName);
if (dev == INVALID_HANDLE_VALUE) {
printf("Failed!\n");
system("pause");
return -1;
}
send_ioctl(dev, HACKSYS_EVD_IOCTL_STACK_OVERFLOW);
close_device(dev);
system("pause");
return 0;
}
尝试编译这个程序并将其部署到靶机上。启动DebugView观察由驱动程序打印的调试字符串。
你可能看到类似输出:
你懂得~
以下为作者福利:
练习,让我们一起搞波事情~
我在HEVD创建了一个小客户端,你可以在这看到源代码:
https://github.com/hasherezade/wke_exercises/tree/master/task1
编译后的32位二进制文件: here.
试着玩各种不同的IOCTL,直到你成功。因为Debugee在调试器的控制下运行,你不会出现蓝幕——相反,WinDbg会被触发。试着对每一个案例做一个简短的崩溃分析。从打印信息开始:
!analyze -v其他一些有用的命令:
k - stack trace
kb - stack trace with parameters
r - registers
dd [address]- display data as DWORD starting from the address
要了解更多,请参阅“WinDbg”帮助文件:
.hh
在我们的示例应用程序中,用户缓冲区填满了“A”-ASCII 0×41
https://github.com/hasherezade/wke_exercises/blob/master/task1/src/main.cpp#L34
RtlFillMemory(inBuffer, bufSize, 'A');
油管示例:
Example #1
https://www.youtube.com/watch?v=lw7vMrkeTpY
Example #2
https://www.youtube.com/watch?v=YV0IqXEUf5s
请注意,触发相同的漏洞可能会给您带来不同的输出,这取决于崩溃的直接原因,这与溢出的大小、内存的当前布局等有关。
内核漏洞学习—熟悉HEVD的更多相关文章
- 【翻译】 Windows 内核漏洞学习—空指针解引用
Windows Kernel Exploitation – NullPointer Dereference 原文地址:https://osandamalith.com/2017/06/22/windo ...
- Windows 内核漏洞学习—空指针解引用
原标题:Windows Kernel Exploitation – NullPointer Dereference 原文地址:https://osandamalith.com/2017/06/22/w ...
- Linux kernel pwn notes(内核漏洞利用学习)
前言 对这段时间学习的 linux 内核中的一些简单的利用技术做一个记录,如有差错,请见谅. 相关的文件 https://gitee.com/hac425/kernel_ctf 相关引用已在文中进行了 ...
- CVE-2014-0038内核漏洞原理与本地提权利用代码实现分析 作者:seteuid0
关键字:CVE-2014-0038,内核漏洞,POC,利用代码,本地提权,提权,exploit,cve analysis, privilege escalation, cve, kernel vuln ...
- 初识linux内核漏洞利用
0x00 简介 之前只接触过应用层的漏洞利用, 这次第一次接触到内核层次的,小结一下. 0x01 概况 这次接触到的,是吾爱破解挑战赛里的一个题,给了一个有问题的驱动程序,要求在ubuntu 14.0 ...
- PWN二进制漏洞学习指南
目录 PWN二进制漏洞学习指南 前言 前置技能 PWN概念 概述 发音 术语 PWN环境搭建 PWN知识学习途径 常见漏洞 安全机制 PWN技巧 PWN相关资源博客 Pwn菜鸡小分队 PWN二进制漏洞 ...
- Linux内核ROP学习
0x00 前言 1.SMEP(Supervisor Mode Execution Protection):一种减缓内核利用的cpu策略,禁止内核态到用户态内存页的代码执行(32位的addresses ...
- XSS漏洞学习笔记
XSS漏洞学习 简介 xss漏洞,英文名为cross site scripting. xss最大的特点就是能注入恶意的代码到用户浏览器的网页上,从而达到劫持用户会话的目的. 说白了就是想尽办法让你加载 ...
- Fibratus:一款功能强大的Windows内核漏洞利用和跟踪工具
今天给大家介绍的是一款名叫Fibratus的开源工具,广大研究人员可以使用这款功能强大的工具来进行Windows内核漏洞利用.挖掘与跟踪. Fibratus这款工具能够捕捉到绝大多数的Windows内 ...
随机推荐
- VMware下的Linux系统中Windows的共享目录,不支持创建软连接
[问题] 在编译VMware下的Linux系统对从Windows中共享过来的文件,进行编译的时候,遇到: ln: creating symbolic link XXXXXX : Operation ...
- [精彩] 关于DB2的内存分配
这两天在看DB2的内存管理的内容,看的很是模糊,有以下问题不明白,请教 是不是数据库管理器的共享内存就是DB2能够使用的最大内容呢,然后数据库全局内存从管理器内存那里获得分配的内存,然后应用程序全局内 ...
- 2018.06.29 NOIP模拟 旅馆(线段树)
旅馆 [问题描述] OIEROIEROIER 们最近的旅游计划,是到长春净月潭,享受那里的湖光山色,以及明 媚的阳光.你作为整个旅游的策划者和负责人,选择在潭边的一家著名的旅馆住 宿.这个巨大的旅馆一 ...
- 2018.09.10 bzoj1597: [Usaco2008 Mar]土地购买(斜率优化dp)
传送门 终究还是通宵了啊... 这是一道简单的斜率优化dp. 先对所有土地排序,显然如果有严格小于的两块土地不用考虑小的一块. 于是剩下的土地有一条边单增,另外一条单减. 我们假设a[i]是单减的,b ...
- ssh到远程执行命令并返回
假设有三台机器 host1,host2,host3,host1能免密登录其他两台.要在第一台的机器里面写一个脚本分别删除每台机器的/root/test.txt rm -rf /root/test.tx ...
- 命令行生成war包
1.找到自己的代码位置 2.进入cmd界面 3.进入对应的目录 4.执行命令 5.就会开始自动打包 6.在文件夹下生成对应的war包
- Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: Unable t
spring与hibernate整合然后出现如下错误: org.springframework.beans.factory.BeanCreationException: Error creating ...
- webuploader php上传视频
webuploader 上传大视频文件 在网上找了一个,自己重新组合了下,两个主要的文件,再加上官方下载的文件.其中有几个重要的点. 1.上传存放视频目录为了测试 直接777 2.fileupload ...
- (最小生成树)Constructing Roads -- poj -- 2421
链接: http://poj.org/problem?id=2421 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 2113 ...
- Resharper 修改命名空间
1. 使用Reshared 右键->Refactor->Rename 修改所有文件的命名空间(鼠标移动到对应类的命名空间) 2.修改类库中的命名空间 包括程序集信息 右键->属性 3 ...