CVE-2018-8453从BSOD到Exploit(上)

简介: 如何构造一个触发BSOD的Poc呢,根据网上现存的分析报告我们得到了一个这样触发BSOD的思路.

0x00 :

Windows10 1703 X64 无补丁

 


0x01 :

如何构造一个触发BSODPoc,根据网上现存的分析报告我们得到了一个这样触发BSOD的思路.

 

1.创建两个窗口,一个父窗口,一个滚动条子控件

2.Hook PEB->KernelCallbackTable中的fnDword(),xxxClientAllocWindowClassExtraBytes()函数指针的指向,让其指向我们自定义的处理函数.

3.fnDword()函数内释放父类窗口

4.xxxClientAllocWindowClassExtraBytes()函数内调用NtUserSetWindowFNID()函数,并创建新的滚动条控件,使用SetCapture()函数修改滚动条捕获窗口

5.fnDword() 函数内判断发送的Message是否为0x70,如果为0x70,则向新创建的滚动条控件发送0x1F号消息

6.向 滚动条子控件(Scroll)发送WM_LBUTTONDOWN消息即可触发BSOD

 

 

虽然这样确实可以触发BSOD,但是我们根本不知道为什么这样会导致BSOD(Double Free),下面是本人关于CVE-2018-8453的分析报告

 

触发BSODPoc,完成了1 - 5的准备工作之后,便向滚动条子控件发送了一个WM_LBUTTONDOWN消息

 

 

我们知道,向滚动条子控件(Scroll)发送WM_LBUTTONDOWN,消息时,会调用到win32kfull!xxxSBTrackInit函数,该函数主要是来实现滚动条跟随鼠标移动的,该函数首先会创建一个0x80字节大小的Session Pool,用来保存tagSBTrack结构

 


接着将创建好tagSBTRACK结构的指针,写入到 tagTHREADINFO.tagSBTRACK,Windows10 1703 X64,该结构的偏移地址为tagTHREADINFO+0x278

 

需要注意的是Lock(&pSBTrack->spwndSBNotify, pwnd->spwndParent),让滚动条子控件引用父类窗口,也就是我们创建的父窗口建立引用+1,此处很重要(PS:当时写Poc时创建滚动条子控件时,属性忘记设置WS_CHILD,导致滚动条窗口的父窗口非创建的父窗口导致无法利用漏洞)

 


Win32kfull!xxxSBTrackInit函数最后会调用Win32kfull!xxxSBTrackLoop函数,来进行消息循环,消息循环函数Win32kfull!xxxDispatchMessage会使用fnDWORD函数回调R3,这时我们就知道为什么要Hook fnDWORD函数了,fnDWORD函数里判断是否是滚动条窗口发送的回调,调用DestroyWindow()函数释放主窗口

 

 

 

Win32kfull!DestoryWindow函数会调用Win32kfull!xxxFreeWindow函数来释放窗口,但是该函数经常被调用,我们可以使用条件断点来判断是否是我们要释放的窗口

 

Ba e1 win32kfull!xxxFreeWindow  .if( poi(rcx) == 释放窗口的句柄 ){}.else{g}

 

此时在rcx+0x52处下内存写入断点 rcx+0x52 处为 tagwnd.FNID,也就是导致漏洞的主角(也不能这样说,本质问题还是Kernel CallBack).

 


Win32kfull!xxxFreeWindow函数会将FNID设置为0x8000 也就是要删除的窗口标记,紧接着我们可以通过xxxClientFreeWindowClassExtraBytes函数的Kernel CallBack回调R3释放窗口扩展结构,该函数会调用user!xxxClientAllocWindowClassExtraBytes,该函数指针我们已经修改了,但释放窗口扩展空间必须要在创建窗口类时设置窗口类的大小,Poc中我设置为 wndclass.cbWndExtra = 0x8

触发xxxClientAllocWindowClassExtraBytes函数回调后,如何判断是主窗口调用的该函数呢,这里我使用了SetWindowLongA(Window, 0, (ULONG)Window); 将主窗口句柄保存在窗口扩展中.

 


MSG,保存了窗口扩展类的地址,里面保存了设置的父窗口指针,通过这个来判断是否为父窗口调用的xxxClientAllocWindowClassExtraBytes函数.

 

此时,我们创建一个新的滚动条窗口,不设置父类句柄,以及子类属性,并设置正在释放窗口WindowFNID0x2A1,本来WindowFNID0x8000,调用NtUserSetWindowFNID后为0x82A1,接着设置新的捕获窗口.

此时父窗口虽然已经调用Win32kfull!DestroyWindow释放了,但是由于滚动条子窗口还对父窗口有引用,所以并未释放主窗口的TagWnd结构,最后Win32kfull!xxxSBTrackLoop函数结束后,Win32kfull!xxxSBTrackInitpSBTrack->spwndSBNotify和链接的主窗口解引用

 

由于是最后一处引用,调用HMAssignmentUnlock时会判断被绑定Win32 Object结构的cLockObj结构是否为1,如果为1代表只有一个引用,修改指针内容后后便立刻调用函数释放该结构,此处释放的函数为(Win32kfull!DestoryWindow)

问题就在这里,由于释放窗口要调用Win32kfull!xxxFreeWindow函数,FNID为释放窗口的Flag属性,被修改为0x82A1,会再次调用fnDWORD函数回调R3,并发送为0x70Message.

 


判断FNID的内容,来决定是否调用fnDWORD

 


可以看到此处调用fnDWORD,并且发送的Message0x70

 


自定义fnDWORD函数如下

 


此时,我们向新创建的滚动条控件发送Message0x1F的消息,最终会调用到Win32kfull!xxxEndScroll函数

 


通过在Win32kfull!SetCapture设置的捕获窗口,可绕过其验证,直入到释放tagSBTrack结构

 


此时线程内的tagSBTrack结构已经被释放了,接着回到Win32kfull!xxxSBTrackInit执行代码.

 


因为tagSBTrack结构已经在Win32kfull!xxxEndScroll函数被释放了,但是Win32kfull!xxxSBTrackInit函数并不知道,再次释放该内存导致Double Free!

相关文章
|
2天前
|
安全 Shell Windows
Metasploit -- CVE-2019-0708漏洞检测及利用
Metasploit -- CVE-2019-0708漏洞检测及利用
19 0
|
8月前
|
安全 Ubuntu Linux
CVE-2021-4034 pkexec提权漏洞
Linux Polkit 的 pkexec程序中发现了一个本地权限提升漏洞。pkexec应用程序是一个 setuid 工具,旨在允许非特权用户根据预定义的策略以特权用户身份运行命令。
170 1
|
8月前
|
安全 Ubuntu Linux
CVE-2016-5195 DirtyCow 脏牛提权
脏牛(Dirty COW,编号:CVE-2016-5195)是2016年10月18日被曝出的存在于Linux内核中的一款0day漏洞。因为此漏洞是在Linux内核的内存子系统在处理写时拷贝(Copy-on-Write)时发生的,而又给Linux内核的使用带来烦恼,所以将其命名为"Dirty COW"。
160 1
|
12月前
|
安全 Windows
CVE-2018-8453从BSOD到Exploit(下)
非常感谢A-Team发表EXPLOIT编写的思路,阅览后受益匪浅,因此本文不再阐述漏洞细节,专注于EXPLOIT编写.
|
12月前
|
安全 Shell
CVE-2014-6271“破壳”
CVE-2014-6271广泛存在与GNU Bash 版本小于等于4.3的*inux的系统之中
|
12月前
|
安全 Shell 数据安全/隐私保护
CVE-2019-15107 Webmin RCE漏洞复现
环境搭建: 进入镜像目录
251 0
|
安全 Oracle 关系型数据库
CVE-2020-2551
2020年1月15日,Oracle发布了一系列的安全补丁,其中Oracle WebLogic Server产品有高危漏洞,漏洞编号CVE-2020-2551,CVSS评分9.8分,漏洞利用难度低,可基于IIOP协议执行远程代码。
112 0
CVE-2020-2551
|
安全 Shell 数据库
CVE-1472
0x00 CVE-1472复现
CVE-1472
|
安全 Java 应用服务中间件
Ghostcat(CVE-2020-1938)
Ghostcat(CVE-2020-1938)
Ghostcat(CVE-2020-1938)
|
安全 网络协议 前端开发

热门文章

最新文章