目录

CVE-2018-8120 分析

1、实验环境

1.1、操作系统

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 分析的更多相关文章

  1. [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. ...

  2. 慢查询日志分析(mysql)

    开启慢查询日志之后,慢查询sql会被存到数据库系统表mysql.slow_log或是文件中,可参考.有两个工具可以帮助我们分析输出报告,分别是mysqldumpslow和pt-query-digest ...

  3. android CVE

    本文收集网上android cve的一些分析供后续学习: Android uncovers master-key:android1.6-4.0 由于ZIP格式允许存在两个或以上完全相同的路径,而安卓系 ...

  4. HDU 2018 母牛的故事 (递归入门)

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2018 思路分析: 问题分析:这道题的递推关系非常类似斐波那契数列,由题意不难得到以下函数递推式: 对于 ...

  5. 深入剖析最新IE0day漏洞

    在2018年4月下旬,我们使用沙箱发现了IE0day漏洞;自从在野外发现上一个样本(CVE-2016-0189)已经有两年多了.从许多方面来看,这个特别的漏洞及其后续的开发比较有趣.下一篇文章将分析最 ...

  6. Android安全研究经验谈

    安全研究做什么 从攻击角度举例,可以是:对某个模块进行漏洞挖掘的方法,对某个漏洞进行利用的技术,通过逆向工程破解程序.解密数据,对系统或应用进行感染.劫持等破坏安全性的攻击技术等. 而防御上则是:查杀 ...

  7. 2018-2019-2 网络对抗技术 20165236 Exp5 MSF基础应用

    2018-2019-2 网络对抗技术 20165236 Exp5 MSF基础应用 一. 实践内容(3.5分) 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要 ...

  8. MT【272】更大的视野,更好的思路.

    已知$f(x)=\sum\limits_{k=1}^{2017}\dfrac{\cos kx}{\cos^k x},$则$f(\dfrac{\pi}{2018})=$_____ 分析:设$g(x)=\ ...

  9. 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 ...

  10. 关于Retrofit网络请求URL中含有可变参数的处理

    开题:在此默认各位看官对Retrofit.以及Okhttp已经有过一定的了解及应用,所以今天我们不谈基础入门的东西,今天我们谈在Retrofit请求接口管理类中URL参数含有动态参数的处理方式.一般我 ...

随机推荐

  1. Python内置函数(19)——eval

    英文文档: eval(expression, globals=None, locals=None) The arguments are a string and optional globals an ...

  2. 「造个轮子」——cicada(轻量级 WEB 框架)

    前言 俗话说 「不要重复造轮子」,关于是否有必要不再本次讨论范围. 创建这个项目的主要目的还是提升自己,看看和知名类开源项目的差距以及学习优秀的开源方式. 好了,现在着重来谈谈 cicada 这个项目 ...

  3. 使用ML.NET + ASP.NET Core + Docker + Azure Container Instances部署.NET机器学习模型

    本文将使用ML.NET创建机器学习分类模型,通过ASP.NET Core Web API公开它,将其打包到Docker容器中,并通过Azure Container Instances将其部署到云中. ...

  4. JavaScript 中 正则替换 replace

    本文初步介绍 replace 在 js 中,我们常常会遇到 用来 解决开发中常会遇到的 问题的 知识总结, 如果你已经 非常熟悉,又可以绕道了. 定义和用法 replace() 方法用于在字符串中常用 ...

  5. 获取Android设备唯一标识码

    概述 有时需要对用户设备进行标识,所以希望能够得到一个稳定可靠并且唯一的识别码.虽然Android系统中提供了这样设备识别码,但是由于Android系统版本.厂商定制系统中的Bug等限制,稳定性和唯一 ...

  6. SpringBoot入门教程(四)MyBatis generator 注解方式和xml方式

    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 XML ...

  7. Chapter 4 Invitations——22

    "Are you going all by yourself?" he asked, and I couldn't tell if he was suspicious I had ...

  8. ThreadPoolExecutor系列二——ThreadPoolExecutor 代码流程图

    ThreadPoolExecutor 代码流程图 本文系作者原创,转载请注明出处:http://www.cnblogs.com/further-further-further/p/7681648.ht ...

  9. PHP大法

    Topic Link http://ctf5.shiyanbar.com/DUTCTF/index.php Notes: 1) 进去发现 根据提示查看是否存在.txt文件,打开之后发现有东西 2)分析 ...

  10. 如何理解git checkout -- file和git reset HEAD -- file

    http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/001374831943254ee ...