Beagle 是一款事件响应和数字取证工具,可将数据源和日志转换为图。支持的数据源包括 FireEye HX Triages、Windows EVTX 文件、SysMon 日志以及原始 Windows 内存镜像。生成的图可以发送到 Neo4J 或 DGraph 等图数据库,也可以作为 Python NetworkX 对象保存在本地。
Beagle 既可作为 Python 库直接使用,也可通过提供的 Web 界面使用。
该库可以以单个数据源的函数调用序列方式使用。
>>> from beagle.datasources import SysmonEVTX
>>> graph = SysmonEVTX("malicious.evtx").to_graph()
>>> graph
<networkx.classes.multidigraph.MultiDiGraph at 0x12700ee10>
也可以作为从多个工件生成的图来使用:
>>> from beagle.datasources import SysmonEVTX, HXTriage, PCAP
>>> from beagle.backends import NetworkX
>>> nx = NetworkX.from_datasources(
datasources=[
SysmonEVTX("malicious.evtx"),
HXTriage("alert.mans"),
PCAP("traffic.pcap"),
]
)
>>> G = nx.graph()
<networkx.classes.multidigraph.MultiDiGraph at 0x12700ee10>
或者通过严格调用数据源到图过程的每个中间步骤:
>>> from beagle.backends import NetworkX
>>> from beagle.datasources import SysmonEVTX
>>> from beagle.transformers import SysmonTransformer
>>> datasource = SysmonEVTX("malicious.evtx")
# 转换器接收一个数据源,并将每个事件转换为一个或多个节点的元组。
>>> transformer = SysmonTransformer(datasource=datasource)
>>> nodes = transformer.run()
# 转换器输出一个节点数组。
[
(<SysMonProc> process_guid="{0ad3e319-0c16-59c8-0000-0010d47d0000}"),
(<File> host="DESKTOP-2C3IQHO" full_path="C:\Windows\System32\services.exe"),
...
]
# 后端接收节点,并将其转换为图
>>> backend = NetworkX(nodes=nodes)
>>> G = backend.graph()
<networkx.classes.multidigraph.MultiDiGraph at 0x126b887f0>
图围绕单个进程的活动展开,主要旨在帮助分析人员调查主机上的活动,而非主机之间的活动。
Beagle 以 Docker 文件形式提供:
docker pull yampelo/beagle
mkdir -p data/beagle
docker run -v "$PWD/data/beagle":"/data/beagle" -p 8000:8000 yampelo/beagle
它也可作为库使用。完整的 API 文档位于 https://beagle-graphs.readthedocs.io
pip install pybeagle
注意:仅支持 Python 3.6 及以上版本。
Rekall 不会自动安装。要安装 Rekall,请改为执行以下命令:
pip install pybeagle[rekall]
配置文件中的任何条目都可以使用遵循以下格式的环境变量进行修改:BEAGLE__{SECTION}__{KEY}。例如,要更改使用 Docker 镜像时的 VirusTotal API 密钥,可以使用 -e 参数并设置 BEAGLE__VIRUSTOTAL__API_KEY 变量:
docker run -v "data/beagle":"/data/beagle" -p 8000:8000 -e "BEAGLE__VIRUSTOTAL__API_KEY=$API_KEY" beagle
环境变量和目录可以很容易地使用 docker compose 定义:
version: "3"
services:
beagle:
image: yampelo/beagle
volumes:
- /data/beagle:/data/beagle
ports:
- "8000:8000"
environment:
- BEAGLE__VIRUSTOTAL__API_KEY=$key$
Beagle 的 Docker 镜像附带一个 Web 界面,它封装了将数据转换为图以及使用图调查数据的过程。
上传表单封装了图创建过程,并自动使用 NetworkX 作为后端。根据数据源所需的参数,表单会提示上传文件或输入文本。例如:
创建的任何图都存储在配置中 storage 部分的 dir 键定义的本地文件夹中。这可以通过设置 BEAGLE__STORAGE__DIR 环境变量进行修改。
可选地,可以为任何图添加注释以帮助更好地描述它。
每个数据源会自动从提供的参数中提取元数据。元数据和注释稍后在查看该数据源的现有图时可见。
单击侧边栏上的数据源会显示该数据源所有已解析图的表格。
在 Beagle 中查看图提供了一个 Web 界面,允许分析人员快速围绕事件进行 pivot。
界面主要分为两部分:左侧部分包含图的不同视角(图视图、树视图、表格视图等),右侧部分允许您按类型过滤节点和边、搜索节点以及展开节点的属性。它还允许您撤消和重做在图上的操作。
图中任何带有上方分隔线的元素都是可折叠的:
图中的节点显示特定字段的前 15 个字符。例如,对于进程节点,将显示进程名称。
边仅显示边的类型。
单击节点或边会聚焦该节点,并在右侧边栏的“节点信息”面板中显示其信息。
双击节点会拉入任何相邻节点。相邻节点是指通过边连接到点击节点的任何节点。如果没有可拉入的邻居,图中将看不到任何变化。
长按单击节点会将其从图中隐藏,同时隐藏依赖于它的所有边。
右键单击节点会弹出一个上下文菜单,允许您运行 图变异器。变异器是接收图状态并返回新状态的函数。
两个非常有用的变异器是:
回溯节点非常有用,类似于在日志文件中进行根本原因感染分析。
展开节点的后代允许您立即查看由该节点引起的所有事件。此操作会显示以所选节点为根的子图。
有时,节点或边可能与当前事件无关,您可以切换边和节点类型的显示/隐藏。一旦切换类型,该类型的节点或边就会从可见图中移除。
关闭节点类型会阻止该节点类型在变异器或拉入邻居时被使用。
图中的任何操作都可以立即撤销!使用撤销/重做按钮可以还原您执行的任何操作。重置按钮会将图状态设置回其加载时的状态,免去刷新页面的麻烦。
当您使用上述操作更改图的当前状态时,您可能还希望从不同的视角查看当前可见的节点和边集合。图屏幕顶部的选项卡允许您将数据转换为多种视图:
每个视角都支持通过单击节点来聚焦节点。
图生成过程可以使用 Python 库以编程方式执行。图生成过程包含三个步骤:
DataSource 类逐个解析并产生事件。Transformer 类接收这些输入并将其转换为各种 Node 类,例如 Process。Backend 类接收节点数组,将其放入图结构中,并将其发送到所需位置。Python 包可以通过 pip 安装:
pip install pybeagle
创建图需要将这些步骤串联起来。这可以通过使用 to_graph() 函数自动完成。
from beagle.datasources import HXTriage
# 默认情况下,使用 to_graph() 方法会使用 NetworkX 和第一个转换器。
G = HXTriage('test.mans').to_graph()
<networkx.classes.multidigraph.MultiDiGraph at 0x12700ee10>
也可以在每个步骤中显式执行。使用函数调用,您还可以定义要使用的后端,例如,将数据发送到 DGraph:
from beagle.datasources import HXTriage
from beagle.backends import DGraph
from beagle.transformers import FireEyeHXTransformer
# 数据将发送到配置文件中配置的 DGraph 实例
backend = HXTriage('test.mans').to_graph(backend=DGraph)
# 也可以指定转换器
backend = HXTriage('test.mans').to_transformer(transformer=FireEyeHXTransformer).to_graph(backend=DGraph)
调用 to_graph 或 to_transformer 方法时,可以向这些类传递任何参数:
from beagle.datasources import HXTriage
from beagle.backends import Graphistry
# 发送到 Graphistry,先匿名化数据,并返回 URL
graphistry_url = HXTriage('test.mans').to_graph(backend=Graphistry, anonymize=True, render=False)
您也可以手动调用上述过程中的每个步骤,访问中间输出:
>>> from beagle.backends import NetworkX
>>> from beagle.datasources import HXTriage
>>> from beagle.transformers import FireEyeHXTransformer
>>> datasource = HXTriage("test.mans")
>>> transformer = FireEyeHXTransformer(datasource=datasource)
>>> nodes = transformer.run()
>>> backend = NetworkX(nodes=nodes)
>>> G = backend.graph()
如果您想手动调用每个步骤,需要确保 Transformer 类实例与提供的 DataSource 类的输出兼容。
每个数据源定义了与其兼容的转换器列表,可以通过 .transformers 属性访问:
>>> from beagle.datasources import HXTriage
>>> HXTriage.transformers
[beagle.transformers.fireeye_hx_transformer.FireEyeHXTransformer]
默认情况下,边不会被合并,这意味着如果进程节点 u 向文件节点 v 写入 5000 次,那么这些节点之间将有 5000 条边。有时,特别是在尝试可视化数据时,这可能会使分析人员不堪重负。
您可以通过向后端类传递 consolidate_edges=True 参数,将所有 5000 条边合并为一条该操作类型(此例中为“写入”)的边,例如:
SysmonEVTX("data/sysmon/autoruns-sysmon.evtx").to_graph(NetworkX, consolidate_edges=False)
# 图包含 826 个节点和 2469 条边。
SysmonEVTX("data/sysmon/autoruns-sysmon.evtx").to_graph(NetworkX, consolidate_edges=True)
# 图包含 826 个节点和 1396 条边
默认情况下,Web 界面会合并边。
使用 NetworkX 后端可以将生成的图保存为 JSON 对象,以便以后使用。您可以使用 NetworkX.from_json 静态方法将其加载回来。
import json
from beagle.datasources import SysmonEVTX
from beagle.backends import NetworkX
# 获取 nx.MultiDiGraph 对象
graph = SysmonEVTX("malicious.evtx").to_graph()
# 将对象转换为 JSON
graph_json = NetworkX.graph_to_json(graph)
with open("my_graph.json", "w") as f:
json.dump(graph_json, f)
# 稍后:
# G 与 `.to_graph()` 生成的 nx.MultiDiGraph 对象相同
G = NetworkX.from_json("my_graph.json")