攻击检测能力的抽象理解
2020-04-02 10:42:15 Author: www.4hou.com(查看原文) 阅读量:228 收藏

在2020年,SpecterOps 检测团队成员正在努力将他们发表的博客文章中提到的概念与Fidelity 漏斗联系起来。 Fidelity 漏斗是一个模型,SpecterOps 使用它来处理为了成功检测和补救攻击所必须经历的阶段。我们希望这能帮助读者理解这篇文章在他们整个检测程序中的位置。本文的重点是一个战略,可以适用于检测阶段的漏斗。

image.png

引言

这是 SpecterOps 检测团队发表的包括多个部分博客系列文章的第一篇。 本系列文章的目标是介绍和讨论基础检测工程的概念。 为了使这些概念尽可能地易于使用,我们将整个系列文章的重点放在 Kerberos 煅烧攻击上。 关注这个技术可以让读者专注于每篇文章中提出的策略,而不用担心技术本身的细节。 这篇文章的重点是一个我们称之为“能力抽象”的概念,其思想是,攻击者的工具仅仅是攻击能力的抽象,检测工程师必须了解在构建检测逻辑时如何评估抽象。

什么是抽象?

你可能想知道我说的“抽象”是什么意思,在本文的上下文中,抽象是一个概念,通过这个概念,实现细节对用户是隐藏的或自动化的。 抽象通常表现在被称为抽象层的层中,这些层系统地隐藏了复杂性,每个层提供了一个比上一个更表面的接口。 抽象是一个重要的设计元素,因为技术产品通常面向的用户基础从根本上不理解产品是如何工作的,但仍然可以从技术的使用中获益。 最终,抽象的主要目标之一就是隐藏事物复杂的内部工作机制,使它更容易被更广泛的受众接受。

抽象的第二个原因是简化与技术的交互。 在信息技术中,我们经常说,“如果你不得不多做一次,那就把它自动化。” 类似地,攻击者可能希望在其可接受的 OPSEC 约束范围内尽可能地简化其攻击过程。 我们可以从敌人使用的工具中看到这个概念。 每个工具都以公共接口的形式提供了一定程度的抽象,供操作符使用。

我相信,如果我们可以剥离抽象层来理解基本的攻击,我们就可以对检测攻击技术的最佳方法做出更明智的决定。

什么是 Kerberos 煅烧攻击?

在深入到能力抽象这个“兔子洞”之前,我想花一些时间讨论一下 kerberos 煅烧攻击。 在宏观意义上,Kerberos 煅烧是一种攻击技术,它允许攻击者将 Kerberos 票据授予服务票据(TGS 票据)转换为密码。 在微观(更详细)级别上,Kerberos 身份验证使用服务主体名称(SPN)唯一地标识服务实例。 每个 SPN 都将一个服务实例(比如 web 服务器、 SQL Server 等)关联到一个服务登录帐户。 要对远程系统进行身份验证,用户必须为 SPN 标识的目标服务请求 TGS 票据。 TGS 票证的一部分是使用与目标 SPN 关联的服务登录帐户的密码散列加密的。 对于 Kerberoast 攻击,攻击者提取出加密部分并尝试暴力破解该部分,直到成功为止。 一旦成功解密票据,他们就知道服务登录帐户的密码,可以假定该帐户的身份,并登录到该帐户可以访问的任何系统。

如果你有兴趣在继续之前更深入地挖掘 Kerberos 演示,我建议你查看 Tim Medin 的 Attacking Kerberos: Kicking the Guard Dog of Hades 的演示视频,他介绍了这个概念(幻灯片可以在这里找到)。 此外,harmj0y 已经写了一些关于这个话题的博客文章,特别是他的无  Mimikatz 的 Kerberos 煅烧攻击的文章,他的文章中有很多链接到许多其他关于这个话题的来源。

Kerberos 煅烧攻击的抽象

在整个讨论过程中,这篇文章使用了一个被称为“抽象图”的可视化图形,目的是帮助读者在讨论抽象层时了解它们之间的关系。其思想是在我们发现抽象层时揭示和跟踪它们。至此,我们还没有研究Kerberos 煅烧攻击,所以下面的初始抽象图是空的。

image.png

让我们开始吧!

工具

重要的是要考虑到攻击工具代表了最表面的抽象层; 然而,快速回顾一下公开共享的检测逻辑就会发现,维护者通常将检测工程的工作集中在特定于工具的签名上。 这些表面的检测本身并不是不好的,但在没有进一步的上下文数据的情况下,容易出现盲点(漏报)。评估抽象在攻击技术中的作用的目标是为检测工程工作提供信息。这个过程可以帮助避免错误的否定,了解潜在的遥测需求,了解新的攻击实现,并确定何时检测方法能够充分覆盖我们的目标技术。

Invoke-Kerberoast

Invoke-Kerberoast 是一个 PowerShell 高级函数,允许攻击者为目标帐户请求 Kerberos 服务票证。 除了请求服务票证,Invoke-Kerberoast 还提取票证的加密部分,并以一种可以使用流行的密码破解工具如 John the Ripper 和 Hashcat 离线破解的格式返回。 下面是在测试域中执行 Invoke-Kerberoast 请求票证的示例。

 image.png

Invoke-Kerberoast 执行

此时,kerberos 煅烧攻击的透视图仅限于一个工具(Invoke-Kerberoast)。 让我们用 Invoke-Kerberoast 来更新这个抽象图:

        image.png

在考虑到当前对这个问题的有限认识,对于检测工程师来说,为 Invoke-Kerberoast 创建一个简单的检测并收工是很常见的。 在这个抽象层中为 Invoke-Kerberoast 构建的检测可能集中在 PowerShell 函数名(Invoke-Kerberoast)、代码中的字符串(“@harmj0y”) ,甚至是脚本本身的密码散列。 这些都是伟大的第一步,忽略这些简单的检测是愚蠢的,但是当一个新的工具被释放来完成相同的攻击技术时会发生什么呢?

Rubeus 执行的 Kerberos 煅烧攻击

Rubeus 是一个包含许多滥用 Kerberos 功能的实用程序,但是“kerberoast”命令与 Kerberos 煅烧攻击特别相关。 事实证明,Rubeus 的 kerberoast 命令在功能上等同于 Invoke-Kerberoast,但其包装方式略有不同。

 image.png

Rubeus kerberoast 执行

现在可以更新抽象图,将 Rubeus 的 kerberoast 命令包含到工具层。

image.png

尽管 Invoke-Kerberoast 是用 PowerShell 编写的,而 Rubeus 是用 C# 编写的,但是正因为如此,它们在如何实现检测方面可能存在差异。 例如,PowerShell 函数名和 Invoke-Kerberoast 的加密散列与检测 Rubeus 无关。 相反,检测工程师可能专注于为命令行参数编写签名,或者可能使用 Rubeus 的加密散列创建其他检测。

正如你可以想象的那样,这种方法的可伸缩性非常差,因为 Kerberos 煅烧攻击 可能存在无限的工具实现变种。 相反,可以将工具视为最肤浅的抽象层,并深入研究 Invoke-Kerberoast 和 Rubeus 的实际功能。

托管代码

在这个过程中,已经确定了两个独特的 Kerberos 煅烧攻击利用工具。 现在重要的是要考虑 Invoke-Kerberoast和 Rubeus kerberoast 有什么共同点。 熟悉 PowerShell 和 C# 的人可能会记得,这两种语言都是构建在 .Net 框架之上,它本身就是一个抽象概念,它允许程序员专注于功能而不用担心复杂的编程主题,如内存管理、安全性、可移植性等。 记住这一点,当在托管代码层进行评估时,可以合理地预期这两个工具可能会显示一些相似之处。 通过比较从 Invoke-Kerberoast 和 Rubeus 请求服务票证的代码,可以发现它们都依赖于对 KerberosRequestorSecurityToken .NET 类 的构造函数重载的调用,如下所示:

 image.png

Invoke-Kerberoast 调用 KerberosRequestorSecurityToken 的构造函数

 image.png

Rubeus 调用 KerberosRequestorSecurityToken 的构造函数

正如你所看到的,虽然这些工具是用不同的语言编写的,但它们最终都依赖于 KerberosRequestorSecurityToken 类。 理论上,如果可以构建一个检测方法来关注这个特定类的使用,那么就可以实现使用单一方法检测两个工具。

是时候为“托管代码”的抽象图添加一个新层了,注意,这个层有一个条目,涵盖了两个工具实现。

image.png

希望剥离抽象的价值开始变得清晰起来。 然而,重要的是要注意,虽然剥离抽象层允许更广泛或全面的检测,这也意味着检测可能失去精确度,这导致产生更高的误报的可能性。 例如,.NET中的KerberosRequestorSecurityToken类的合法用例是什么?分析师如何区分合法使用和恶意使用? 这是我的一个同事将在未来的博客文章中更深入讨论的话题。

Windows API 函数

假设你编写了一个检测逻辑,来检测当KerberosRequestorSecurityToken .NET类被使用出发告警。 你是否应该停下来考虑 ,将 Kerberos 煅烧攻击视为一个已经解决的问题? 如果有人使用不与 .NET 交互的语言编写 Kerberos 煅烧攻击利用工具会发生什么? 也许他们决定用 C++ 编写。 那么,正如前面提到的,. Net 本身就是一个抽象层,所以让我们深入挖掘一下,看看底下发生了什么。

幸运的是 .Net 是开源的,所以源代码(.Net 参考源代码)是容易访问的。 使用引用源,检测工程师可以深入研究 KerberosRequestorSecurityToken 类的实现,以了解它在底层是如何工作的。 经过一番调查,我们发现 Invoke-Kerberos 和 Rubeus 的 kerberoast 命令所使用的 KerberosRequestorSecurityToken 类的功能(构造函数)是在 security32.dll 的两个 Windows API 函数上构建的,即 AcquireCredentialsHandleInitializeSecurityContext

Windows API 是一组函数,允许程序员以预定义和文档化的方式与操作系统交互。 可以把它们看作是另一个抽象层,规定了软件如何与硬件组件(如内存、网络接口或输入设备)进行交互。 理论上,攻击者也可以调用 InitializeSecurityContext 而无需通过 KerberosRequestorSecurityToken  .Net 类。

下面的截图来自于  .Net 引用源,显示了  .Net 通过名为 Platform Invoke (P/Invoke)的概念实现了 AcquireCredentialsHandleW 和 I InitializeSecurityContextW

image.png

.NET 引用源 — AcquireCredentialsHandleW

image.png

.NET 引用源 — InitializeSecurityContextW Net

因此,这个函数提供了另一个层次,检测工程师可以在这个层次中构建检测逻辑。

 image.png

一个合理的假设是,使用非 .Net语言编写的Kerberos 煅烧攻击工具也会使用InitializeSecurityContext API函数。让我们看看用C++编写的一个工具,看看这个假设是否正确。

几乎信息安全领域的每个人都熟悉 mimikatz 这个工具,它允许攻击者从内存中转储明文密码。 很少有人知道 mimikatz 是一个复杂的工具,它提供了许多功能,其中之一就是能够为 kerberos 煅烧攻击请求任意的服务票证。 下面的图片显示了 mimikatz 被用来请求与我们使用Invoke-Kerberoast和Rubeus请求的相同的服务票据。。

image.png

Mimikatz kerberos::ask 命令执行

Mimikatz 的 kerberos::ask 命令现在可以添加到支持 kerberos 煅烧攻击工具列表中,如下所示:

image.png

现在,检测工程师如何确定 mimikatz 是否基于 InitializeSecurityContext? mimikatz 工具是开源的,因此可以检查源代码,看看 mimimikatz 是否调用了 InitializeSecurityContext。

查看 kerberos::ask 命令的源代码,你会发现它是由 kuhl_m_kerberos_ask 函数实现的。

image.png

kuhl_m_kerberos_ask 函数调用一个名为 LsaCallKerberosPackage 的函数。

image.png

LsaCallKerberosPackage 函数最后调用一个名为 LsaCallAuthenticationPackage 的 Windows API 函数。

image.png

看来这个逻辑上的假设是不正确的。 Mimimitz 没有调用 InitializeSecurityContext,而是调用了 LsaCallAuthenticationPackage。 似乎至少有两个 Windows API 函数可以请求服务票据。 让我们花一点时间来更新我们的抽象图。

 image.png

现在你可能知道下一个需要回答的问题了! 在 InitializeSecurityContext 和 LsaCallAuthenticationPackage 之间有共同点吗?

远程过程调用

看起来至少有2个 Windows API 函数可以用来请求服务票证,但是这些 API 函数会在下面汇聚成一个共享的抽象层吗? 为了帮助解决这个问题,我与 Matt Graeber (@mattifestation)一起分析了 security.dll (两个函数都存在的库)。 在我们的分析过程中,我们发现 InitializeSecurityContext 和 LsaCallAuthenticationPackage 都进行了 RPC 调用。 进一步检查表明,这两个 API 函数与 RPC 接口交互,UUID 为4f32adc8-6052-4a04-8701-293ccf2096f0。

在 Google 上快速搜索 UUID,返回了 Matt Nelson 的(@enigma0x3) GitHub 摘要,其中他列出了机器上的所有 RPC 接口。 下面的屏幕截图显示了所讨论的 RPC 接口是由 sspisrv.dll 实现的。

image.png

如果你有兴趣更深入地了解这是如何发现的,可以看看 Adam Chester (@_xpn_)的优秀文章“探索 Mimikatz 第二部分”。 在他的文章中,Adam 解释了他是如何检查了一个与我们遇到的非常类似的情况,这个情况涉及 mimikatz 的安全支持提供者(Security Support Provider)能力的内部工作。

现在可以在抽象图中添加一个新的“RPC”层,以显示 InitializeSecurityContext 和 LsaCallAuthenticationPackage 最终如何依赖于幕后相同的 RPC 调用。

image.png

网络协议

你可能会问自己,“难道攻击者不必先调用我们讨论过的 API 函数之一来发出网络请求吗? ” 答案可以在我们的老朋友 Rubeus 那里找到。 Rubeus 有许多专注于滥用 Kerberos 协议的功能。 “ kerberoast”功能在前面已经介绍过了,但是另一个名为“asktgs”的命令允许攻击者通过构建原始的 TGS-REQ 包并解析原始的 TGS-REP 响应来请求服务票证。 可以把这看作是 Kerberos 煅烧攻击可持续的,本地的,手动式的人肉方法。 如下图所示:

 image.png

Rubeus asktgs 命令执行

在此必须更新抽象图,以便在工具层包含 Rubeus 的 asktgs。 不幸的是,这个实现与迄今为止所发现的任何抽象层都没有重叠。 这听起来像是一个更深入挖掘的机会!

 image.png

从根本上讲,Kerberos 是一种网络身份验证协议,用户通过一个称为 Kerberos 密钥分发中心(KDC)的中心实体进行身份验证。 Kerberos 煅烧攻击需要请求一个服务票据或多个服务票据,以方便离线密码破解。 要发出这个请求,必须建立从客户机到 KDC 的网络连接,并且网络请求必须采用票据授予服务请求的形式(TGS-REQ)。

下面是 Invoke-Kerberoast,Rubeus kerberoast, mimikatz 的 kerberos::ask 和 Rubeus asktgs 的数据包。 请注意,虽然数据包在捕获中存在细微差别,但每个工具都发出了相同的 TGS-REQ 请求,并在下面的每张图片中突出显示。

 image.png

Wireshark 捕获的 Invoke-Kerberoast 数据包

image.png 

Wireshark 捕获的 Rubeus kerberoast 数据包

 image.png

Wireshark 捕获的 Mimikatz kerberos::ask 数据包

 image.png

Wireshark 捕获的 Rubeus asktgs 数据包

抽象图通过添加覆盖所有 Kerberos 煅烧攻击实现的网络协议层来完成。 请记住,尽管 RPC 和网络协议层对 kerberos 煅烧攻击的实现更具包容性,但它们对合法活动也更具包容性。 简单地说,在较低的抽象层上构建检测并不总是理想的。 

image.png

请记住,这个抽象图可能不会考虑 Kerberos 煅烧攻击所涉及的每一个可能的抽象。 你能想到任何额外的抽象层吗? 如果有,请在评论中分享你的想法!

总结

我经常听到攻击者在谈论,了解他们的攻击工具如何工作是多么重要,但是我很少从我的从事防御工作的圈子中听到类似的观点。 我经常看到一个检测工程师从表面上看待攻击工具。理解攻击性能力是如何被抽象出来的,为检测工程师提供了一个机会,以一种明智的方式来评估他们的检测方法。我相信,通过花更多的时间来理解工具从我们身边抽象出来的技术,我们将能够提高标准,不仅检测我们所知道的,而且也检测我们所不知道的。能力抽象只是你可以添加到你的检测工程工具箱中的一个工具。

本系列的下一篇文章将解释在不同的抽象层上理解检测的优缺点的策略,以及如何利用一个抽象图来确定分层检测逻辑的最有效方法,从而创建一个全面的检测方法。

本文翻译自:https://posts.specterops.io/capability-abstraction-fbeaeeb26384如若转载,请注明原文地址:


文章来源: https://www.4hou.com/posts/A9Zj
如有侵权请联系:admin#unsafe.sh