热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

CVE201912750:SEP本地提权漏洞分析(Part1)

 0x00 概述Symantec Endpoint Protection(以下简称SEP)中存在一个漏洞,恶意应用可以利用该漏洞泄露高权限上下文中的信息以及/或者以较高权限执行代码,最终实现对目标主机

 

0x00 概述

Symantec Endpoint Protection(以下简称SEP)中存在一个漏洞,恶意应用可以利用该漏洞泄露高权限上下文中的信息以及/或者以较高权限执行代码,最终实现对目标主机的完全控制。

漏洞利用过程如下图所示:

图1. 漏洞利用示意图

受影响的版本如下:

Symantec Endpoint Protection v14.x Symantec Endpoint Protection v12.x <12.1 (RU6 MP10)
Symantec Endpoint Protection Small Business Edition v12.x <12.1 (RU6 MP10c)

 

0x01 前言

几个月之前,在研究最新版SEP软件(SEP v14.2 Build 2486)中是否存在本地提权漏洞时,我们找到了已存在几年之久的一个漏洞。

此外,Windows 10从v1809开始在内核池分配中引入了最新的安全更新,迫使我们找到利用该漏洞的另一种方法,并且新方法依然适用于当前可用的最新系统版本(v1909)。

由于这两种利用方法存在较大不同,因此我们决定分两篇来介绍相关内容。

在第一篇文章中,我们将讨论SEP中的bug,介绍如何在早期Windows版本(Windows 7到Windows 10 v1803)中利用该漏洞,利用过程不需要满足额外的内核模式执行控制条件

在第二篇文章中,我们将采用更为复杂的一种方法。在Windows 10 v1809及更高版本系统中,内核模式池分配中引入了新的Low Fragmentation Heap(LFH,低碎片堆)机制,此时无法使用第一种利用方法,因此我们需要进一步分析存在漏洞的产品。通过进一步研究,我们才能实现内核模式下的代码执行,绕过其他缓解机制(如SMEP及KASLR)。

 

0x02 SEP漏洞分析

当系统中创建新进程时,SEP会将名为sysfer.dll的一个DLL模块注入进程,该模块在加载时会发送一系列输入输出控制(IOCTL)请求。

这里我们比较感兴趣的是IOCTL 0x222014,该请求会发送给SysPlant.sys内核模块。

在处理该请求的过程中,产品代码逻辑上存在缺陷,允许攻击者泄露并破坏内核模式数据。

分析在处理IOCTL请求过程中调用的子例程时,我们发现SEP会执行如下操作:

1、调用ExAllocatePool,在分页池(Paged Pool)中分配大小为0x14字节的一个缓冲区;

2、调用IoAllocateMdl,为该缓冲区分配一个内存描述符列表;

3、调用MmProbeAndLockPages来探测并锁定内存中的关联页面;

4、调用MmMapLockedPagesSpecifyCache将这些页面映射到另一个虚拟地址范围(如图2所示)。

图2. 在用户模式下映射Paged Pool Chunk

上面最后一个步骤会将pool chunk映射到用户模式,位于调用进程的上下文中。然而当映射缓冲区时,该缓冲区涉及到的整个内存页面同样会被映射。

在这种情况下,缓冲区分配的是一个非常小的chunk,总共占用0x30个字节(缓冲区大小 + 池头部 + 对齐填充数据)。这意味着通过在用户模式下映射这个pool chunk,我们可以泄露出剩余的内存页面数据。我们能多得到0xFD04048)字节的内核内存,其中可能包含一些高权限下才能查看的信息。

不幸的是,漏洞影响范围并没有那么简单。默认情况下,内存页面会被映射为可写模式,因此用户模式进程可以修改对应的内容。对用户态映射内存页面的任何修改操作也会反映到原始的内核模式内存页面。

为了缓解内存泄露,驱动应当调整内核模式下分配的缓冲区大小,使其等于系统所用内存页面大小(通常为4KB)的整数倍。在映射操作之前,该缓冲区应当执行清零操作。

另外需要注意的是,当被映射到用户地址空间时,内核模式缓冲区不应当被释放。否则,向该缓冲区写入的任何新数据也会在用户态中泄露。

因此被映射的内核模式下的缓冲区应处于只读状态,从Windows 8开始,我们在调用MmMapLockedPagesSpecifyCache函数时可以使用MdlMappingNoWrite标志。

传递给MmMapLockedPagesSpecifyCache的第1个参数为指向MDL结构的一个指针,该结构在前文提到的步骤2中分配。

图3. MDL结构

该结构中我们重点关注3个成员:



  • StartVa:内存页面的起始地址。


  • ByteCount:MDL对应缓冲区的大小。


  • ByteOffset:内存页面中缓冲区的起始偏移量。

开发者本来是想将大小为0x14字节的缓冲区映射到用户模式下调用进程的地址空间中,然而系统会映射整个内存页面,而不单单是所需的pool chunk,如图4及图5所示:

图4. 内核模式缓冲区

图5. 用户模式映射的缓冲区

这个漏洞点不错,但我们还想进一步挖掘利用价值,而不单单是在用户态下获取分页池内存信息。

需要注意的是,只有进程在加载该模块时我们才能利用这一点。因此,我们无法在同一个进程中多次复用相同的IOCTL,在用户态中映射其他内核内存页面。

另一方面,由于内核对象一直都在被分配和释放,因此关联的映射页面的内容也会不断变化。

然而,如果在我们自己的函数中复用相同的IOCTL,那么一旦我们的进程被初始化,我们就能找到已映射chunk在用户模式下的地址。

假如页面分配单元为4KB大小,我们还可以在用户空间中找到该页面的基址(VA & 0xFFFFF000)。

掌握这些信息后,我们可以解析映射的页面,寻找特定的信息及有趣的对象,以便进一步利用该漏洞。

 

0x03 漏洞利用(Win 7 – Win 10 v1803)

在这篇文章中,我们将重点关注Windows 10 v1809之前的系统。澄清相关内容后,也能帮助我们理解第二篇文章内容(其中介绍了最新版Windows 10系统在内核池分配中部署的LFH如何影响本文的利用技术)。这里我们以Windows 10 v1803为研究对象。

由于每个进程我们只能提取1个分页池内存页面,并且不同进程可能提取到的是同一个页面(如果有多个大于0x30字节的空闲chunk),因此我们首先可以启动多个进程进行测试。

每个进程都会使用前面提到的IOCTL来获取用户空间中映射页面的基地址,然后将得到的数据保存到文件中,以便进一步分析。

创建一些进程后,我们可以观察到一些“有趣的”情况。

图6. 提取到的令牌对象

测试我们发现,有时候我们能获取到令牌对象(Token Object),这是内核本地权限提升(LPE)攻击中最常用的目标。这些为分页池对象,现在已经被我们牢牢掌握。

需要注意的是,提取到的内存页面并不一定会包含调用进程所关联的对象,实际上通常不满足该条件。

当发送IOCTL请求时,我们获取到的主要是随机的页面,并且当分页内核池中存在空闲空间时,就会填入0x30字节chunk。

然而幸运的是,我们获取到的不一定是调用进程对应的令牌对象(并且实际上通常不会得到调用进程的令牌对象)。

但这里依然存在随机性,因此我们需要找到正确的方法,以便高效处理这种场景。


令牌对象处理(方法1)

由于每个进程都有自己的令牌对象,因此我们可以创建许多进程,并且将这些进程设置为“等待”状态。我们需要执行该操作,避免关联的令牌对象被释放。

简而言之,我们会在每个子进程中检查映射到当前地址空间中的内核内存页面,查找令牌对象。不论获取到什么数据,进程将无限期处于等待状态。

创建的进程越多,我们能分配到更多的令牌对象,因此最终我们会在映射到用户模式下可写的内核页面中找到所需的对象。

此时我们并不知道每个对象对应的是哪个进程,因此我们必须维护关于进程句柄的一个列表。当子进程创建操作结束后,我们可以检查这些进程对应的令牌,找到已被我们修改权限的进程,然后在其上下文中执行代码。

这个方法的确可行,但可以进一步改进,我们来看一下方法2.


令牌对象处理(方法2)

我们的目标是尽可能多获取令牌对象,因此分配的对象越多,我们就有更大的机率通过0x30字节大小的chunk找到适用的内存页面。

我们可以使用DuplicateTokenEx函数,创建漏洞利用进程Primary令牌的副本。该函数允许我们将克隆出来的令牌作为Primary令牌,以便后续在CreateProcessAsUser函数中使用。

此外,我们还可以使用ImpersonateLoggedOnUser函数,使我们漏洞利用程序的调用线程能直接使用提升的令牌特权。

成功创建数千个Primary令牌副本后,我们就可以使用前面提到的方法1。

沿用之前的方法,我们开始创建一些子进程,每个子进程查看已映射到自己地址空间的内核页面,搜索待修改的令牌对象(如图6所示)。

接下来我们可以遍历令牌副本列表,使用TokenPrivilegesTOKEN_INFORMATION_CLASS枚举类型)来调用GetTokenInformation,搜索其中包含高权限进程特有的特权(比如SeDebugPrivilege)。

最后,我们可以使用修改的令牌,通过CreateProcessAsUser函数来启动具备高权限的新进程,或者通过ImpersonateLoggedOnUser函数来提升调用线程本身的权限。


利用过程总结

1、创建Primary令牌的数千个副本;

2、启动子进程,搜索并修改获取到的令牌对象;

3、解析Primary令牌副本列表,查找被修改的令牌;

4、使用CreateProcessAsUser或者ImpersonateLoggedOnUser函数,在高权限下执行代码;

5、在以SYSTEM权限运行的进程中注入并执行代码。

 

0x04 总结

有时候简单的编程错误会造成非常严重的漏洞,本文就是一个典型的案例。开发者需要在调用进程中映射一小段chunk数据,但却没有详细阅读官方文档,考虑可能带来的安全风险。

在第二篇文章中,我们将重点关注最新版Windows 10 v1909上的利用技术,了解新增的内核池LFH机制如何给我们带来挑战,使我们不得不寻找利用该漏洞的其他方法。

 

0x05 时间线

2019年4月:发现漏洞

2019年4月18日:通知厂商

2019年4月19日:厂商确认漏洞

2019年4月19日:厂商请求延长漏洞处理时间

2019年7月31日:厂商发布安全公告

2019年12月5日:本文发布


推荐阅读
  • MicrosoftDeploymentToolkit2010部署培训实验手册V1.0目录实验环境说明3实验环境虚拟机使用信息3注意:4实验手册正文说 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 在Windows系统中安装TensorFlow GPU版的详细指南与常见问题解决
    在Windows系统中安装TensorFlow GPU版是许多深度学习初学者面临的挑战。本文详细介绍了安装过程中的每一个步骤,并针对常见的问题提供了有效的解决方案。通过本文的指导,读者可以顺利地完成安装并避免常见的陷阱。 ... [详细]
  • 您的数据库配置是否安全?DBSAT工具助您一臂之力!
    本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ... [详细]
  • 浏览器作为我们日常不可或缺的软件工具,其背后的运作机制却鲜为人知。本文将深入探讨浏览器内核及其版本的演变历程,帮助读者更好地理解这一关键技术组件,揭示其内部运作的奥秘。 ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中配置 fstab 文件以实现开机自动挂载 NFS 共享目录的方法,并解决了常见的配置失败问题。 ... [详细]
  • Win10 周年更新 14393.1737 的详细内容与改进
    尽管今天不是常规的周二补丁日,微软依然发布了 Win10 周年更新 14393.1737 和 Win10 创意者更新 15063.632。本文将详细介绍 Win10 周年更新 14393.1737 的主要更新内容。 ... [详细]
  • 全面升级的中文PubMed——Medreading
    Medreading 是一款由科研者之家(HOME for Researchers)推出的中文版PubMed,提供强大的文献检索和分析功能,支持AI辅助全文下载。 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • 本文介绍了如何利用 `matplotlib` 库中的 `FuncAnimation` 类将 Python 中的动态图像保存为视频文件。通过详细解释 `FuncAnimation` 类的参数和方法,文章提供了多种实用技巧,帮助用户高效地生成高质量的动态图像视频。此外,还探讨了不同视频编码器的选择及其对输出文件质量的影响,为读者提供了全面的技术指导。 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • DVWA学习笔记系列:深入理解CSRF攻击机制
    DVWA学习笔记系列:深入理解CSRF攻击机制 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
author-avatar
牛氏学道_246
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有