[译] APT分析报告:09.漏洞利用图谱–通过查找作者的指纹来寻找漏洞

2021-12-03 14:44:02 浏览数 (1)

该专栏主要翻译国外知名安全厂商的APT报告,了解它们的安全技术,学习它们溯源APT组织和恶意代码分析的方法,希望对您有所帮助。当然,由于作者英语有限,会借助机翻进行校验,还请包涵!

前文分享了APT组织OilRig发起的一项新攻击行动,该行动似乎是针对Lebanese目标,使用了一种新的后门变体,称之为“SideTwist”。这篇文章将详细讲解checkpoint公司提出的一个新技术,即漏洞利用图谱,通过查找作者的指纹来寻找利用漏洞,文章内容非常值得我们学习,尤其搞科学研究的读者。

代码语言:javascript复制
原文标题:Graphology of an Exploit – Hunting for exploits 
by looking for the author’s fingerprints
原文链接:https://research.checkpoint.com/2020/
graphology-of-an-exploit-volodya/
文章作者:checkpoint
发布时间:2020年10月2日
文章来源:https://research.checkpoint.com/

文章目录:

  • 一.背景
  • 二.漏洞利用集成
  • 三.指纹漏洞利用开发者
  • 四.攻击者漏洞利用 CVE-2015-2546 CVE-2016-0040 CVE-2016-0167 CVE-2016-0165* CVE-2016-7255 CVE-2017-0001 CVE-2017-0263 CVE-2018-8641* CVE-2019-0859 CVE-2019-1132* CVE-2019-1458
  • 五.作者指纹 PlayBit(又名luxor2008) bool elevate(int target_pid) Sleep(200) 操作系统指纹 内核地址泄漏 Token Swap
  • 六.客户分析
  • 七.结论 附录-IOC表

在过去的几个月中,我们的漏洞和恶意软件研究团队专注于恶意软件内部的漏洞利用研究,尤其是漏洞利用者本身。从一个事件响应案例开始,我们构建了Windows最活跃的漏洞利用开发人员之一的档案,称为 VolodyaBuggiCorp。到目前为止,我们设法跟踪了他们Windows内核本地特权升级(LPE)十多个漏洞,并且许多漏洞为0-day漏洞。

一.背景

正如所有有趣故事一样,我们的故事始于一个应急响应案例。在分析针对我们客户的一个复杂攻击时,我们注意到该恶意软件执行了一个很小的64位可执行文件。该样本包含了一些不寻常的调试字符串,这些调试字符串指向试图利用受害者计算机上的漏洞。更重要的是,该示例有一个遗留的PDB路径,并指向了该二进制目标文件:

  • …cve-2019-0859x64 ReleaseCmdTest.pdb

由于 CVE-2019-0859 实现时没有任何在线资源,我们意识到我们看到的不是一个公开可用的PoC,而是一个真实的开发工具。这激发了我们深入挖掘的兴趣。

接着我们直接对漏洞进行逆向工程。二进制文件很小,并且调试消息在那里指导我们。它利用了 CreateWindowsEx 中的一个UAF漏洞来获取父进程的更高特权。我们很快发现了一个有趣的现象:

  • 似乎这个漏洞和恶意软件本身并不是由同一个人编写的,其代码质量、缺乏混淆、PDB和时间戳都表明了这个结论。

图1:CreateWindowEx调用,如Cutter所示。

CVE-2019-0859: Microsoft Win32k特权提升漏洞 CVE-2019-0859是CreateWindowEx函数中提供的Use-After-Free漏洞。当Win32k组件无法正确处理内存中的对象时,Windows中存在一个特权提升漏洞。成功利用此漏洞的攻击者可以在内核模式下运行任意代码,然后攻击者可以安装程序,查看、更改或删除数据,或创建有完全用户权限的新帐户。 - https://securelist.com/new-win32k-zero-day-cve-2019-0859/90435/

二.漏洞利用集成

我们倾向于将特定恶意软件家族背后的人们视为一个完整的单元。设想每一个组件都是由一个人、团队或小组编写而成。事实是,编写一个高级恶意软件,无论是国家还是APT组织,都需要不同技能的不同人群。一个国家的网络攻击组织,很可能在不同的组织和分支中有数百甚至数千名员工。组织中的每个工人都有一个特定的角色,并通过特殊的技术培训和多年的专业知识进行调整。

在这样的组织中,编写公共组件的工作量被分解到专门的团队中,不同的团队将负责初始访问、收集敏感数据、横向移动模块。

一个运营实体的目标是在它的恶意软件中嵌入一个漏洞利用模块(exploit),不能只依赖恶意软件开发人员。发现漏洞并可靠地利用漏洞,很可能是由专门从事特定角色的特定团队或个人来完成的。对于恶意软件开发人员来说,他们并不真正关心其幕后是如何工作的,只想集成这个模块并完成它

为了实现这种劳动分工,两个团队需要就一些API达成共识,这些API将成为不同组件之间的桥梁。这种集成API并不是国家参与者所独有的,而是漏洞利用“自由市场”中很常见的功能。无论是在地下论坛、漏洞利用经纪人,还是网络攻击组织,他们都会向客户提供如何将利用漏洞利用程序集成到恶意软件中的指导手册。

从本质上讲,这个集成点是我们研究的重点。假设利用漏洞的作者独立工作,并且只将他们的代码/二进制模块分发给恶意软件作者,我们决定对他们进行更改。通过分析嵌入在恶意软件样本中的漏洞利用程序,我们可以了解有关漏洞利用程序作者的更多信息,希望通过研究他们的编码习惯以及将其产品分发给编写恶意软件的同行时留下的其他线索来区分他们的身份。

作者简单总结:在大型网络攻击活动或APT组织中,由于需要不同团队协作来完成攻击事件,因此各个团队间需要调用API来搭建桥梁,比如实现初始访问、数据收集、横向移动等功能,最终构建恶意程序,并且会提供相应的集成手册。基于此,会造成他们的编程习惯、漏洞利用细节信息不同,本文将通过收集漏洞利用的线索来区分他们的身份。

三.指纹漏洞利用开发者

本文不是专注于一个完整的恶意软件溯源和寻找新样本的恶意软件家族或参与者,而是想提供另一种观点,专注于漏洞利用开发人员编写的这几个功能。

从事件响应案例中获得这个小的64位二进制文件看起来是个不错的开始。该二进制文件除了利用 CVE-2019-0859 之外什么也没做,并且它不基于开源的源代码或POC。由于可执行文件是由漏洞利用作者(攻击者)以外的其他人编写而成,因此它非常适合指纹识别。

此外,可执行文件与恶意软件的主要二进制文件是分离的(一个臭名昭著的犯罪软件),这让我们相信这个漏洞不是由恶意软件开发人员内部开发的。带着这个希望,我们开始寻找同一作者编写的更多的exploit。

我们首先从已经拥有的二进制文件中收集简单的信息(Checkpoint):

  • 字符
  • 串内部文件名
  • 时间戳
  • PDB路径

第一个结果立即出现了——一个与64位示例完全匹配的32位可执行文件。具体来说,正如它们的时间戳嵌入式PDB路径所显示的那样,它们是在同一时间从相同的源代码中一起编译的。现在我们有了这两个样本,我们就能得出要寻找的东西。

为了对这个漏洞的作者进行指纹识别,我们将目光投向了以下方面:

  • 二进制文件中的独特工件 – 硬编码值(加密常量,“垃圾”值,例如0x11223344) – 数据表(通常是特定于版本的配置) – 字符串(GDI对象名称:“ MyWindow”、“ MyClass_56”、“ findme1”等) – PDB路径
  • 代码段 – (1) 独特的功能实现 a.系统调用包装器(syscall) b.内联汇编 c.专有加密函数/实现 – (2) 技术和习惯 a.首选的泄漏技术(HMValidateHandle、gSharedInfo等) b.首选的提升技术(如何执行token替换?) c.堆溢出技术(使用AcceleratorTables?Windows?Bitmaps?) – (3) 构架 a.漏洞利用流程(The flow of the exploits) – 选项1:几乎没有分支的主要漏洞利用流程 – 选项2:针对不同版本操作系统的多个扭曲和旋钮 b.代码和函数的结构 – 模块化:功能分离 – 结构:分离以清除阶段(初始化、配置、喷涂、令牌交换等) – 全局变量:哪些信息存储在全局变量中?(操作系统版本?枚举操作系统版本?特定字段偏移量?) c.特定于版本的配置 – 字段偏移量:哪些字段特别重要? – 首选系统调用:系统调用的首选集合 d.提供给客户的API

图2:寻找的与利用漏洞相关的工件集。

对应原文:

带着这些属性,回到我们拥有的两个样本,并标记了一些我们认为独特的工件。即使只有两个小的二进制文件(本质上是相同的),我们仍然能够创建搜寻规则来查找该开发人员编写的更多示例。令我们惊讶的是,我们能够找到比想象中更多的东西。

一个接一个的出现了几十个样本,随着每一个样本的出现,我们改进了搜寻规则和方法。通过对样本的仔细分析,我们能够了解哪些样本利用了哪个CVE,并以此为基础创建了一个时间表,以了解该漏洞是在暴露之前的0-day漏洞,还是基于补丁扩散和类似技术实现的1-day漏洞。

到目前为止,仅基于我们的指纹识别技术且没有进一步的情报信息,我们就可以将10多个CVE归因于同一个漏洞利用开发人员。后来,公开的报告披露了我们的目标漏洞利用(exploit)销售者的名称为——Volodya(又名Volodimir) ,以前称为BuggiCorp。

似乎我们不是唯一跟踪此漏洞卖家的,卡巴斯基也报道关于他们的一些相关信息。此外,ESET在VB2019关于Buhtrap的演讲中还提到了Volodya的一些重要线索。

根据卡巴斯基的说法,Volodya最初以其 “BuggiCorp” 绰号成为头条新闻,当时他们在臭名昭著的Exploit [.]网络犯罪论坛上宣传了Windows 0-day的待售广告,起价为9.5万美元。多年来,价格不断上涨,他们的一些Windows LPE 0-day漏洞利用软件的售价高达20万美元。

正如卡巴斯基报告中所发表的,后来得到我们的证实,Volodya将漏洞利用软件卖给了犯罪软件和APT团体。我们将在“客户”一节中详细讨论actor的客户。

四.攻击者漏洞利用

Our actor’s exploits 尽管我们最初的一些狩猎规则需要进行一些微调,但即使是我们得到的即时结果也相当令人惊讶。经过进一步的校准后,我们找到了许多示例,所有这些示例都是Windows中的本地特权升级(LPE,Local Privilege Escalation)漏洞。从这些样本中,我们的行动者(actor)能够确定所利用的CVE列表。

注意: 在对漏洞进行分类时,我们选择了一种保守的方法来决定一个给定的漏洞是0-day还是1-day。如果其他安全供应商将在野的漏洞归因于我们的行动者,那么它就是0-day。如果我们发现足够的证据表明我们的某个样本的确是利用在外传播的漏洞,就像供应商在他们的报告中描述的那样,那么我们也会标记它为0-day。在所有其他情况下,我们将该漏洞标记为1-day,宁愿有较低数量的0-day,而不错误计数超过正确的数量。

CVE-2015-2546

  • 分类:1-day
  • 基本描述: 在 xxxSendMessage(tagPOPUPMENU) 中释放后使用(Use-After-Free)
  • 0-day报告供应商:FireEye
  • 在以下恶意软件样本中发现:Ursnif,Buhtrap

我们的漏洞利用示例使用了与初始报告中所述不同的内存整形技术:喷射Windows(spraying Windows)而不是加速器表(Accelerator Tables)。此外,我们最早和最基本的攻击示例包含以下PDB路径,这表明作者已经知道该漏洞的CVE-ID:

  • C:…volodimir_8c2CVE-2015-2546 _VS2012 x64Release CmdTest.pdb

CVE-2016-0040

  • 分类: 1-day
  • 基本描述: WMIDataDevice IOControl 中未初始化的内核指针(Uninitialized kernel pointer)
  • 0-day报告供应商:N/A. 从来没有在野被当做0-day利用过
  • 在以下恶意软件样本中发现:Ursnif

该漏洞利用已用于单个样本,该样本还包含前面描述的CVE-2015-2546漏洞。如果目标是Windows 8之前的Windows版本,则选择此漏洞。否则使用CVE-2015-2546。

CVE-2016-0167

  • 分类: 0-day
  • 基本描述: 在 Win32k!xxxMNDestroyHandler 中释放后使用(Use-After-Free)
  • 0-day报告供应商:FireEye
  • 在以下恶意软件样本中发现:PUNCHBUGGY

我们的漏洞利用样本与在野的漏洞利用技术报告完全吻合。

CVE-2016-0165*

  • 分类: 1-day
  • 基本描述: 在 Win32k!xxxMNDestroyHandler 中释放后使用(Use-After-Free)
  • 0-day报告供应商:Kaspersky ,被卡巴斯基发现,但未公开发布任何报告
  • 在以下恶意软件样本中发现:Ursnif

这是一个有趣的案例。我们方案的0-day(CVE-2016-0167)已于2016年4月由Microsoft修补。该补丁也修复了CVE-2016-0165,该漏洞也被广泛在外使用。为了寻找新的漏洞进行利用,我们的行动可能对微软的修补程序进行了不同的修补,并发现了一个认为是修补过的0-day漏洞。此漏洞源于之前漏洞 Win32k!xxxMNDestroyHandler 中修补过的函数。

注意,我们从他们针对该漏洞的漏洞样本中找到多个迹象表明,该漏洞作者或他们的客户确定他们已出售了一个针对CVE-2016-0165的漏洞。可悲的是,在分析这个漏洞之后,我们确定这个被利用的漏洞是一个不同的漏洞。

图3:调试字符串显示CVE-2016-0165的混淆,可以从Cutter中看到。

这种困惑可能是由于微软发布了一个解决多个漏洞的单一修复,而且它们是唯一一个在每个代码修复与为其发布的CVE之间有完整映射的补丁。

CVE-2016-7255

  • 分类: 0-day
  • 基本描述: 在 NtUserSetWindowLongPtr 中内存损坏(Memory corruption)
  • 0-day报告供应商:Google ,被谷歌发现,通过技术报告趋势科技(TrendMicro)
  • 在以下恶意软件样本中发现:APT28,又叫Fancy Bear或Sednit。后来被使用在 Ursnif,Dreambot,GandCrab,Cerber,Maze

我们的漏洞利用样本完美地与在野漏洞利用技术报告吻合。后来,这个特定的漏洞被不同的勒索软件参与者广泛使用。此外,我们还看到了其他针对这个特定漏洞的利用,这些漏洞在1-day期间被卖给了其他勒索软件参与者。

注意:我们有多个间接证据认为,这个0-day就是那个由BuggiCorp在2016年5月发布到 exploit[.] 著名广告中提到的漏洞。

CVE-2017-0001

  • 分类: 1-day
  • 基本描述: 在 RemoveFontResourceExW 中释放后使用(Use-After-Free)
  • 0-day报告供应商:N/A. 从来没有在野被当做0-day利用过
  • 在以下恶意软件样本中发现:Turla,归因于Turla。后来被使用在 Ursnif

Turla(FireEye)在操作中当作1-day漏洞使用过。

CVE-2017-0263

  • 分类: 0-day
  • 基本描述: 在 win32k!xxxDestroyWindow 中释放后使用(Use-After-Free)
  • 0-day报告供应商:ESET
  • 在以下恶意软件样本中发现:APT28,又叫Fancy Bear或Sednit

我们的漏洞利用样本与在野的漏洞利用技术报告完全吻合。

CVE-2018-8641*

  • 分类: 1-day
  • 基本描述: 在 win32k!xxxTrackPopupMenuEx 重复释放(Double Free)
  • 0-day报告供应商:N/A. 从来没有在野被当做0-day利用过
  • 在以下恶意软件样本中发现:Magniber

同样,识别使用过的1-day通常比识别0-day漏洞更难。这一次,我们找不到任何可能暗示参与者认为他们正在利用的漏洞示例。我们发现该漏洞已于2018年12月被微软修补。在扫描此补丁中解决的漏洞列表后,我们非常确定微软将此漏洞标记为CVE-2018-8641,但我们无法确认。

2020年6月24日,卡巴斯基在其博客上发表了一份通过大规模漏洞利用工具(the Magnitude exploit kit)分发的漏洞利用攻击。在他们的博文中,卡巴斯基分析了Magniber使用的LPE漏洞,将其归因于 Volodya,并预测其可能是CVE-2018-8641。这进一步通过卡巴斯基的独立结论验证了我们的初步估计。

CVE-2019-0859

  • 分类: 0-day
  • 基本描述: 在 CreateWindowEx 中释放后使用(Use-After-Free)
  • 0-day报告供应商:Kaspersky
  • 在以下恶意软件样本中发现:用作一个独立的组件被注入或加载,我们无法将其归因于任何特定的APT/恶意软件

我们的漏洞利用示例与有关野生漏洞利用的技术报告完全吻合。我们的研究始于在客户网络中发现的这种漏洞利用的单个样本。在我们后来发现的样本中,我们可以看清这个PDB字符串:

  • X:tools 0day 09-08-2018 x64ReleaseRunPS.pdb

该字符串和我们最初示例中的PDB字符串相反。

  • S:WorkInject cve-2019-0859 ReleaseCmdTest.pdb

CVE-2019-1132*

  • 分类: 0-day
  • 基本描述: 在 win32k!xxxMNOpenHierarchy(tagPOPUPMENU) 中空指针引用(NULL pointer dereference)
  • 0-day报告供应商:ESET
  • 在以下恶意软件样本中发现:归因于 Buhtrap

我们有多个理由相信这是Volodya的另一个0-day漏洞,因为报告中的多个技术细节匹配他们典型的利用方式。此外,,该漏洞报告其中嵌入了以下PDB路径:

  • C:work volodimir_65 …PDB

然而,这是我们列表中唯一尚未找到样本的漏洞,因此我们不能确定这一漏洞的归属。

CVE-2019-1458

  • 分类: 1-day
  • 基本描述:在窗口切换时内存损坏
  • 0-day报告供应商:Kaspersky (初始报告、详细报告)
  • 在以下恶意软件样本中发现:归因于操作 WizardOpium

我们的漏洞利用和技术报告里的漏洞利用不一致。此外,在他们的详细报告中,卡巴斯基指出“同样有趣的是,我们在补丁发布一周后就发现了另一个1-day漏洞,这表明利用这个漏洞非常简单。”事实上,我们的样本是在卡巴斯基首次报告后的第6天。

最后通过下表总结我们列出的11个漏洞:

五.作者指纹

现在,我们从Volodya那里发现了10多个不同的exploit,我们可以更详细地审查它们,并熟悉actor的工作习惯。从一开始我们就很清楚,我们的参与者可能有一个简单的模板,他们可以针对不同的漏洞利用程序进行部署,因为每个漏洞利用程序的功能流程甚至不同功能的顺序都在大多数漏洞利用程序之间共享。

在本节中,我们将描述一组关键特征,这些特征反映了在创建exploit模板时Volodya所做的不同实现选择。我们将他们的实现与昵称为PlayBit的另一个exploit编写器的实现进行比较。通过这种比较,旨在概述漏洞利用各部分中存在的各种实现选项,从而使每个作者的实现选择集成为他们思维和工作方式的独特“签名”。

PlayBit(又名luxor2008)

使用我们用来搜寻Volodya漏洞的相同技术,我们设法追踪了PlayBit编写的5个Windows LPE 1-day漏洞,以及作者多年来销售的其他工具。我们从REvil勒索软件使用的CVE-2018-8453样本开始,并使用PlayBits的独特指纹来寻找更多漏洞。

我们发现以下Windows LPE漏洞由作者实施为1-day:

  • CVE-2013-3660
  • CVE-2015-0057
  • CVE-2015-1701
  • CVE-2016-7255 – 这是Volodya的0-day
  • CVE-2018-8453

从技术上讲,PlayBit还出售了针对CVE-2019-1069(一个SandboxEscaper漏洞)和CVE-2020-0787的两个漏洞。但是,我们忽略这些漏洞,因为它们不是内存损坏漏洞,而是不同服务中的漏洞,因此具有不同的结构。

注意:关于PlayBit的更深入分析,以及他们开发和销售的不同漏洞,将在即将发布的博文中发布。

bool elevate(int target_pid)

Volodya的所有exploit样本中的API总是相同的。无论它是嵌入在一个恶意软件样本中,还是一个独立的POC,该漏洞都有以下签名的单一API函数:

  • bool elevate(int target_pid)

图4:调用elevate(target_pid)函数,可以在Cutter中看到。

该漏洞本身并不包括将shellcode注入到另一个进程或任何类似的功能。它向所需的进程授予系统特权,只接受其PID作为参数。

Sleep(200)

该elevate()函数在被恶意软件调用后所做的第一件事,是调用Sleep函数休眠200毫秒的固定时间。

图5:通过调用Sleep(200)来启动漏洞,如Cutter中所示。

为什么Sleep(200)会出现在模板中还不是很清楚。我们怀疑这是为了避免不必要的不稳定,特别是因为这些漏洞是基于时间安排(UAF races)。因此,短时间的等待与I/O和内存访问相关的活动结束,可以提高稳定性。

由于这些漏洞是恶意软件的一部分,在漏洞利用程序执行之前,所有这些与恶意软件相关的代码都会导致CPU / 磁盘 / RAM出现短暂的峰值,因此在进行实际漏洞利用之前让情况有所缓和可能是有意义的。对于短期峰值负载(在启动新进程,从磁盘读写文件等情况下自然会发生),它应该足足等待200毫秒。尽管我们在最近的示例中注意到这种模式的变化,但是仍然可以在我们发现的9个漏洞中找到该功能。

与PlayBit的比较:PlayBit在其利用中没有任何此类功能。

操作系统指纹

sleep函数结束后,该漏洞利用程序就会识别并校准目标的Windows版本,以便为尽可能多的OS版本提供支持。从我们的样本中,作者似乎使用了两种技术来查询操作系统。

  • (1) 解析ntdll.dll的头部 这是最常用的技术。ntdll.dll句柄用于查找 IMAGE_NT_HEADERS 的偏移量,从这里解析两个字段。 MajorOperatingSystemVersion MinorOperatingSystemVersion
  • (2) GetVersionEx() 该技术通常与前一种技术一起使用,仅在2016年至2017年初的样品中使用。这可能是因为这个API现在已经弃用了。

图6:调用GetVersionExW()以获取Windows版本,如Cutter所示。

在这两种技术中,目标都是查询操作系统的主版本和次版本,并相应地配置漏洞利用程序的全局变量。虽然大多数的利用都支持多种Windows版本,但Volodya似乎从不关心目标的特定服务包,也不关心它是否是Windows服务器。

除了对特定的Windows 10构建版本感兴趣之外(仅在CVE-2019-1458漏洞中使用),我们的actor只使用了主要版本和次要版本,仅此而已。

与PlayBit的比较:再次使用GetVersionEx(),通常随后还要对流程环境块(PEB)本身的主次编号进行额外解析,如图7所示。不仅使用PEB代替 ntdll.dll,PlayBit还从GetVersionEx()输出中提取额外的信息,如计算机的服务包(Service Pack),甚至检查目标计算机是否使用服务器操作系统。

图7:从PEB中提取主要版本和次要版本,如Cutter所示。

这是两个行动者在操作方式上的明显区别。它们不仅以不同的方式提取相同的信息,而且即使它们都利用了相同的漏洞(CVE-2016-7255), Volodya感兴趣的信息也远少于PlayBit。

通常,两个参与者都持有详细的特定于版本的配置,一旦确定了操作系统版本,他们就从这些配置加载相关信息。两者之间的主要区别是:

  • Volodya的漏洞利用代码流很少依赖于操作系统版本
  • PlayBit使用了多种依赖于操作系统版本的if-check来进行多重扭曲和旋转
  • 这反过来又影响了它们对确切版本细节的不同兴趣

内核地址泄漏

Leaking Kernel Addresses 在绝大多数漏洞利用中,操作者使用内核指针泄漏原语来调整漏洞利用。在除CVE-2019-1458之外的所有漏洞利用中,此漏洞原语都是众所周知的 HMValidateHandle 技术。

HMValidateHandle()是user32.dll的一个内部未导出函数,它被各种函数如isMenu()所利用,并可用于获取所有Windows版本(直到Windows 10 RS4)中不同Window对象的内核地址。这种技术很有名,早在2011年就开始使用了,当时大多数开发教程都选择专门解析isMenu()来找到HMValidateHandle()的地址。

令人惊讶的是,在数十个用于查找HMValidateHandle()的不同函数中,参与者只是简单地遵循了著名的教程,并选择了使用isMenu()。更令人惊讶的是,多年来,这种常见的利用技术仍然非常有效,使得参与者没有动力通过选择一个不太为人所知的函数(如CheckMenuRadioItem)来“隐藏”。

泄露给我们的信息如下:

  • 窗口的内核地址
  • THREAD_INFO(pti字段)的内核地址

该漏洞利用过程中的多个步骤将使用此信息,具体如下:

  • 地址在指向 / 创建假的内核结构体时使用
  • 确保我们的内核地址是有效的Unicode字符串(不包含两个连续的 ‘x00’ 字节)
  • 该pti用于定位一个有效的EPROCESS,然后其在令牌交换阶段中使用

与PlayBit的比较:PlayBit选择通过直接访问用户模式桌面堆来实现此功能。关于这个主题的更多内容,可以在未来关注这个actor的博文中找到。

Token Swap

该漏洞的最终目标是根据给定的PID参数将系统权限授予所需进程。传统上,实现这一点的方法是用系统进程的令牌替换 EPROCESS / KPROCESS 结构中的进程令牌。

下面是一些常用的技巧。您会惊讶地发现有多少不同的选项可以实现此功能。

(1) 使用Ps 符号(Using Ps * symbols) Windows内核包含以下与进程相关的函数和全局变量:

  • PsLookupProcessByProcessId 获取一个指向进程EPROCESS的指针
  • pinitialsystemprocess 全局变量,它保存着一个指向系统EPROCESS的指针
  • psreferencepprimarytoken 返回一个指向进程主令牌(token)的指针

通过在内核模式下执行这些函数,一个给定的shellcode可以很容易地定位系统的令牌,但是它仍然不能解决如何在所需的EPROCESS中分配它的问题。为此,有两种常见的解决方案:

  • 使用特定版本的偏移量直接访问EPROCESS内部的正确偏移量
  • 扫描EPROCESS,查找我们自己的指针(通过前面对PsReferencePrimaryToken的调用知道),一旦找到匹配的条目,就替换它

这种技术需要以内核模式执行代码,因此会被SMEP保护阻止,除非部署了额外的SMEP旁路。

(2) 扫描PsList

查找目标进程和系统进程EPROCESS的常见替代方法是扫描双向链接的进程列表,称为PsList。此技术涉及的步骤为:

  • 找到一个初始过程(使用泄漏的pti字段)
  • 扫描PsList以查找具有目标PID的EPROCESS
  • 通过查找PID为4或名称为的方式,扫描PsList以搜索SYSTEM的EPROCESS SYS*
  • 提取令牌并将其放置在目标进程中的匹配偏移量中
  • 谨慎更新SYSTEM令牌的引用计数

图8:使用任意读原语搜索SYS*的Volodya漏洞,可以在Cutter中看到。

这种技术需要PsList的主令牌和LIST_ENTRY的偏移量,要求它们都存储在特定于版本的配置中。

该技术的主要优点是,尽管它仍然可以作为一个简单的shellcode在内核模式下执行(正如CVE-2017-0263所做的那样),但它也可以在用户模式下完全实现。为此,您需要两个利用原语,一个用于任意读(来自内核空间),另一个用于任意写(进入内核空间)。在用户模式下运行解决了我们之前详细介绍的关于SMEP的问题,使这种保护对此类exploit原语毫无用处。

由于令牌是一个引用计数对象,因此正确注册刚刚添加的引用非常重要,以避免在升级的进程终止时出现蓝屏死机(BSOD)。事实上,有两种不同的引用计数:

  • 令牌是一个EX_FAST_REF对象-较低的指针位用作引用计数
  • 将anOBJECT_HEADER存储在令牌之前,并保留另一个引用计数

由于参与者选择更新后一个引用计数字段,因此需要执行以下步骤:

  • 从标记的指针中屏蔽掉refcount位——在32位进程上应该对齐到8字节,在64位进程上应该对齐到16字节
  • 减去指向OBJECT_HEADER的ref-count字段所需的常量
  • 读取值(使用任意读取的exploit原语)
  • 相应地增加它
  • 回写更新后的值

但是,如图9所示,我们在包含此功能的所有32位漏洞利用程序中发现了以下错误。

图9:32位漏洞利用中的引用计数更新中的实现错误。

读取引用计数值时对齐掩码对齐到8字节,而回写更新后的值时使用不同的掩码。如果令牌将被存储在一个对齐到8字节而不是对齐到16字节的内存地址中,写操作将更新错误的字段。

虽然CVE-2016-0040和CVE-2016-0167使用的是Ps*技术,但到目前为止,扫描PsList是我们的actor最喜欢的执行令牌交换的方式,在他们的8个漏洞中使用过。在其中的7个例子中,他们使用了用户模式的任意读和任意写。

与PlayBit的比较:在他们的所有样本中,我们总是看到PlayBit使用Ps*函数进行令牌交换。这一决定迫使参与者实现了一些SMEP绕过,他们将这些绕过集成到CVE-2016-7255和CVE-2018-8453的后续攻击中。这种设计选择解释了为什么参与者不麻烦地实现适当的任意读取原语作为利用的一部分。PlayBit不使用版本特定的配置来对EPROCESS中的令牌偏移量进行搜索,而是总是扫描EPROCESS来搜索它,通常使用0x300或0x600作为搜索的上限。

值得注意的是,PlayBit在不同的攻击中使用的内存破坏技术也被Duqu 2.0所使用,并在微软2015年的VB演讲中进行了分析。通过这种内存破坏,它们可以触发从内核内存到内核内存的一些内存读写,这将在攻击期间起到帮助作用。

图10:PlayBit漏洞扫描EPROCESS以搜索令牌,如Cutter所示。

尽管我们可以讨论其他方面,例如每个参与者在开发过程中喜欢使用的不同系统调用,对Windows和ScrollBars之类的已创建对象的命名约定,但我们相信上面的清单清楚地证明了我们方法的效率/有效性。从上面的列表可以看出,漏洞利用程序的几乎每个方面都可以几种不同的方式实现。尽管如此,我们的两个actor在各自的剥削程序上都非常一致,每个人都坚持自己喜欢的方式。

六.客户分析

在我们的整个研究过程中,我们想把重点放在开发作者本身,无论是Volodya, PlayBit或其他。然而,我们认为,通过观察这些利用作者的客户,还有很多东西要学习。Volodya的客户名单多种多样,包括Ursnif等银行家木马作者,GandCrab、Cerber和Magniber等勒索软件作者,以及Turla、APT28和Buhtrap等APT组织。有趣的是,我们可以看到Volodya的0-day更有可能卖给APT组织,而1-day则被多个犯罪软件组织购买。

由于没有进一步的情报,我们只能假设一旦0-day漏洞被安全行业检测到,该漏洞就会被回收,并以更低的价格作为非排他性的1-day漏洞出售。

APT的客户Turla、APT28和Buhtrap,都被普遍认为是俄罗斯的,有趣的是,即使是这些高级团队也购买漏洞,而不是自己开发。这是另一点,进一步加强了我们的假设,编写exploits可以作为一个单独的和不同的部分恶意软件处理。

下表总结并显示了我们能够归因于Volodya的CVE,以及使用这些漏洞发现的客户或恶意软件组。标有蓝色的CVE为0-day,自然更昂贵,左侧高亮显示的组被视为APT。

图11:Volodya的客户和他们使用的CVE。

在回顾我们在一段时间内检查漏洞样本时注意到的不同趋势之前,我们应该强调,我们的可见性有限,因为我们不能讨论尚未捕获的0-day。此外,我们只能尝试确定样本的年代,直到它们被捕获之前,但令人遗憾的是,我们通常基本上确定的是这种漏洞首次在野外被发现的时间。值得一提的是,Volodya在开发第一个漏洞(CVE-2015-2546)时就已经非常专业了。例如,它有一个独特的任意编写原语,我们无法追踪到任何其他的exploit教程或exploit。

在分析这些漏洞以及我们收集的数十个恶意软件样本的过程中,我们注意到一个有趣的变化。早期的Volodya漏洞作为源代码出售,以嵌入恶意软件中,后来的漏洞作为接受特定API的外部工具出售。这一变化表明Volodya采取了更多的预防措施。在2015年至2019年期间,我们也注意到Volodya的技术技能有了显著的提高。当他们变得更好和更有经验时,Volodya开始使用更有效的任意读和写原语,他们甚至修复了这些原语之间的一个bug。

CVE-2015-2546和CVE-2016-0165。此外,这些漏洞的代码变得更加模块化,因为大型函数被分割成更小的子例程。同时,他们在各种结构中搜索和访问特定偏移量的技术也得到了改进,在最近的实现中,它变得更加动态和安全,因为它在Windows的小版本中更好地处理了变化。

这不仅显示了我们actor的学习曲线和发展,也暗示了他们的技能。找到并可靠地利用Windows内核漏洞的能力并不是那么简单的。相比之下,PlayBit在2015-2018年期间在这个市场上非常活跃,他们的重点是销售1-day漏洞,其中之一是0-day的Volodya漏洞(CVE-2016-7255)。

七.结论

我们的研究方法是对漏洞利用作者的特征进行指纹识别,然后再将这些属性用作唯一的狩猎签名。在跟踪Volodya和PlayBit的漏洞时,我们两次部署了此技术。有了这两个成功的测试案例,我们相信该研究方法可用于确定其他漏洞利用程序作者。我们建议其他研究人员尝试我们建议的技术,并将其用作其武器库中的其他工具。

在这项研究中,我们重点研究了APT攻击和商品恶意软件(尤其是勒索软件)中不同恶意软件系列所使用或嵌入的漏洞。尽管它们很普遍,但我们经常发现详尽的恶意软件报告,而忽略了提及手边的恶意软件也利用漏洞来提升其特权的报告。

事实上,我们能够反复地使用我们的技术来跟踪16个Windows LPE漏洞,这些漏洞是由两个不同的角色编写和销售的,这是非常令人惊讶的。考虑到其中15个是在2015-2019年的时间框架内,我们有理由认为它们构成了开发市场的重要份额,特别是针对Windows LPE的开发。

最后,我们不可能说出Windows内核0-day漏洞的总数,这些漏洞正在被广泛利用。我们仍然可以通过观察被捕捉到的漏洞来获得洞见,同时记住这种生存偏差。去年,卡巴斯基报告说,一个单一的参与者分发了超过3个0-day的利用框架。把这些数字加起来,我们发现15个零日漏洞中有8个(超过一半的“市场份额”)是由两名actor完成的。这意味着我们的研究技术有可能被用于追踪“可视市场”中的许多威胁actor(可能不全)。

保护建议:Check Point威胁模拟可针对以下威胁提供保护。

  • Trojan.Wins.Generic.F
  • Trojan.Wins.Generic.G

前文分享:

  • [译] APT分析报告:01.Linux系统下针对性的APT攻击概述
  • [译] APT分析报告:02.钓鱼邮件网址混淆URL逃避检测
  • [译] APT分析报告:03.OpBlueRaven揭露APT组织Fin7/Carbanak(上)Tirion恶意软件
  • [译] APT分析报告:04.Kraken - 新型无文件APT攻击利用Windows错误报告服务逃避检测
  • [译] APT分析报告:05.Turla新型水坑攻击后门(NetFlash和PyFlash)
  • [译] APT分析报告:06.猖獗的小猫——针对伊朗的APT攻击活动详解
  • [译] APT分析报告:07.拉撒路(Lazarus)使用的两款恶意软件分析
  • [译] APT分析报告:08.伊朗APT34更新武器库——SideTwist变体
  • [译] APT分析报告:09.漏洞利用图谱–通过查找作者的指纹来寻找漏洞

2020年8月18新开的“娜璋AI安全之家”,主要围绕Python大数据分析、网络空间安全、逆向分析、APT分析报告、人工智能、Web渗透及攻防技术进行讲解,同时分享CCF、SCI、南核北核论文的算法实现。娜璋之家会更加系统,并重构作者的所有文章,从零讲解Python和安全,写了近十年文章,真心想把自己所学所感所做分享出来,还请各位多多指教,!谢谢。

附录-IOC表

Volodya

  • CVE-2015-2546 3f6fe68981157bf3e267148ec4abf801a0983f4cea64d1aaf50fecc97ae590d3
  • CVE-2016-0040 0ea43ba3e1907d1b5655a665b54ad5295a93bda660146cf7c8c302b74ab573e9
  • CVE-2016-0165* f1842080b38b3b990ba3ccc1d55ceedd901d423b6b8625633e1885f0dadee4c2
  • CVE-2016-0167 6224efee6665118fe4b5bfbc0c4b1dbe611a43a4b385f61ae33b0a0af230da4e
  • CVE-2016-7255 a785ad170a38280fc595dcc5af0842bd7cabc77b86deb510aa6ebb264bf2c092
  • CVE-2017-0001 ed7532c77d2e5cf559a23a355e62d26c7a036f2c51b1dd669745a9a577f831a0
  • CVE-2017-0263 f9dca02aa877ad36f05df1ebb16563c9dd07639a038b9840879be4499f840a10
  • CVE-2018-8641* 0829f90a94aea5f7a56d6ebf0295e3d48b1dffcfefe91c7b2231a7108fe69c5e
  • CVE-2019-0859 – Initial 64bit sample 895ab681351439ee4281690df21c4a47bdeb6691b9b828fdf8c8fed3f45202d8
  • CVE-2019-0859 – Matching 32bit sample eea10d513ae0c33248484105355a25f80dc9b4f1cfd9e735e447a6f7fd52b569
  • CVE-2019-1458 8af2cf1a254b1dafe9e15027687b0315493877524c089403d3ffffa950389a30

PlayBit

  • CVE-2013-3660 9f1a235eb38291cef296829be4b4d03618cd21e0b4f343f75a460c31a0ad62d3
  • CVE-2015-0057 8869e0df9b5f4a894216c76aa5689686395c16296761716abece00a0b4234d87
  • CVE-2015-1701 (yes, it is the same sample as CVE-2015-0057) 8869e0df9b5f4a894216c76aa5689686395c16296761716abece00a0b4234d87
  • CVE-2016-7255 5c27e05b788ba3b997a70df674d410322c3fa5e97079a7bf3aec369a0d397164
  • CVE-2018-8453 50da0183466a9852590de0d9e58bbe64f22ff8fc20a9ccc68ed0e50b367d7043

0 人点赞