自检代码中trustmanager漏洞_Windows内核漏洞利用教程
堆栈溢出漏洞
首先,我们将从HackSysExtremeVulnerableDriver中的vanilla栈溢出漏洞开始讲起。
当向堆栈上的缓冲区存放的数据超出其存储容量时(例如,向16字节缓冲区(这里的缓冲区可以是字符数组或类似对象)中存放20个字节时),多出来的数据将会写入附近的内存中,从而覆盖或破坏堆栈。
这里的核心思想是控制溢出过程,以便可以覆盖保存在堆栈中的返回地址,并在执行当前(易受攻击的)函数后,将返回我们的覆盖值,其中存放的是相应的shellcode。
注意:在执行我们的shellcode之后,代码执行流程必须回到相应的应用程序,就这里来说,是交还给内核,否则,就会破坏应用程序。通常情况下,应用程序崩溃后,我们可以重新启动它,但是如果内核内存发生损坏的话,内核发出kernel panic,导致蓝屏死机,这是我们最不想要的。
为了解决这个问题,我们需要恢复执行路径,以便在执行shellcode之后,将执行流程返回到执行易受攻击的函数后面相应的函数。
含有堆栈溢出漏洞的代码
现在,我们已经了解了攻击思路,下面,让我们考察一下易受攻击的代码(位于StackOverflow.c文件中的函数TriggerStackOverflow)。首先,该函数会创建一个ULONG型数组,它可以容纳512个成员元素(在common.h头文件中,BufferSize被设置为512)。
然后,内核会检查缓冲区是否驻留在用户空间中,并在非分页池中为其分配内存。
完成上述操作后,内核会将数据从用户空间的缓冲区复制到内核空间的KernelBuffer中,实际上,它本质上就是一个ULONG型数组。
堆栈溢出
请大家注意RtlCopyMemory(它本质上就是memcpy)函数的第三个参数Size,它是用户空间缓冲区的长度,而非内核空间缓冲区的长度。这里就是发生缓冲区溢出的关键点。
漏洞验证
现在,为了验证这里是否为该漏洞的实际位置,我们将编写一个函数,让它调用函数StackOverflowIOCTLHandler的IOCTL。需要说明的是,具体IOCTL代码请参见exploit/common.h文件。
注意:我们本可以从编译后的驱动程序本身获得IOCTL代码,但是既然我们有这样的优势,为什么不用呢?
什么是IOCTL代码?
“I/O控制码(IOCTL)用于用户模式应用程序和驱动程序之间的通信,或用于堆栈中驱动程序之间的内部通信。I/O控制代码可以通过IRP进行发送。”——Microsoft.com
基本上,如果驱动程序具有相应的IOCTL代码,就可以直接在驱动程序中调用内核函数。
要使用IOCTL代码,我们可以借助于DeviceIoControl函数,该函数的详细说明请参阅这里。
DeviceIoControl函数的原型是:
我使用C++语言编写了一个函数,它可以通过DeviceIoControl来调用StackOverflowIoctlHandler,后者又会调用TriggerStackOverflow——一个含有堆栈溢出漏洞的函数。
我们知道该缓冲区是长度为512个ULONG型元素,所以,我们可以再附加由me tasploit框架中的pattern_create.rb生成的100字节模式。
最后,将这个缓冲区的内容发送到HEVD,看看会发生什么情况。
注意:这个函数位于头文件StackOverflow.h中,并且由main函数来调用它。完整的代码,请访问我的代码库。
在Win7系统上编译并执行二进制文件后,我们可以在WinDbg中看到:
如您所见,这里存在访问违例,EIP指向了31624130。
利用me tasploit的pattern_offset.rb的模式之后,我们会发现其偏移量为32。下面,我们开始利用这个漏洞。
堆栈溢出漏洞的利用方法
为了利用这个漏洞,我们只需要用HEVD中提供的TokenStealingPayloadWin7 shellcode覆盖保存的返回地址,就可以了。
注意:为了防止崩溃,可能需要对shellcode稍加修改,这一个任务留作作业。
获取Shell
让我们首先检查当前身份是否为普通用户。
可以看出,当前身份只是普通用户。
在运行漏洞利用代码之后,转身变为ntauthority/system用户。
参考资料
- HackSysTeam
- FuzzySecurity
类型混淆漏洞
什么是类型混淆漏洞?
类型混淆是这样一种漏洞,即应用程序没有验证对象的类型(函数、数据类型等),就直接按预期类型对其进行处理,所以,当传递给程序的其实是其他类型的对象时,就会出现这种类型的安全漏洞。
含有类型混淆漏洞的代码
现在,我们已经了解了类型混淆漏洞的概念,下面,让我们开始考察含有这种类型的漏洞的代码(位于typeconfusion.c中的函数triggerTypeConfusion中)。
首先,内核会检查缓冲区是否位于用户空间中,然后,在非分页池中为其分配内存空间。完成上述操作后,内核将objectID从用户空间缓冲区赋值给内核空间缓冲区,并对对象类型执行相同的操作。
之后,内核会对对象调用TypeConfusionInitializer函数(内核模式而非用户模式)。
让我们考察一下这个函数:
这个函数首先接收对象,并调用对象中的函数指针。
让我们看看kernel_type_confusion_object的结构(本质上是一个结构体),它位于typeconfusion.h头文件中。这个头文件保存了用户空间对象和内核空间对象的定义,这使得该漏洞的利用方法要比堆栈溢出漏洞的利用方法更容易一些。
首先,让我们看看用户模式对象中所包含的内容。实际上,这个用户模式对象是一个包含2个成员的结构体,这些成员为:
l 对象ID
l 对象类型
在内核模式对象的情况下,它也是一个包含2个成员的结构:
l 对象ID
l 第二个成员是UNION,可以保存:
1. 对象类型
- 回调函数(函数指针)
我们知道UNION变量一次只能存放一个成员,这里它可以是一个object Type,也可以是一个指向TypeConfusionInitializer函数调用的函数的指针。
当函数TriggerTypeConfusion函数没有验证第二个成员是objectType还是Callback时,就会触发类型混淆漏洞。
类型混淆漏洞的利用方法
为了利用这种类型的漏洞,只需传递一个结构体,并且让该结构体的第二个成员为我们想要从内核空间调用的函数的地址即可。
就这里来说,该结构体的第二个成员存放的是令牌窃取Shellcode代码的地址,以替换我们的进程的令牌,这样,当创建新进程时,将使用该令牌。
但是,需要注意的是,这里需要使用HEVD提供的shellcode(TokenStealingPayloadWin7无法正常使用,并且会导致系统崩溃)。
修改shellcode
由于函数TypeConfusionInitializer会调用Callback指针,既然它是一个函数,所以,我们需要设置函数的prologue和epilogue,并将ret 8改为ret。
注意:这里我将shellcode函数编译为裸函数,如果您不这样做的活,也可以直接使用提供的shellcode。之所以这么做,只是不喜欢编译器将额外的代码添加到shellcode代码中而已。
我的漏洞利用代码可以从这里下载。
获得Shell
让我们首先检查当前身份是否为普通用户。
可以看出,当前身份只是普通用户。
运行漏洞利用代码后,我们将华丽变身为ntauthority/system用户。
整数溢出
下面,我们开始介绍如何利用HacksysExtremeVulnerableDriver中的整数溢出漏洞。
什么是整数溢出漏洞?
对于不了解整数溢出的人来说,听到这个名称的时候可能会非常困惑——整数怎么会溢出呢?
实际的整数是不会溢出。CPU会将整数存储在固定长度的内存空间中(注意,这里我们不会讨论堆或类似的内容)。如果您熟悉C/C++之类的编程语言的话,您可能还记得各种数据类型都具有固定的长度。
在大多数机器和操作系统上,字符变量长度为1字节,整型变量的长度为4字节。这意味着char数据类型可以保存长度为8比特的值,取值范围从0到255,如果是带符号的值,则取值范围为-128到127。整型变量也是如此,在整型变量长度为4字节的机器上,可以保存0到2的32次方-1之间的值(无符号值)。
现在,让我们考虑使用一个最大值为2的32次方-1或0xFFFFFFF的无符号整型变量。取最大值后,如果再加1,会发生什么情况呢?由于所有32位上的值均为1,因此,加1将使其变为一个长度为33位的值,但由于存储器只能容纳32位,因此这32位上的值将被设为0。
在执行上面的操作时,CPU通常会将数字加载到32位寄存器(此处指x86)中,加1时会设置进位标志,而寄存器各位的值为0,因为现在所有32位上的值都为0。
现在,如果进行长度检查,查看值的长度是否大于指定的值,比如10,则该检查将返回fail,但如果不存在长度限制,则比较操作将返回true。
为了加深理解,让我们来考察一下具体的漏洞代码:如何利用HEVD中的整数溢出漏洞来获得Windows内核中的代码执行权限。
含有整数溢出漏洞的代码
现在已经了解了整数溢出漏洞的相关概念,接下来,我们来分析一下含有该漏洞的代码(该漏洞位于IntegerOverflow.c中的函数TriggerIntegerOverflow中)。
首先,该函数会创建一个ULONG型数组,该数组可以存放512个成员元素(在common.h头文件中,BufferSize被设置为512)。
然后,内核会检查缓冲区是否位于用户空间中,然后,它还会为我们打印一些信息。这些信息对于我们来说非常有帮助。
完成上述操作后,内核会检查数据的长度(以及终结符的长度,即4个字节)是否大于KernelBuffer的长度。如果是的话,则退出,并且不会将用户空间中的缓冲区内容拷贝到内核空间的相应缓冲区中。
但是,如果情况并非如此,则继续进行,并将数据复制到内核缓冲区中。
这里要注意的另一件事是,如果它在用户区缓冲区中遇到BufferTerminator,就会停止复制,并继续执行后面的代码。因此,我们需要将BufferTerminator放在用户模式缓冲区的末尾。
整数溢出
IntegerOverflow.c的第100行代码的问题在于,如果我们提供的size参数为0xFFFFFFFC,然后再加上BufferTerminator的长度(这里是4个字节),则有效长度变为:0xFFFFFFFC+ 4 = 0x00000000,即大于KernelBuffer的长度,但是,由于我们通过了数据长度的检查,所以,能够将该缓冲区内容复制到内核空间。
漏洞验证
现在,为了验证这个漏洞,我们将把缓冲区内容发送到HEVD,但是将0xFFFFFFFC作为缓冲区的长度进行传递。现在,我们不用设置一个巨大的缓冲区来令内核崩溃,相反,只需发送一个小型的缓冲区并确认漏洞即可。
由于我们知道缓冲区长度为512个ULONG型元素,因此,我们可以发送这么长的数据,并查看内核的反应。
注意:这里的重点是DeviceIoControl的第4个参数,而不是实际数据。
最后,将该缓冲区内容发送到HEVD,看看到底会发生什么情况。
正如您看到的那样,UserBufferSize的值为0xFFFFFFFC,但我们仍设法绕过了长度的有效性检查并触发了整数溢出漏洞。
我们发现,通过设置0xFFFFFFFC,我们可以绕过长度检查,接下来要做的事情,就是在UserBuffer之后放置一个模式(一个唯一无二的模式),然后放置终结符,以找到保存的返回指针。
如果您不清楚该如何操作,请阅读本文的前面部分,那里有具体的介绍。
下面,我们开始介绍如何利用这个漏洞。
整数溢出的利用方法
下面,我们会通过HEVD提供的TokenStealingPayloadWin7 shellcode来覆盖保存的返回地址,这样,我们就大功告成了。
注意:为了避免崩溃,需要对shellcode稍作修改,这项任务留作课后作业。
获得shell
下面,首先来检查一下当前的身份是否为普通用户。
可以看出,当前身份只是普通用户。
运行我们的漏洞代码之后,我们的身份已经变为ntauthority/system。
完整的代码,大家可以从作者的代码库中下载。
参考资料
- HackSysTeam
- FuzzySecurity
自检代码中trustmanager漏洞_Windows内核漏洞利用教程相关推荐
- 自检代码中trustmanager漏洞_2020-11微软漏洞通告
微软官方发布了11月的安全更新.本月更新公布了112个漏洞,包含35个远程代码执行漏洞,37个特权提升漏洞,19个信息泄露漏洞以及10个身份假冒漏洞,其中17个漏洞级别为"Critical& ...
- 自检代码中trustmanager漏洞_通达OA远程代码执行漏洞通告
报告编号:B6-2020-031801
- 安全漏洞一内核漏洞利用
漏洞描述 Windows 事件跟踪 (ETW) 机制允许记录内核或应用程序定义的事件以进行调试. 开发人员能够启动和停止事件跟踪会话,检测应用程序以提供跟踪事件,并通过调用 ETW 用户模式 Wind ...
- 怎么挖linux内核的漏洞,linux内核漏洞分析实战看看专家是怎么一步步...-卓优商学院问答...
推荐回答 Linux内核调试方法kdb:只能在汇编代码级进行调试:优点是不需要两台机器进行调试.gdb:在调试模块时缺少一些至关重要的功能,它可用来查看内核的运行情况,包括反汇编内核函数.kgdb:能 ...
- java word转html 空指针_Windows 内核漏洞学习—空指针解引用
原标题:Windows Kernel Exploitation – NullPointer Dereference
- android 大量代码中 grep 太慢,ReactNative 性能 - 闪电教程JSRUN
使用React Native替代基于WebView的框架来开发App的一个强有力的理由,就是为了使App可以达到每秒60帧(足够流畅),并且能有类似原生App的外观和手感.因此我们也尽可能地优化Rea ...
- Android 7.0 插卡后APN信息的加载流程、UI界面编辑APN的流程及Android中APN配置相关的漏洞
终端中有一个apns-config.xml文件,负责定义各个运营商规定的默认APN参数. 开机后,终端启动Phone进程时,会加载运行在Phone进程中的TelephonyProvider. Tele ...
- linux内核竞争条件漏洞,Linux内核竞争条件漏洞-导致远程代码执行
原标题: Linux内核竞争条件漏洞-导致远程代码执行 导读*本文中涉及到的相关漏洞已报送厂商并得到修复,本文仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担. 运行了Linux发行版 ...
- 在windows 服务中 调打印_Windows打印后台处理程序漏洞(CVE20201048)
2020年5月,Microsoft修补了CVE-2020-1048,该漏洞是Windows后台打印程序服务中的特权升级漏洞,该漏洞由SafeBreach Labs的Peleg Hadar和Tomer ...
最新文章
- 广告域名审核之后跳转技术:点击域名A页面iframe框架下的链接,域名A跳转到域名B...
- 20151024学习内容:安全相关
- MATLAB实战系列(一)-二维路径规划算法续集-图像边缘提取(附代码)
- Implementation:Bellman-ford
- Mybatis自动生成实体类等代码
- Nessus扫描器的使用
- mysql读写分离的含义_MySQL 主从复制与读写分离概念及架构分析
- 《Algorithms》Comparable 实现选择排序
- 敏捷开发般若敏捷系列之七:重新认识敏捷与CMMI
- 使用wordpress分页函数paginate_links
- appcan双击返回退出系统
- 数据治理需要注意什么问题
- PAT (Advanced Level) 1051. Pop Sequence (25)
- 通信原理学习笔记4:信道编码、分组码、卷积码、现代信道编码(Turbo码、LDPC码、Polar码)
- Java题目内容: 你的程序要读入一系列正整数数据,输入-1表示输入结束,-1本身不是输入的数据。程序输出读到的数据中的奇数和偶数的个数。
- 大学生计算机考证时间表
- 微信公众号(服务号)申请时候需要补充的资料
- 电脑老是弹出vrvedp_m_vrvedp_m.exe是什么进程?是病毒吗?vrvedp,vrvedp.exe,,,,,,,
- 【Http请求工具类】
- 程序人生 - 桂林西瓜霜含片 西瓜霜清咽含片
热门文章
- android开发:input类型
- 修改本机域名服务器为Google Public DNS或者OpenDNS
- mfc远程连接mysql数据库连接_MFC连接mysql数据库(十分钟搞定)
- java foreach顺序_Java中的LongStream forEachOrdered()方法
- unity android适配,unity实战 手机屏幕适配
- php控制器,php模型和控制器之间交互
- 三八妇女节PSD分层海报,来啦!
- UI设计师经常去的提升欣赏水平的社区网站
- 免扣(抠)PNG格式图片,让你告别抠图之痛!
- 合成创意海报灵感|比技术更重要的是创意!