CVE-2018-8897 调试分析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CVE-2018-8897 调试分析相关的知识,希望对你有一定的参考价值。

技术分享图片

漏洞说明

系统内核通过Mov到SS(stack segment)或Pop到SS指令进行堆栈切换操作后处理异常情况时发现了一个缺陷.在堆栈切换操作期间,处理器没有传送中断和异常,而是在堆栈切换后面的第一条指令执行完传送.一个没有特权的系统用户可以利用这个漏洞来破坏系统内核,导致拒绝服务.实际上MOV到SS会延迟一些调试异常(例如一个硬件断点)直到下条指令完成;如果跟随MOV到SS或者POP到SS后面的指令是SYSCALL 、SYSENTER、INT 3之类的指令,调试异常被捕获之后将转移到Ring0执行.

样本环境

首先从https://github.com/can1357/CVE-2018-8897 下载POC源代码,用vs2015新建立一个win32控制台工程;POC里面有个64位汇编的asm文件,使用VC++自带的汇编编译器编译Native.asm 为一个obj文件[ml64.exe/FlNative /c /Zi Native.asm],再把obj添加到工程里面[右击工程名字,点击属性;点击配置属性→链接器→输入→附加依赖项;输入obj名字],然后编译得到一个POC,编译POC一步算完了.

技术分享图片

样本是Win7x64位的,接下来搭建一个Win7x64的VMWar环境,运行poc.exe尝试触发一次,POC显示失败了.

技术分享图片

POC失败问题先暂停.关于WinDBG的内核调试,WinDBG与VMWare双机内核调试工具的配置请使用VirtualKD.如何安装使用请自行搜索.

技术分享图片

修复样本

回看一下上面的问题,样本为什么会失败?看下前面错误提示之前的代码,这段代码与KeBugCheckEx与PsGetCurrentProcess函数有关.

技术分享图片

在IDA中打开目标系统的ntoskrnl.exe文件,看KeBugCheckEx的汇编代码,代码应该搜寻0x53E0这个偏移,gs:20h是一_KPRCB结构的变量_KPCR→CurrentPrcb,这些结构一般是公开的,利用搜索引擎很容易获得.0x53EO偏移处保存的一个CONTEXT结构,也就是Prcb.Context.

技术分享图片

PsGetCurrentProcess的汇编代码,代码应该是搜寻0x70值.GS寄存器等于32位系统FS寄存器,其实这里指向内核结构_KPCR结构.0x188的偏移位置是_KTHREAD结构,0x70的偏移位置是_KTHREAD结构,也就是KThread.ApcStateFill.Process

技术分享图片

技术分享图片

PsGetCurrentProcess函数的有关实现.

技术分享图片

现在说下修复方法,找到自己系统上这两个函数数据结构的偏移,如果发现没有这两个数据结构的偏移,那么请找一个函数修复这个偏移.测试系统上Prcb.Context对应不上,需要修复偏移.

技术分享图片

打开WinDBG进行双机内核调试,输入命令dt _KPRCB查找_CONTEXT的偏移地址,测试系统偏移为0x4bd8.

技术分享图片

修改POC里面的偏移地址,然后运行POC测试

技术分享图片

在vmware里面运行到漏洞触发那里还是崩溃了?为什么呢?原因是读取GS的基址失败了.原因很有可能就是vmware不支持rdgsbase之类的指令,尝试了二进制翻译功能,仍然提示错误.怎么解决呢?请看下面.

技术分享图片

如果本机打了补丁的请卸载名字为KB4103712 与KB4103718的补丁,卸载补丁后再次运行.运行结果是直接重启.WHAT?说明已经触发了漏洞,但是例如ROP与Shellcode之类的可能还需要修复.先看一下攻击过程.

攻击过程

源码中首先检测内核页表隔离(KPTI,kernel page table isolation, Windows内核中又叫KvaShadow)是否被启用,这好像与一个INTEL漏洞相关.

技术分享图片

使用VirtualLock函数把两个函数的代码锁定在物理页面,供内核使用.

技术分享图片

得到内核基址并加载(LoadLibrary)内核ntoskrnl.exe到自身进程.

技术分享图片

分配4个内核对象(_KPCR,_KTHREAD,_KPROCESS,_KPRCB)供内核使用.

技术分享图片

内核结构_KPCR的偏移0x180处是_KPRCB结构.

技术分享图片

解析内核模块,查找一些用于ROP技术的小组件.

技术分享图片

找到内核结构_KPRCB成员Context的偏移地址,找到进程_EPROCESS的偏移地址.前面讲过,不重复讲.

填充_KPCR,_KPRCB,_KTHREAD结构体,相关成员的偏移地址在不同的系统可能会一样,请自己修复.

技术分享图片

读取堆栈段寄存器保存到变量SavedSS.

技术分享图片

创建一个线程,获得填充_KPRCB对象的成员_CONTEXT的偏移地址,并等待RtlCaptureContext函数调用获得泄漏的RSP,漏洞触发前会一直等待,实际上异常才会进入这个函数.等待第二次RtlCaptureContext被调是计算两次RSP的差异值来预测下一次RSP的值,并预测返回指针的位置,并建立RtlCaptureContext需要的上下文.第一条ROP的RETN位置放在XMM13寄存器.

技术分享图片

设置辅助线程的优先级为最高并分离当前线程与创建的辅助线程,让它们在不同的CPU上执行,接着获取了一些内核函数的地址.

技术分享图片

给线程设置两个异常,一个在SS段寄存器为读写异常,另一个写异常位于结构_KPRCB→ProcessorState(_KPROCESSOR_STATE)→SpecialRegisters(_KSPECIAL_REGISTERS)→Cr8.

技术分享图片

WinDBG输入u KeBugCheckEx,红色部分,如果偏移不一样则需要修复这个结构.

技术分享图片

开始填充rop到XMM寄存器.

技术分享图片

最后读取gs段寄存器基址,重设基址指向自己填充的_KPCR结构,然后触发漏洞,恢复GS段寄存器,并使用SS段寄存器去触发漏洞.

技术分享图片

先使用mov ss指令切换堆栈,并且会产生前面的ss调试异常,但mov ss切换后不会立即发送异常要等下一条指令执行完成后才发送;紧接着是一个int 3指令,由于前面会改变了gs段寄存器的基址,进入内核之后要使用SWAPGS指令交换gs段寄存器.

技术分享图片

可能需要修复的一些数据偏移,根据不同的系统偏移不同.

技术分享图片

小结

由于无法使用WinDBG对本机进行内核调试验证,修复POC里面的数据偏移,如果数据偏移没有修改正确就测试POC,可能会造成系统重启.快点自己动手试下吧.

原文地址:https://mozhe.cn/news/detail/285请添加链接描述

以上是关于CVE-2018-8897 调试分析的主要内容,如果未能解决你的问题,请参考以下文章

CVE-2018-8897/CVE-2018-1087:多个操作系统对MOV SS/POP SS指令处理存在缺陷预警

开发者误读芯片厂商调试文档,导致主要操作系统均出现新内核漏洞

SylixOS调试方法详解——性能分析

IDA动态调试破解EXE文件与分析APK流程

IDA动态调试破解EXE文件与分析APK流程

SylixOS 调试方法详解——静态代码分析