构建 Huntbook 以发现来自计划的 Windows 任务的持续威胁
Xiaokui Shu和Ian Molloy · 2021 年 7 月 26 日 · 9 分钟阅读
from: https://opencybersecurityalliance.org/posts/kestrel-2021-07-26/
在这篇博文中,是介绍 Kestrel 威胁狩猎语言的系列文章的第一篇,我们将向您展示如何开始您的第一次狩猎。您将学习如何设置环境、连接到数据源以及搜索常见的攻击技术,即Windows 中的计划任务。您还将熟悉可用于构建自己的狩猎簿的基本概念。 从该博客创建的Windows 计划任务 Huntbook可以从Kestrel 狩猎簿存储库下载。
让我们设置我们的监控堆栈并通过对计划的 Windows 任务进行推理来执行 Kestrel搜寻持久性 Windows 威胁。
Kestrel安装
首先,我们将遵循Kestrel 安装指南并在带有 Python 3.9 的 Linux 狩猎盒上的 Python 虚拟环境中安装 Kestrel。
接下来,创建一个干净的 Python 虚拟环境并激活它:
$ python -m venv huntingspace
$ . huntingspace/bin/activate
接下来,使用 Jupyter notebook 内核安装 Kestrel 运行时:
$ pip install -U pip setuptools wheel
$ pip install kestrel-jupyter
$ python -m kestrel_jupyter_kernel.setup
此步骤将安装所有 Kestrel 运行时组件和依赖项,例如 STIX-shifter以及Jupyter Server,以使用 Kestrel 内核。
设置数据源
大多数组织使用 EDR 来监控他们的 Windows 主机并收集遥测数据,我们可以使用 Kestrel 进行推理。在这个演示中,我们将使用 Sysmon并使用 winlogbeat 将事件流式传输到Elasticsearch以进行日志管理。Elasticsearch 中的日志是 记录,在其之上 Kestrel 提供了一个抽象来进行基于实体的推理, 并支持动态搜索 流 开发和共享。
Kestrel 通过一组可扩展的接口连接到数据源 。我们今天将使用的主要接口是STIX-shifter 接口。STIX-shifter 支持从各种数据源检索数据,包括存储在 Elasticsearch 服务器(由 winlogbeat 使用)上的Elastic Common Schema (ECS) 中的数据。STIX-shifter 有几十个默认未安装的连接器——用户需要根据他们可用的数据源选择要安装的连接器。让我们为 Sysmon-Elasticsearch(ECS) 数据管道安装连接器:
$ pip install stix-shifter-modules-elastic_ecs
通常,人们会使用存储在 Elasticsearch 中的日志来监控多个 Windows。通常,人们为来自不同主机的日志分配不同的 Elasticsearch 索引以单独查询它们。在 Kestrel 中,我们添加并配置了我们在执行狩猎时想要连接的数据源。每个配置指定一个或多个受监控的 Windows 主机,由 Elasticsearch 索引标识。该配置还告诉 Kestrel 如何使用主机名和凭据(例如密码或 API 密钥)访问 Elasticsearch 服务。
我们打开一个新终端,用 Kestrel 激活 Python 虚拟环境,并导出三个环境变量来设置一个名为 Kestrel 的数据源 host101
(更多信息可以在Kestrel 教程中找到:
$ . huntingspace/bin/activate
$ export STIXSHIFTER_HOST101_CONNECTOR=elastic_ecs
$ export STIXSHIFTER_HOST101_CONNECTION='{"host":"elastic.securitylog.company.com", "port":9200, "indices":"host101"}'
$ export STIXSHIFTER_HOST101_CONFIG='{"auth":{"id":"VuaCfGcBCdbkQm-e5aOx", "api_key":"ui2lp2axTNmsyakw9tvNnw"}}'
启动 Jupyter 并创建一个新的 Huntbook
接下来只需使用我们的 Kestrel 数据源配置(导出的环境变量)在上述终端中启动 Jupyter notebook:
$ jupyter notebook
在浏览器的 Jupyter 页面上,我们通过在New Notebooks的下拉菜单下选择Kestrel内核来创建一个空的 Kestrel 狩猎簿。
huntbook是Jupyter笔记本包含狩猎步骤(在 Kestrel),执行结果,和文件或注释。
获取 Windows 调度程序列表
在这次追捕中,我们将开始从 Windows 计划任务/服务列表中向下钻取,以追捕诸如FIN7 之类的持续威胁 。
注:FIN7是一个东欧威胁组织,至少自 2015 年年中以来一直活跃,主要针对美国实体,目标是直接窃取金融信息,例如信用卡和借记卡数据。2021年6月下旬至7月下旬,FIN7组织在鱼叉式网络钓鱼活动中,利用武器化Windows 11 Alpha主题Word文档,针对销售点 (PoS) 服务提供商投放恶意载荷,包括JavaScript植入程序。
在最近的 Windows(>= Windows 10 版本 1511)中,计划任务由svchost.exe
特定参数执行和管理-k netsvcs -p -s Schedule
。任务是svchost.exe
在预定时间从进程中作为子进程产生的。Nasreddine Bencherchali在他的 博客中撰写的这种理解 提供了将 Windows 计划任务作为进程实体与父进程一起检索的想法svchost.exe
。
在 Kestrel 中,我们使用该GET
命令从匹配给定模式的数据源中检索数据。在本次搜索中,我们使用STIX 模式, 因为我们使用的数据源接口是 STIX-shifter,它将 STIX 模式转换为本地查询语言,并将结果转换回 STIX 包以供 Kestrel 处理。
在 Kestrel 中编写 STIX 模式时需要注意两个特殊项目(在GET 命令文档中更详细):
-
GET
命令中返回的实体类型应始终与 STIX 模式中的根级STIX 网络可观察对象 (SCO)类型匹配。 -
我们需要
START ... STOP ...
为我们的第一个模式提供一个时间范围。否则,STIX-shifter 将默认搜索最后五分钟,这可能不是感兴趣的时间范围。
要获取 scheduler svchost.exe
,获取此类进程实体的直接想法是使用以下 STIX 模式将进程与其特定命令行匹配:
[process:command_line = 'C:\Windows\system32\svchost.exe -k netsvcs -p -s Schedule']
我们可以将GET
命令放在第一个huntbook单元中执行:
# create Kestrel variable scheduler with the list of scheduler processes
scheduler = GET process FROM stixshifter://host101
WHERE [process:command_line = 'C:\Windows\system32\svchost.exe -k netsvcs -p -s Schedule']
START t'2021-04-03T00:00:00Z' STOP t'2021-04-04T00:00:00Z'
或者,我们可以编写一个更简单的模式来匹配所有svchost.exe
进程,并通过在 上应用第二个模式来进一步过滤结果 command_line
。
# first GET going through STIX shifter
svchost = GET process FROM stixshifter://host101
WHERE [process:name = 'svchost.exe']
START t'2021-04-03T00:00:00Z' STOP t'2021-04-04T00:00:00Z'
# second GET running locally against the returned/cached data from the first command
# no need to specify time range for GET from a Kestrel variable, check doc for more info
scheduler = GET process
FROM svchost
WHERE [process:command_line = 'C:\Windows\system32\svchost.exe -k netsvcs -p -s Schedule']
Kestrel 将通过 STIX-shifter 运行第一个模式,并在本地运行第二个模式,以对抗第一个GET
. 我们将这两个GET
命令放在一个代码块中,因为它们将始终一起运行。如果我们想对svchost.exe
进程执行多次搜索并最小化我们必须对后端执行的查询,这可能很有用。请注意,在撰写本文时,由于ECS STIX-shifter 模块中的错误,第一种方法将失败。
查找计划任务
执行上面的单元格,我们svchost.exe
在变量中得到 183 个进程 svchost
。其中只有两个是在变量中捕获的调度程序进程 scheduler
。
下一步很简单:找到 的子进程scheduler
,它们是我们感兴趣的计划任务进程。
对于关系解析,我们使用 Kestrel 命令FIND
,它将负责记录到实体的处理并预取相关记录以进一步深入挖掘。
要使用FIND
,我们查找要使用的适当关系语法的命令语法。文档中还有一些示例,例如在 Kestrel 变量中查找进程的子进程,这正是我们在这里需要的。
tasks = FIND process CREATED BY scheduler
DISP tasks ATTR name, command_line
在上面的代码块中,变量tasks
包含来自 的子进程 scheduler
,我们使用 display 命令DISP
来显示 中进程实体的关键属性tasks
。对于不熟悉流程实体的人,可以使用INFO tasks
命令打印出所有的属性,然后打印出DISP
其中的一些。
该单元需要 8 秒才能运行并找到 126 个任务进程作为 .svchost 调度程序的子进程scheduler
。该DISP
命令将它们显示在表格中。
从上面的截图(中的部分进程tasks
),我们看到了一些未知的进程amcet.exe
,但我们在谷歌和VirusTotal上找不到信息。
深入研究计划任务
acmet.exe
由于位置路径,我们怀疑是一个合法的 IBM 进程,c:/programdata/ibm/rii/amcet.exe
如上所示。我们可以amcet
通过GET
命令为这些进程创建一个新变量并进一步调查。
我们可以使用该FIND
命令找到与进程相关的可执行文件,但它提供的信息可能不会比我们从command_line
现场获得的信息更多。相反,我们可以搜索子进程以查看是否有任何可疑的东西,例如PowerShell或其他已知的恶意进程。此外,我们可以找到任何网络流量并分析通信模式。
让我们深入研究 amcet 作为我们笔记本中的单个执行块:
# get only the amcet processes from all scheduled tasks
amcet = GET process FROM tasks WHERE [process:name = 'amcet.exe']
# find and display their child processes
amcet_child = FIND process CREATED BY amcet
DISP amcet_child ATTR name, command_line
# find and display their network traffic
nt = FIND network-traffic CREATED BY amcet
DISP nt ATTR dst_ref.value, dst_port
从执行摘要中,我们得到 24 个 amcet 进程,它们产生 45 个子进程并建立 23 个网络连接。
所有网络流量共享同一个远程 IP 地址9.148.5.93
(根据我们的DISP nt
命令显示,带有属性dst_ref.value
和dst_port
):
从我们的威胁情报(在 TI 工具中查找或直接在追查流程中使用 TI 信息丰富实体(将在以后的博客中讨论))中,我们没有看到任何主机受到威胁的迹象。我们可能会检查该服务9.148.5.93:443
以确认该服务没有受到损害或恶意。此时更有趣的是我们发现的子进程:45 个生成的进程只分为两类——conhost
而且 powershell
——正如我们的DISP
命令所示:
这里的敏感过程是conhost.exe
with参数0xffffffff -ForceV1
,它可以访问内核空间,被用于许多攻击,尤其是DLL注入。我们需要检查所有进程使用的子进程和文件,amcet_child
以了解是否有某些内容被篡改或是否存在带有可疑命令行的进程。
# find child processes of amcet_child
amcet_cc = FIND process CREATED BY amcet_child
DISP amcet_cc ATTR name, command_line
# find files read/written/executed by amcet_child
# Kestrel v1.0.8 only resolves the generic relation LINKED into STIX 2.0 references,
# which is limited to execution relation between processes and executables
amcet_f = FIND file LINKED amcet_child
DISP amcet_f ATTR name, parent_directory_ref.path
执行此单元后,我们看不到任何进程创建的子进程 amcet_child
(中的零实体amcet_cc
)。
命令中amcet_child
显示的进程只有两个文件DISP amcet_cc
,它们只是进程的主要可执行文件。
总结和伸展狩猎
在这篇博文中,我们展示了如何开始使用 Kestrel 威胁狩猎语言,从灌输到第一次寻找:发现 Windows 中的持续威胁。我们首先查找所有计划的 Windows 任务,然后深入研究一个特定进程以搜索可疑活动。虽然我们在实践中没有发现任何持续存在的威胁,但我们创建了一个 可以重复使用和修订的狩猎手册,以供未来的狩猎使用。检查威胁的持续性通常是发现大型 APT 活动的第一阶段之一,可组合的追捕流 功能可以重用这种追捕簿大型追捕。我们只使用GET
和FIND
此狩猎实践中的命令,涵盖了知识编码的两个类别之一——模式匹配。在我们的下一篇博客中,我们不仅将介绍模式匹配,还将介绍分析,它们的组合在大型狩猎中将非常有用。