CVE-2018-8120 分析
CVE-2018-8120 分析
1、实验环境
1.1、操作系统
- windows 7 sp1 x86 未打补丁 磁力链接
 
1.2、用到的分析工具
2、假如
2.1、我想提权
 我想使我编写的一个普通的R3的程序一运行就获得SYSTEM最高权限。一个常用的办法是: 替换当前进程_EPROCESS结构的Token成员的值为system进程的_EPROESS的Token成员值。一旦替换成功,那么从替换成功的那一刻开始一直到程序退出这段时间里,程序所做的一切操作都是以SYSTEM最高权限执行的。
 但是,要完成这项工作在R3层面上直接上shellcode是不行的,因为所有进程的EPROCESS结构都是位于内核空间中的,如果要对其进行读写则代码必须运行在内核空间中才行,用户空间中的代码如果对其进行读写则会产生保护性异常。
 所以问题就来了,怎样让我们的替换Token的shellcode(这段shellcode是怎么写的在后面会有详细解释)运行在内核空间中呢?
2.2、 有一个处于内核空间,极少被调用的函数
2.2.1、快速系统调用简介
 虽然用户程序不能直接访问内核空间,但是用户程序可以通过调用系统服务来间接访问系统空间中的数据或间接调用执行系统空间中的代码。当调用系统服务时,调用线程会从用户模式切换到内核模式,调用结束后再返回到用户模式,也就是所谓的模式切换,有时也被称为上下文切换(Context Switch)。模式切换是通过软中断或专门的快速系统调用(Fast System Call)指令来实现。
	下面我来简要介绍下Windows 7 X86 sp1 是如何通过SYSENTER指令实现快速系统调用的。举一个简单的例子。调用ReadFile()这个函数的流程为下图所示:

        在windows 7 sp1 x86中使用微软的亲儿子WINDBG(本地内核调试模式,具体设置百度,PS:设置完后需使用管理员权限启动WINDBG否则使用BCDEDIT设置重启后依然不能启用本地内核调试模式)查看NTDLL.DLL中导出的NtReadFile()函数的反汇编:
lkd> uf ntdll!NtReadFile
ntdll!ZwReadFile:
775762b8 b811010000      mov     eax,111h ;NtReadFile的系统服务号码为 0x111
775762bd ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
775762c2 ff12            call    dword ptr [edx]
775762c4 c22400          ret     24h
那么当第二句 mov     edx,offset SharedUserData!SystemCallStub  执行后,edx 值为0x7ffe0300。因为第三句是 call dword ptr [edx] 所以继续查看地址SharedUserData!SystemCallStub 处的值
lkd> dd SharedUserData!SystemCallStub
7ffe0300  775770b0 775770b4 00000000 00000000
	继续执行call    dword ptr [edx] 则跳转到地址0x775770b0 处执行,继续使用神器反汇编
lkd> uf 775770b0
ntdll!KiFastSystemCall:
775770b0 8bd4            mov     edx,esp
775770b2 0f34            sysenter
775770b4 c3              ret
	当执行sysenter指令后,进入内核模式,调用KisystemService()函数,该函数会根据服务ID从系统服务分发表(System Service Dispatch Table)中找到要调用的服务函数的函数地址和参数描述,然后调用内核中正真的NtReadFile()函数。那个服务ID就是进入SharedUserData!SystemCallStub之前那个mov eax,111h的111h。
2.2.2、SSDT表 和 ShadowSSDT 表和 HalDispatchTable硬件抽象层调度表 简介
 再windows NT系列操作系统中,有两种类型的系统服务,一种是实现在内核文件中,是常用的系统服务。另一种实现在win32k.sys中,是一些与图形显示及用户界面相关的系统服务。这些系统服务在系统运行期间常驻于系统内存区中,并且他们的入口地址保存在两个系统服务地址表KiServiceTable和Win32pServiceTable中.所有的系统服务地址表都保存在系统服务描述表(SDT)中。
 目前windows系统共有两个SDT,一个是ServiceDescriptorTable(SSDT),另一个是ServiceDescriptorTableShadow(SSDTShadow).
 其中ServiceDescriptorTable中只包含KiServiceTable,而ServiceDescriptorTableShadow中既包含KiServiceTable又包含Win32pServiceTbale.其中SSDT是可以访问的而SSDTShadow是不公开的。
 使用windbg查看SSDT和SSDTShadow如下:
lkd> dd nt!KeServiceDescriptorTable
83fad9c0  83ec1d9c 00000000 00000191 83ec23e4
83fad9d0  00000000 00000000 00000000 00000000 //SSDT中该项为空
lkd> dd nt!KeServiceDescriptorTableShadow
83fada00  83ec1d9c 00000000 00000191 83ec23e4
83fada10  955b6000 00000000 00000339 955b702c //SSDTShadow中该项不为空
SDT的表项中成员按以下数据结构组成:
typedef struct _KSYSTEM_SERVICE_TABLE
{
    PULONG ServiceTableBase;         // 0x00 系统服务地址表地址
    PULONG ServiceCounterTableBase;  // 0x04
    PULONG NumberOfService;          // 0x08 服务函数的个数
    ULONG ParamTableBase;            // 0x0c 该系统服务的参数表
} KSYSTEM_SERVICE_TABLE, *PKSYSTEM_SERVICE_TABLE; //sizeof=0x10
那么根据SSDTShadow可以得到KiServiceTable的地址为0x83ec1d9c,包含0x191个服务函数;
可以得到Win32pServiceTable的地址为0x955b6000,包含0x339个服务函数。
 这时我们去看看Win32pServiceTable处的东西吧!
lkd> dds 955b6000
955b6000  95543d37 win32k!NtGdiAbortDoc
955b6004  9555bc23 win32k!NtGdiAbortPath
955b6008  953b71ac win32k!NtGdiAddFontResourceW
955b600c  95552c5d win32k!NtGdiAddRemoteFontToDC
955b6010  9555d369 win32k!NtGdiAddFontMemResourceEx
955b6014  95544554 win32k!NtGdiRemoveMergeFont
955b6018  955445e8 win32k!NtGdiAddRemoteMMInstanceToDC
955b601c  9546dad1 win32k!NtGdiAlphaBlend
955b6020  9555cb94 win32k!NtGdiAngleArc
955b6024  95421965 win32k!NtGdiAnyLinkedFonts
955b6028  95421882 win32k!NtGdiFontIsLinked
955b602c  9555eead win32k!NtGdiArcInternal
955b6030  9555d085 win32k!NtGdiBeginGdiRendering
955b6034  9555bc97 win32k!NtGdiBeginPath
955b6038  954628cb win32k!NtGdiBitBlt
 可以发现它的每一个成员都是一个四字节的服务函数指针!如果把这里面某个函数指针改为我们shellcode的地址,再在用户层调用它的R3对应函数,那么不就让我们的shellcode在高权限执行了吗?但是,我们需要一个更好的目标,它在我们程序的运行阶段不会被其他任何进程调用。(因为又不是你一个程序在调系统服务函数,如果其他程序调用了你改了函数指针指向的函数,就会有不可预料的事情发生,比如BSOD).
	另一个很好的表是硬件抽象层(HAL)调度表nt!HalDispatchTable。这里也存储了系统调用地址,不过是HAL例程的地址。用温帝霸查看如下所示:
lkd> dds nt!HalDispatchTable
83f6e3f8  00000004
83f6e3fc  83e338a2 hal!HaliQuerySystemInformation
83f6e400  83e341b4 hal!HalpSetSystemInformation
	注意到nt!HalDispatchTable+4那个地址指向的函数了吗?这个函数就是我们要覆盖为shellcode地址的最佳选择。因为有一个名为NtQueryIntervalProfile的未记录函数,它获取当前为给定配置文件源设置的配置文件间隔。该函数可以通过调用GetProcAddress从NTDLL.DLL中获取地址,在userland调用。该函数在内部调用KeQueryIntervalProfile函数 :
kd> u nt!NtQueryIntervalProfile + 0x62
nt!NtQueryIntervalProfile+0x62:
8414fecd 7507            jne     nt!NtQueryIntervalProfile+0x6b (8414fed6)
8414fecf a1acdbf683      mov     eax,dword ptr [nt!KiProfileInterval (83f6dbac)]
8414fed4 eb05            jmp     nt!NtQueryIntervalProfile+0x70 (8414fedb)
8414fed6 e83ae5fbff      call    nt!KeQueryIntervalProfile (8410e415);调用KeQueryIntervalProfile
8414fedb 84db            test    bl,bl
8414fedd 741b            je      nt!NtQueryIntervalProfile+0x8f (8414fefa)
8414fedf c745fc01000000  mov     dword ptr [ebp-4],1
8414fee6 8906            mov     dword ptr [esi],eax
//本地u好像权限不够,双机调u成功
	继续反汇编nt!KeQueryInterValProfile
kd> u nt!KeQueryIntervalProfile+0x23
nt!KeQueryIntervalProfile+0x23:
8410e438 ff15fce3f683    call    dword ptr [nt!HalDispatchTable+0x4 (83f6e3fc)]
8410e43e 85c0            test    eax,eax
8410e440 7c0b            jl      nt!KeQueryIntervalProfile+0x38 (8410e44d)
8410e442 807df400        cmp     byte ptr [ebp-0Ch],0
8410e446 7405            je      nt!KeQueryIntervalProfile+0x38 (8410e44d)
8410e448 8b45f8          mov     eax,dword ptr [ebp-8]
8410e44b c9              leave
8410e44c c3              ret
	发现了吗?nt!HalDispatchTable+0x4不就是hal!HaliQuerySystemInformation吗?所以我们可以用userland中的令牌(Token)窃取shellcode的地址覆盖这个指针,那么一旦我们调用NtQueryIntervalProfile函数的时候,就会在内核中运行我们的shellcode啦!!!
 但是绕来绕去,我们还是没有办法在R3直接修改内核空间中的内存。。。
CVE-2018-8120 分析的更多相关文章
- [uboot] (第三章)uboot流程——uboot-spl代码流程  后续2018版本分析
		
board_init_f在/u-boot-2018.07-fmxx/arch/arm/mach-fmxx/spl.c中定义 board_init_f之后,和转载的部分有出入: u-boot-2018. ...
 - 慢查询日志分析(mysql)
		
开启慢查询日志之后,慢查询sql会被存到数据库系统表mysql.slow_log或是文件中,可参考.有两个工具可以帮助我们分析输出报告,分别是mysqldumpslow和pt-query-digest ...
 - android CVE
		
本文收集网上android cve的一些分析供后续学习: Android uncovers master-key:android1.6-4.0 由于ZIP格式允许存在两个或以上完全相同的路径,而安卓系 ...
 - HDU 2018 母牛的故事 (递归入门)
		
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2018 思路分析: 问题分析:这道题的递推关系非常类似斐波那契数列,由题意不难得到以下函数递推式: 对于 ...
 - 深入剖析最新IE0day漏洞
		
在2018年4月下旬,我们使用沙箱发现了IE0day漏洞;自从在野外发现上一个样本(CVE-2016-0189)已经有两年多了.从许多方面来看,这个特别的漏洞及其后续的开发比较有趣.下一篇文章将分析最 ...
 - Android安全研究经验谈
		
安全研究做什么 从攻击角度举例,可以是:对某个模块进行漏洞挖掘的方法,对某个漏洞进行利用的技术,通过逆向工程破解程序.解密数据,对系统或应用进行感染.劫持等破坏安全性的攻击技术等. 而防御上则是:查杀 ...
 - 2018-2019-2 网络对抗技术 20165236 Exp5 MSF基础应用
		
2018-2019-2 网络对抗技术 20165236 Exp5 MSF基础应用 一. 实践内容(3.5分) 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要 ...
 - MT【272】更大的视野,更好的思路.
		
已知$f(x)=\sum\limits_{k=1}^{2017}\dfrac{\cos kx}{\cos^k x},$则$f(\dfrac{\pi}{2018})=$_____ 分析:设$g(x)=\ ...
 - Debian Security Advisory(Debian安全报告) DSA-4405-1 openjpeg2
		
package :openjpeg2 相关CVE ID: CVE-2017-17480 CVE-2018-5785 CVE-2018-6616 CVE-2018-14423 CVE-2018-1808 ...
 - 关于Retrofit网络请求URL中含有可变参数的处理
		
开题:在此默认各位看官对Retrofit.以及Okhttp已经有过一定的了解及应用,所以今天我们不谈基础入门的东西,今天我们谈在Retrofit请求接口管理类中URL参数含有动态参数的处理方式.一般我 ...
 
随机推荐
- Lunix服务器上项目迁移命令
			
scp就是security copy,用于将文件或者目录从一个Linux系统拷贝到另一个Linux系统下. scp传输数据用的是SSH协议,保证了数据传输的安全,其格式如下: scp 远程用户名@IP ...
 - 记录eclipse安装SpringBoot插件及搭建SpringBoot项目
			
刚学习了下SpringBoot 插件安装 创建项目在此记录下 在spring官网上下载相关的插件,然后导入到eclipse中,以下是下载步骤: 1.首先查看自己eclipse版本号 help--> ...
 - 使用reflector对.NET反编译
			
reflector的下载地址:https://www.cr173.com/soft/355285.html 反编译后的结果:
 - Qt之二进制兼容
			
一.回顾 使用qt2年多了,但是还是觉得很陌生,总是会被qt搞的很紧张,有时候当我自信满满的打开帮助文档,搜索某个已知的类时,由于笔误敲错了一个字母而出现了另外一个类,不过奇怪的是还真有这么一个类,哎 ...
 - Redis学习——数据结构介绍(四)
			
一.简介 作为一款key-value 的NoSQL数据库,Redis支持的数据结构比较丰富,有:String(字符串) .List(列表) .Set(集合) .Hash(哈希) .Zset(有序集合) ...
 - Java8虚拟机内存模型
			
1. Java虚拟机运行时数据区 在JDK1.8之前,JVM运行时数据区分为堆.虚拟机栈.本地方法栈.方法区.程序计数器.如下图所示: 虚拟机栈:线程私有,随线程创建而创建.栈里面是一个一个“栈帧” ...
 - 关于ML.NET v0.8的发布说明
			
ML.NET允许您创建和使用针对场景的机器学习模型,以实现常见任务,如情绪分析,问题分类,预测,推荐,欺诈检测,图像分类等.您可以使用ML.NET示例在GitHub仓库中查看这些常见任务 .ML.NE ...
 - dotnet core使用开源组件FastHttpApi进行web应用开发
			
FastHttpApi相对于asp.net mvc来说有着更轻量和性能上的优势,性能上面就不在这里介绍了(具体可查看 https://github.com/IKende/FastHttpApi).在这 ...
 - SpringBoot入门教程(一)详解intellij idea搭建SpringBoot
			
最近公司有一个内部比赛(黑客马拉松),报名参加了这么一个赛事,在准备参赛作品的同时,由于参赛服务器需要自己搭建且比赛产生的代码不能外泄的,所以借着这个机会,本地先写了个测试的demo,来把tomcat ...
 - EF架构~TransactionScope与SaveChanges的关系
			
回到目录 TransactionScope是.net环境下的事务,可以提升为分布式事务,这些知识早在很久前就已经说过了,今天不再说它,今天主要谈谈Savechanges()这个方法在Transacti ...