威胁检测与搜寻建模11.隐式进程创建

admin 2024年1月23日11:14:35评论12 views1字数 9499阅读31分39秒阅读模式

介绍

欢迎回到“威胁检测与搜寻建模”系列的另一部分。在上一篇文章中,我认为我们在操作级别感知环境中的操作(尤其是当涉及到端点事件时),这意味着我们也应该在操作级别“构思”攻击者的交易技巧。在这篇文章中,我想说明为什么概念和感知之间的这种融合如此重要。考虑到这一点,我想探讨我在检测工程 (DE) 中看到的一个常见问题;即“基于过程的检测”。

 

 

何塞·路易斯·罗德里格斯(Jose Luis Rodriguez)在描述MITRE ATT&CK中表示的数据源的拟议更新的帖子中分享了以下图表:

威胁检测与搜寻建模11.隐式进程创建
信用:https://medium.com/mitre-attack/defining-attack-data-sources-part-i-4c39e581454f

此图是基于技术与其相关数据源之间的关系创建的,因为它们最初在 ATT&CK 中表示。快速浏览这些数字表明,“进程监视”和“进程命令行参数”是最常见的关联数据源。事实上,在制作此图表时(即 2020 年 9 月),“过程监控”涵盖了 234 种不同的技术。那么,这对检测工程师意味着什么呢?乍一看,不能责怪人们假设如果他们有过程监控,他们就有足够的数据来检测绝大多数技术。然而,事实并非如此。

根据 MITRE ATT&CK 设计和理念白皮书,“数据源”被定义为“传感器或记录系统收集的信息源,可用于收集与识别正在执行的操作、操作顺序或对手这些操作的结果相关的信息。数据源列表可以包含如何为特定(子)技术执行操作的不同变体。此属性旨在限制为定义的列表,以便允许基于唯一数据源分析技术覆盖率。(例如,“如果我有过程监控,我可以检测哪些技术?

短语“收集与识别正在执行的操作相关的信息”告诉我们,从数据源到技术的映射并不表示数据源足以检测行为。相反,这些映射旨在指示数据源可能提供与该技术相关的可能有价值的上下文。

不幸的是,我们中的许多人似乎将 Jose 的图表解释为,“如果我有过程监控,可以检测到 234 种技术”,而不是“流程监控为多达 234 种不同的技术提供了潜在的有价值的上下文”。在这篇文章中,我希望演示为什么过程监控通常不能为可靠的检测提供足够的上下文。这个问题我称之为“隐式进程创建操作”。

进程创建是否足够?

这是否意味着所有基于进程的检测都应被视为签名?好吧,正如任何优秀的顾问都会回答的那样,这取决于。为了更彻底地回答这个问题,我们必须了解在攻击者的贸易和技术的背景下如何创建流程。在本节中,我希望演示隐式进程创建(即,当创建进程以执行恶意代码但在相关操作链之外时)和显式进程创建(即,当进程创建为技术操作链的一部分时)之间的区别。本文的其余部分将探讨四种示例技术,两种隐式和两种显式,以说明为什么使用相同的数据源可以在某些情况下提供整体覆盖,而在其他情况下则不能。按照本系列中介绍的样品分析过程,您应该能够轻松辨别您面对的样品/技术类型。

隐式进程创建

示例 1:创建服务

我们的第一个示例是简单的服务创建或 T1543.003 创建或修改系统进程:Windows 服务。Windows 附带了一个内置实用程序,称为它,它有助于 Windows 服务的创建、枚举、管理等。下面是用于检测服务创建的常见检测规则的示例。您会看到,它专门查找一个名为的进程和一个命令行参数,其中包括字符串,它是 的子命令。sc.exesc.execreatesc.exe

https://github.com/SigmaHQ/sigma/blob/d68f19a88e1fc7c9f82918b3f374e840518e82fd/rules/windows/process_creation/proc_creation_win_sc_create_service.yml

如果我们分析,我们可以开始了解该工具在引擎盖下是如何工作的。在这里,我在 IDA Pro 中打开了该工具并导航到该功能。到达那里后,我查找了在发出子命令时将执行的代码路径。在下面的屏幕截图中,我们看到一个 if 语句将字符串 () 与字符串进行比较。如果它们匹配,则执行后续代码。我们看到三个函数,如下所示:sc.exewmaincreatev10create

  • 第一个函数 , 是一个帮助程序函数,用于在未提供正确参数时显示此子命令的命令行语法CreateUsage
  • 第二个函数是 API 函数(即 ),它打开本地或远程计算机上的服务控制管理器 (SCM) 的句柄(由第一个参数指定)OpenSCManagerWlpMachineName)
  • 第二个参数指定目标服务数据库的名称;如果为 null,则默认打开SERVICES_ACTIVE_DATABASE
  • 最后一个参数是对 SCM 的所需访问权限

在这里,我们看到值设置为 ,这相当于根据子命令的目的有意义的值。需要注意的是,此函数的输出(即 SCM 的句柄)将返回给变量,该变量随后被传递给我们接下来将要介绍的内部函数。2SC_MANAGER_CREATE_SERVICEcreatev5DoCreateService

威胁检测与搜寻建模11.隐式进程创建

该函数有很多参数解析,但该函数的核心可以在下面的屏幕截图中看到。在这里,我们看到对 API 函数的调用。我们还可以看到,与上一次调用的 SCM 句柄相对应的变量作为第一个参数传递。然后,我们看到一堆关于正在创建的服务的详细信息正在传递,例如服务名称 ()、服务类型 ()、服务启动类型 () 以及服务启动时要执行的命令行 ()。DoCreateServiceCreateServiceWa1OpenSCManagerWlpServiceNamedwServiceTypedwStartTypelpBinaryPathName

注意:有趣的是,尽管该参数被调用,但它实际上并不局限于二进制文件的文件路径。它实际上是一个带有参数的命令行,因此在此参数中指定的二进制文件及其参数的绝对或相对路径并不少见。lpBinaryPathName

接下来,我们看到该函数,但并非所有代码路径中都调用此函数;为简单起见,我们将忽略它。同样,仅当函数调用失败时才调用该函数。相反,我们将通过调用 来完成分析,它只是关闭从 返回的新创建的服务的句柄。此调用并没有什么特别之处,但最好在不再需要句柄时关闭句柄。ChangeServiceConfig2WDeleteServiceChangeServiceConfig2WCloseServiceHandleCreateServiceW

威胁检测与搜寻建模11.隐式进程创建

分析完成后,我们可以用以下函数链来总结 的子命令的功能:sc.execreate

威胁检测与搜寻建模11.隐式进程创建
的 create 子命令的功能链sc.exe

然后,我们可以使用函数调用堆栈最终派生出以下操作链:

威胁检测与搜寻建模11.隐式进程创建
sc.exe 的 create 子命令的操作链

为什么这很重要?请注意,操作链由三个操作组成:、 和 。具有最低编程能力的攻击者可以在一个全新的工具中重新实现这些操作。另请注意,此操作链中不包含“”操作。那么,当工具的行为不包括进程创建时,我们怎么可能创建一个专注于进程创建(例如 Sysmon 事件 ID 1)的检测规则呢?SCM OpenService CreateHandle CloseProcess Create

答案是,进程创建对于任何应用程序的执行都是隐式的(在本例中)。为了运行代码,代码必须在进程的上下文中运行,这意味着始终存在与恶意代码执行关联的进程创建事件。但是,由于此功能可以隐藏在任何任意进程后面,这并不一定意味着我们应该依赖进程创建作为主要数据源。任意点很重要,因为这意味着从检测工程的角度来看,它是不可预测的。sc.exe

示例 2:whoami

让我们看第二个例子。一种常见的检测方法是查找发现命令。一个特别有趣的发现命令是 。之所以值得注意,是因为普通的合法用户相对不太可能需要问这个问题。一般来说,当用户合法登录时,他们知道自己是谁;在某些情况下,提出问题本身就被认为是可疑的。因此,我们经常看到一个简单的高保真规则来检测执行情况,如下例所示:whoami.exewhoami.exewhoami.exe

https://github.com/SigmaHQ/sigma/blob/d68f19a88e1fc7c9f82918b3f374e840518e82fd/rules/windows/process_creation/proc_creation_win_whoami_execution.yml

这个例子最近对我来说很突出,因为弗洛里安·罗斯(Florian Roth)和丹尼尔·卡德(Daniel Card)正在讨论在上下文中执行的创造性方法。他们的例子包括下载并使用它来运行,以及创建一个计划任务来做同样的事情。这让我想知道引擎盖下到底在做什么;这样,我就可以重新创建功能,而无需从字面上执行此工具。whoami.exeSYSTEMpsexecwhoamiwhoami.exe

再一次,我在 IDA Pro 中打开并开始深入研究。这样做时,我们遇到的第一个函数是函数,它调用 和 函数。这些函数的目的是打开调用进程 () 的伪句柄,然后将该进程句柄用作输入,以打开与该进程关联的访问令牌的句柄。接下来,我们看到一组对内部函数的调用。该函数特别令人感兴趣,因此我们接下来将深入研究。whoami.exeWsUser::InitGetCurrentProcessOpenProcessTokenwhoami.exeWsAccessToken::InitUserSid

威胁检测与搜寻建模11.隐式进程创建

到达 到达后,我们会看到对函数的调用,该函数专门要求提供返回令牌用户上下文的安全标识符 (SID) 的信息类。此 SID 表示“我是谁”这个问题的答案。WsAccessToken::InitUserSidGetTokenInformationTokenUser

威胁检测与搜寻建模11.隐式进程创建

现在我们已经完成了代码分析,我们可以生成一个由以下三个函数组成的函数链:.GetCurrentProcess -> OpenProcessToken -> GetTokenInformation

威胁检测与搜寻建模11.隐式进程创建
whoami.exe 的功能链

我们可以再次泛化操作上实现的行为,其中我们看到获取了当前进程的句柄(),打开了与当前进程关联的令牌的句柄(),并查询了该令牌以确定与令牌关联的用户帐户。请注意,没有操作。whoami.exeProcess OpenToken OpenProcess Create

同样,为什么我们要基于甚至不包含在相关操作链中的操作来构建检测?

威胁检测与搜寻建模11.隐式进程创建
whoami.exe 的操作链

然后,我们可以创建一个“自定义工具”来实现此函数/操作链,该工具将绕过专注于不存在(隐式)操作的检测。下面是基于我的 PSReflect-Function PowerShell 模块构建的示例实现。此实现获取相同的输出(调用用户帐户的名称),而无需创建名为 的进程。Process Createwhoami.exe

威胁检测与搜寻建模11.隐式进程创建

显式进程创建

在上一节中,我们分析了两个不包含显式操作的示例操作链。此时,您的结论可能是,基于与流程创建相关的事件的检测本质上是以工具为中心的;但是,在本节中,我们将分析另外两种技术,其中操作是操作链的显式组件。这将更改与进程创建相关的检测规则的值。Process CreateProcess Create

示例 3:WMI 横向移动

使用显式操作的第一个示例是在所谓的 WMI 横向移动中找到的,或者根据 ATT&CK 的说法,是 T1047 Windows Management Instrumentation。特别是 WMI 的类,它实现了一种名为该方法的方法,该方法有助于本地或远程创建任意进程。远程组件专门为横向移动提供了出色的基元。Process CreateWin32_ProcessCreate

Win32_Process类的 Create 方法 - Win32 应用

创造 WMI 类方法创建一个新进程。

learn.microsoft.com

如果您有兴趣了解有关 WMI 内部结构的详细信息,我强烈推荐 Jonathan Johnson 的 WMI 内部结构博客系列。在本系列中,他介绍了 WMI 类、方法、提供程序和许多其他功能。

我想花点时间认识到像 Jonny 这样的博客文章是多么有用,这些文章走过了查找信息的战术过程。我基本上不记得用于派生此信息的 PowerShell 语法,因此我发现自己每次使用 WMI 提供程序时都会引用 Jonny 的帖子。

在第 1 部分中,Jonny 提供了派生实现特定 WMI 类的 WMI 提供程序(通常是动态链接库 [DLL] 文件)的文件路径所需的 PowerShell 命令。为了便于使用,我已将他的命令改编为 PowerShell 函数,该函数接受 WMI 类的名称并输出提供程序的文件路径。该函数在下面的要点片段中共享。

现在,我们可以在 Windows 计算机上执行 Get- 函数来标识实现该类的提供程序。WmiProviderPathWin32_Process

威胁检测与搜寻建模11.隐式进程创建
使用 Get-WmiProviderPath 函数将 cimwin32.dll 标识为 Win32_Process 类的 WMI 提供程序。

现在,我们已经找到了实现该类的提供程序,我们可以查看实现。在反汇编程序中打开提供程序后,我们的第一个问题是应该从哪里开始分析?为了回答这个问题,了解如何实现远程 WMI 方法调用非常重要。Win32_Process

WMI 依赖于远程过程调用 (RPC) 在远程系统上执行方法。具体而言,该过程有助于在远程系统上执行 WMI 方法。此过程需要 7 个参数,其中前两个参数分别指定 WMI 类 () 和 WMI 方法 ()。IWbemServices::ExecMethodstrObjectPathstrMethodName

[MS-WMI]:IWbemServices::ExecMethod (Opnum 24)

IWbemServices::ExecMethod 方法执行由 CIM 类或 CIM 实例实现的 CIM 方法。

learn.microsoft.com

首先,让我们搜索名称中包含字符串的内部函数。当我们这样做时,我们发现提供程序实现的每个 WMI 类都有一个函数。例如,我们看到类、类和类。由于我们有兴趣研究类方法的实现,因此我们应该检查该函数。ExecMethodExecMethodProvider::ExecMethodWin32_ProviderProcess::ExecMethodWin32_ProcessLogicalDisk::ExecMethodWin32_LogicalDiskWin32_ProcessCreateProcess::ExecMethod

威胁检测与搜寻建模11.隐式进程创建

在函数中,我们看到一系列条件语句,这些语句似乎将参数与与类实现的方法(即 、 、 等)相对应的字符串进行比较。在本例中,代码显示,当指定方法时,将调用 。我们可以按照该函数继续分析。Process::ExecMethoda3CreateTerminateGetOwnerCreateProcess::ExecCreate

威胁检测与搜寻建模11.隐式进程创建
Process::ExecMethod 函数检查调用方指定了哪个方法。

在遵循一些内部函数调用后,我们看到了实际的 Windows API 函数。能力的关键在于功能。这向我们展示了该方法的实际工作原理。我们看到该方法用作包装器,以允许执行函数。CreateProcessAsUserWWin32_Process::CreateCreateProcessAsUserW

威胁检测与搜寻建模11.隐式进程创建
对 CreateProcessAsUserW 函数的调用,该函数是调用 Win32_Process 类的 Create 方法的结果。

我包含了该方法实现的简化函数链。在这里,我们看到 ,它打开了调用线程的伪句柄;然后,这将打开与调用线程关联的令牌。我没有一直跟踪它,但通常 RPC 服务器会模拟 RPC 客户端,因此此令牌将与该模拟相关。接下来,我们看到对的调用,它允许后续调用 ,特别是查询信息类。最后,我们看到提供给函数的信息以创建请求的进程,在恶意示例中,该进程将是有效负载。CreateGetCurrentThreadOpenThreadTokenDuplicateTokenExGetTokenInformationTokenUserCreateProcessAsUserW

威胁检测与搜寻建模11.隐式进程创建
WMI 横向移动示例的函数链

然后我们可以推导出操作链,它由 .此时,您应该注意到该链包含一个操作。这与前面的示例有很大不同,在前面的示例中,操作是纯隐式的。Thread Open -> Token Open -> Token Duplicate -> Token Query -> PROCESS CREATEProcess CreateProcess Create

威胁检测与搜寻建模11.隐式进程创建
WMI 横向移动示例的操作链

然而,这带来了一个新问题。在本例中,现在有两个操作:一个是隐式操作,另一个是显式操作。我们可以回顾一下另外两个 Sigma 规则,看看这种二分法是如何发挥作用的。Process Create

规则 1:wmic 进程调用创建

第一条规则查找映像(即正在执行的进程)所在的进程创建事件,并且(即命令行参数)包含字符串 、 和 。这是因为 Windows Management Instrumentation 控制台 (WMIC) 是用于与 WMI 交互的内置传统应用程序,如果使用 WMIC 执行该方法,命令行将类似于 .但是,有一个问题;如果攻击者使用 PowerShell 或创建了自定义工具,该怎么办?此检测规则是专门为此技术的规范变体而构建的,但它不会泛化以捕获替代变体。这样做的原因是,此规则侧重于隐式操作。wmic.exeCommandLineprocesscallcreateWin32_Process::Createwmic.exe process call createInvoke-WmiMethodProcess Create

规则 2:wmiprvse.exe 的子级

第二条规则侧重于检测进程创建事件,其中(即父进程)为 。之所以创建此父/子关系,是因为进程加载了有助于远程 WMI 请求的 DLL ();因此,当调用该方法时,将在进程的上下文中调用该函数。ParentImagewmiprvse.exewmiprvse.execimwin32.dllWin32_Process::CreateCreateProcessAsUserWwmiprvse.exe

此事件与我们正在寻找的显式操作有关。这种显式的额外好处是,此操作的显式性质通常使事件的某些方面成为静态的或可预测的。虽然我们不知道将通过此方法执行哪些应用程序的具体细节,但我们确实知道该应用程序将作为 的子项执行。对于隐式操作,情况并非如此。在这种情况下,我们无法可靠地预测所有可能的变化的特征。Process CreateProcess Createwmiprvse.exeProcess Create

这个例子希望能证明:

  1. 在某些操作链中,操作可能是显式的Process Create
  2. 当存在显式操作时,我们必须区分始终存在的隐式操作和唯一显式操作Process Create
  3. 显式操作通常具有某种静态功能(在本例中为父进程),允许检测工程师归零Process Create

示例 4:工艺镂空

我们发现存在显式操作的技术的另一个示例是工艺空心化,或者,对于那些在 ATT&CK 中遵循的人,T1055.012 工艺注入:工艺空心化。对于此特定示例,我使用了 Malware Analyst's Cookbook 中描述的源代码。如果你想看看源代码,我鼓励你看看这本书,因为里面有大量很棒的金块。Process CreateRecipe 15–8

以下是书中描述的功能链。请注意,链稍长一些,这表明此实现可能稍微复杂一些。我们看到它从对函数的调用开始,该函数用于创建一个“牺牲过程”来掏空。此过程的一个关键功能是它将在“挂起状态”下创建,因为该标志被设置为函数调用的参数。接下来,我们看到 ,它表示一个序列,其中与牺牲过程相关的合法代码被掏空并被恶意代码替换。确保以允许执行的方式编写新的恶意代码涉及很多复杂性,但我们将在此处跳过这些细节。CreateProcessACREATE_SUSPENDEDNtUnmapViewOfSection -> VirtualAllocEx -> WriteProcessMemory -> WriteProcessMemory

接下来,我们看到 ,它负责调整挖空进程主线程的执行上下文,以指向“注入”的恶意代码的入口点,以代替原始可移植可执行文件 (PE)。我们最终得到以下函数链:GetThreadContext -> SetThreadContext -> ResumeThread

威胁检测与搜寻建模11.隐式进程创建
过程镂空样品的功能链

然后,我们可以推导出分别由操作组成的操作链。同样,这个操作链的关键发现是我们发现存在一个显式操作;因此,下一个合乎逻辑的问题是,“这个操作如何使它可预测,因此可观察?PROCESS CREATE -> Section Unmap -> Memory Allocate -> Process Write -> Process Write -> Thread Read -> Thread Write -> Thread ResumeProcess CreateProcess Create

威胁检测与搜寻建模11.隐式进程创建
工艺镂空样品的操作链

这里的关键功能是使用标志启动该过程。虽然此功能通常不包含在报告流程创建的所有事件中,但该功能本身在理论上是可观察的。与我们的 WMI 横向移动示例类似,在执行此操作链时,将同时存在隐式和显式操作。隐式将与实现进程空心的实用程序相关。通常,与此实用程序相关的详细信息是不可预测的。另一方面,显式与“牺牲过程”有关,该过程将被掏空以最终执行恶意代码。攻击者再次完全自由地选择他们用作牺牲过程的应用程序;但是,至少对于此特定操作链,挂起的初始状态是一致的。因此,如果我们能观察到一个进程是在暂停状态下创建的,我们可以收集到它可能会被掏空。请务必记住,所有进程空心化实例都将在挂起状态下创建,但并非所有在挂起状态下创建的进程都表示进程空心化。CREATE_SUSPENDEDProcess CreateProcess CreateProcess Create

结论

本文的目的并不是说所有基于进程创建的检测都是脆弱的。需要指出的是,并非所有流程创建事件都是平等的;流程创建是某些技术的关键组成部分,而许多其他技术则是附带的;并且单个事件在不同情况下可能具有不同的侦探能力。

我希望我已经证明了理解技术如何工作的效用,以可理解的方式映射该理解,并将该理解转换为检测规则。同样重要的是要了解,即使操作链明确包含操作,我们也必须谨慎,以确保我们选择正确的流程来关注。我们还必须努力确定保持足够静态的特征,以便于预测结果(即可预测的父进程或挂起状态)。Process Create

最后,我会给你一个想法。长期以来,关于检测工程领域两个相对抽象概念的含义一直存在争议:即“基于签名的检测”与“基于行为的检测”。一般来说,签名侧重于实现(什么),而行为侧重于工具和操作系统之间的交互(如何)。虽然这种理解提供了一个很好的启发式方法,但我发现存在一个很大的灰色地带,很难区分两者。我的建议是,我们可以使用操作链来确定检测规则是否专注于行为。我的意思是,如果检测集中在不是操作链的显式组件(例如,隐式)的操作上,那么它就完全适合签名类别。另一方面,如果检测基于明确包含在操作链中的操作(即显式、、等),则它是行为的。Process CreateProcess CreateToken QueryService Create

 

原文始发于微信公众号(安全狗的自我修养):威胁检测与搜寻建模11.隐式进程创建

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年1月23日11:14:35
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   威胁检测与搜寻建模11.隐式进程创建http://cn-sec.com/archives/2421486.html

发表评论

匿名网友 填写信息