Windows内核漏洞利用

来源:岁月联盟 编辑:猪蛋儿 时间:2020-01-29

分配ObjectID和ObjectType
完成之后,内核在对象(内核模式而不是用户模式)上调用TypeConfusionInitializer函数。

在对象上调用TypeConfusionInitializer
让我们来看看这个函数:

函数类型ConfusionObjectInitializer
该函数接收对象并调用对象内部存在的函数指针,下面,让我们看一下TypeConfusion.h标头文件中存在的KERNEL_TYPE_CONFUSION_OBJECT的结构(本质上是一个结构)。该标头文件包含用户模式对象以及内核模式对象的定义,这使得利用这个漏洞比利用堆栈溢出更容易。

对象原型
首先,让我们看看用户模式对象包含什么。用户模式对象是一个包含2个成员的结构:
1.对象ID;
2.对象类型。
对于内核模式对象,它也是一个包含2个成员的结构:
1.对象ID;
2.第二个成员是UNION,它本身包含:
2.1对象类型;
2.2回调(函数指针);
现在,如果你还记得,一个UNION一次可以容纳一个成员,在这里它可以是Object Type或指向由TypeConfusionInitializer函数调用的函数的指针。
当函数TriggerTypeConfusion函数无法验证第二个成员是ObjectType还是Callback时,就会发生混淆。
利用混淆情况
要利用混淆情况,我们所要做的就是发送一个结构,该结构的第二个成员是我们要从内核领域调用的函数的地址。
在漏洞已经被利用的情况下,它将成为我们的令牌窃取Shellcode的地址,并替换我们进程的令牌,因此当创建一个新进程时,将使用该令牌创建它。
但是有一个问题,HEVD附带的shellcode(TokenStealingPayloadWin7无法正常工作并导致设备崩溃)。
修改shellcode
由于函数TypeConfusionInitializer会像调用函数一样调用回调指针,因此我们需要设置函数序言和结尾,并将ret 8更改为ret。
注意:我会将shellcode函数编译为裸函数,但如果你不这样做,则可以直接使用提供的shellcode。我只是不希望编译器将额外的代码添加到我的shellcode中。
你可以点此,找到漏洞利用代码。
获得Shell
首先验证我们是否是一个普通用户。

普通用户
可以看出,我只是一个普通用户。运行漏洞利用程序后,我会拥有NT权限/系统

通过利用Type Confusion开发SYSTEM Shell
整数溢出
在这一部分中,我们将利用HackSysExtremeVulnerableDriver中的整数溢出。
什么是整数溢出?
对于那些不知道整数溢出的人,他们可能会想到整数如何溢出?实际的整数不会溢出。 CPU会将整数存储在固定大小的内存分配中。如果你熟悉C / C++编程语言或类似语言,则可能会想起数据类型以及每种数据类型具有特定的固定大小。
在大多数设备和操作系统上,char是1个字节,int是4个字节长。这意味着char数据类型可以容纳8位大小的值,范围从0到255,或者在有符号值的情况下从-128到127。整数也是如此,在int大小为4字节的设备上,它可以保存0到232 – 1之间的值(无符号值)。
现在,让我们考虑使用一个无符号整数,其最大值可以是232 – 1或0xFFFFFFFF。如果加1时会发生什么?由于所有的32位都设置为1,因此加1将使它成为33位的值,但是由于存储区只能容纳32位,因此将这32位设置为0。
在执行操作时,CPU通常将数字加载到32位寄存器中(这里说的是x86),添加1将设置Carry标志,寄存器保存值0,因为所有32位现在都是0。
现在,如果进行大小检查,则该值是否大于(例如10),则检查将失败,但是如果没有大小限制,则比较操作将返回true。
为了更详细地了解它,让我们看一下该漏洞,看看如何利用HEVD中的整数溢出漏洞来获得在Windows内核中的执行代码。
易受攻击性
现在我们已经清除了它,让我们看一下易受攻击的代码(函数IntegerOverflow.c中的TriggerIntegerOverflow)。
最初,该函数创建可容纳512个成员元素的ULONG数组(在common.h头文件中,BufferSize设置为512)。

IntegerOverflow.c中的漏洞函数
然后,内核检查缓冲区是否驻留在用户区域中,然后为我们打印一些信息,这对整数溢出很有帮助。
完成此操作后,内核将检查数据大小(以及终止符的大小,终止符为4字节)是否大于KernelBuffer的大小。如果是这,则它退出时不会在kernel-land缓冲区中复制user-land缓冲区。

大小检查
但是,如果不是这种情况,那么它将继续进行,然后将数据复制到内核缓冲区。
这里要注意的另一件事是,如果它在用户区域缓冲区中遇到BufferTerminator,它将停止复制并继续前进。因此,我们需要将BufferTerminator放在用户模式缓冲区的末尾。

上一页  [1] [2] [3]  下一页