用Neo4j和G.V()可视化攻击图谱,加固你的网络安全

0 阅读11分钟

用攻击者的视角思考

从恶意软件加密挖矿攻击到勒索软件团伙,网络攻击的目标往往与任何抢劫行为相同:找到通往有价值资产的最短路径并迅速撤离。这本质上是路径寻找问题,这就是为什么长期以来人们都知道网络攻击者经常将其目标视为图网络,也称为攻击图谱。

要保护你自己的系统,防御者需要像攻击者一样思考。例如,Wiz最近使用攻击者思维模式在Ingress NGINX控制器中发现了漏洞。

即使你的系统日常只使用常规的关系型数据库,你的网络安全团队也需要一种方法来预见到最有可能的潜在攻击路径并快速反应。对于复杂的互联系统,图数据库技术以及与之配套的图可视化和分析,是识别网络攻击风险的关键工具。

幸运的是,Neo4j实例是进行这类网络安全分析的完美环境。你甚至可以将Neo4j实例与G.V()这样的图可视化工具结合起来——这将帮助你以最少的查询编写,快速轻松地识别系统中的漏洞。如果你使用G.V()的Graph Data Explorer,你可能根本不需要编写任何代码。

让我们仔细看看。

像攻击者一样思考

攻击者首先从他们能进入的任何地方获取你系统的访问权限。一旦进入内部,他们会尝试在你的网络中向前推进。

攻击者通常事先并不知道你网络的结构,因此他们通常会采用一套通用的技术工具和一种“试试看”的方法。他们很少能立即找到他们想要的东西。相反,他们会探索你的网络,从一个位置跳转到另一个位置。

攻击者成功访问到的任何东西都是一个资源——这可能是对一个新位置的访问权限、一段新代码、登录凭证,或者仅仅是有用的信息,例如另一个资源的位置。攻击者用来从一个资源转移到另一个资源的任何技术都是一次攻击

目标是找到有价值的东西——我们称之为关键资产。关键资产是一个故意模糊的概念,它可能是多种东西,但重要的是要知道它是攻击者想要而防御者无法承受损失的东西。

例如,关键资产可能是一个能让攻击者完全控制系统权限的资源。

你可以立刻明白为什么黑客倾向于将计算机网络可视化为图。攻击者可能对理解你系统的每个部分或查看每个资源不感兴趣。相反,攻击者关心的是通过所有其他资源找到一条通往关键资产的可行路径。将系统想象成图有助于他们快速找到并概念化这些路径。

这就是攻击图谱

在伪Cypher语言中,我们可以像你预期的那样表示攻击图谱——我们使用 (⬤ Resource)(⬤ Critical asset) 节点来表示每个实体。我们用 [ATTACK] 关系来表示攻击者可能在两个节点之间进行的任何假设性移动。

一个良好的系统图模型——结合良好的数据可视化和分析——能给防御者带来优于攻击者的优势。记住,攻击者通常事先不知道系统的布局,但防御者知道!

为Kubernetes集群建模

在实践中,一个网络将包含多种类型的资源和关键资产节点。它们很可能拥有自己的属性,这将影响可能的攻击路径类型。

在本次讨论中,我们选择使用一个说明Kubernetes集群的样本数据集,并采用了KubeHound对该集群的描述。

以下是我们示例系统中存在的节点类型:

(⬤ Volume) — 集群内存储持久内存的位置 (⬤ Node)* — Kubernetes集群中运行pod的工作机 (⬤ Pod) — 节点内运行一个或多个容器的可部署单元 (⬤ Container) — 包含应用程序的小型环境 (⬤ PermissionSet) — 给定用户/身份允许的一组操作,也是系统中唯一的关键资产节点 (⬤ Identity) — 认证后授予的用户或服务账户 (⬤ Endpoint) — Pod的连接点

这是一个高度简化的数据模型版本,展示了一些攻击类型的示例。有些很简单,有些高度抽象。例如,可以想象这样一个通用概念:攻击者可能通过一个暴露的端点获取你的系统访问权限。我们用 [ENDPOINT_EXPLOIT] 攻击来表示这个概念,而不过多担心其具体机制。其他攻击,如 [TOKEN_STEAL],则描述了一种更具体的攻击:窃取挂载的服务账户令牌。

从一个节点类型移动到另一个节点类型需要不同类型的攻击。在完整的分析中,你会考虑哪些攻击类型更可能发生,或者哪些攻击会使你的关键资产最脆弱。

当然,这里展示的可能网络攻击类型只是冰山一角。理解个体攻击类型对于后续解释和应对你的网络安全图谱非常重要。这将使你能够处理在系统中发现的漏洞。

但现在,我们只专注于识别危险路径,所以不必过分担心对不同类型的攻击进行分类。我们只需要知道存在多种关系类型。

下载样本数据集

既然我们理解了数据模型,我们将在Neo4j中管理我们的示例安全集群。我们还将引导你了解如何在G.V()中可视化它。

这里的一切你都可以自己完成。样本数据集以ZIP格式在GitHub上提供,并可在Neo4j Sandbox中使用。你可以通过数据导入器直接上传数据。只需在Neo4j Sandbox中选择“Open model (with data)”并选择ZIP文件。我们还以CSV格式包含了原始数据。

如果你还没有安装G.V(),请前往下载门户,因为你需要它来跟着操作。

下载并打开G.V()后,点击“New Database Connection”。

从那里,你只需要选择Neo4j作为你的图数据库类型,并输入你的Bolt地址和端口。完成后,系统会提示你输入用户名和密码。

输入你的详细信息并提交连接——就这么简单!

使用G.V()进行图可视化

为了节省大量时间,让我向你介绍G.V()的新功能——Graph Data Explorer。传统上,如果你想看到图数据库中的所有数据,你必须运行一个Cypher查询。类似这样:

MATCH p=()-[]-() RETURN p LIMIT 10000

虽然G.V()完全兼容Cypher,并且如果你喜欢,绝对可以从查询编辑器运行此查询,但Graph Data Explorer消除了为直观数据探索而构建此类基于代码的查询的需要。事实上,我们即将在不编写任何代码的情况下进行一些网络安全分析。但无论如何,我们还是会包含Cypher命令——以防你更喜欢以那种方式跟随操作。

让我们尝试查找图中连接到另一个节点的任何节点。

现在我们有了对情况的总体概览。系统中所有的攻击路径都一目了然,我们可以使用力导向布局来很好地概览节点之间的关系,或者使用社区布局来查看系统中存在哪些类型的资源。

由于(⬤ Endpoint)图节点是最常见的攻击入口点之一,我们已经高亮显示了这些节点,并关闭了所有其他节点的标签。这让你一眼就能看出攻击可能从哪个暴露的端点开始。

如果你想要调查特定图节点或关系的漏洞,只需点击几下即可高亮显示感兴趣的节点。让我们看看名为kubehound.test.local-control-plane的工作机(⬤ Node)

我们可以看到进出该工作机(⬤ Node)的所有不同类型的攻击。

上面的图可视化让我们可以描绘出这个资源的心智图景:

  • 众多目标 — 如果攻击者成功执行[VOLUME_ACCESS]或[POD_ATTACH]攻击,有大量(⬤ Volume)(⬤ Pod)资源可以直接访问。
  • 暴露的身份 — 有一个相邻的(⬤ Identity)资源易受[IDENTITY_ASSUME]攻击。
  • 容器威胁 — 有一条关系进入该资源。攻击者可以使用[CE_PRIV_MOUNT]攻击从相邻的(⬤ Container)图节点获取对该节点资源的访问权限。

当我们实施安全措施时,也很容易进一步修改我们的图以反映这些措施。

例如,假设我们已经做了大量工作来保护我们的卷,使它们不易受到卷访问攻击。由于我们现在不太担心这类攻击,我们希望专注于其他领域。

我们有两个选择。第一个是关闭[VOLUME_ACCESS]关系的显示。这使得卷节点仍然可见,这样我们可以确保没有其他类型的攻击进出这些资源。

如果——并且仅当——我们确信卷资源现在已有效地与我们的工作机(⬤ Node)资源隔离,我们可以完全关闭(⬤ Volume)节点的显示。这让我们可以完全专注于其他资源。

你可以选择从关系(攻击路径)或节点(资源)的角度来评估你的攻击图谱。你的可视化和解释选择将取决于你选择分析系统的哪些部分。

但是关键资产呢?

回想一下,我们所有的关键资产都是(⬤ PermissionSet)类型。正如我们所见,在我们工作机(⬤ Node)的最近邻居中没有关键资产。但是,如果我们允许多跳,可能仍然存在通过更远邻居到达关键资产的路径。我们想看看这样的路径是否存在。

假设我们想检查我们的工作机(⬤ Node)是否在10跳或更少跳数内连接到任何关键资产:

MATCH path = (start {name: 'kubehound.test.local-control-plane'}) -[*1..10]-> (end)
WHERE (end.critical=True AND ALL(n IN NODES(path)[1..] WHERE n <> start))
RETURN path

我们可以看到有多条可行的路径从我们的资源引出,暴露了多个关键资产!这里显示的每条路径都代表我们系统的一个假设性风险。

让我们只高亮一条攻击路径。

由于system:coredns (⬤ PermissionSet)是一个关键资产,让我们特别关注这个节点。与其查看从我们的起始资源——那个我们有些随机选择的(⬤ Node)——出发的路径,我们更想了解这个关键资产总体上有多脆弱。

攻击者通常从端点开始攻击,所以让我们寻找可能将此资产暴露给端点的关系。

我们可以反转之前的查询,查看所有连接到此资产的(⬤ Endpoint)

MATCH path = (start:PermissionSet {role: 'system:coredns'}) -[*1..10]-> (end)
where (end.label='Endpoint' AND ALL(n IN NODES(path)[1..] WHERE n <> start))
RETURN path

我们立刻就能看到,如果我们分析来自端点的攻击,我们实际上不需要太担心kubehound.test.local-control-plane这个(⬤ Node),因为没有任何路径将该图节点连接到端点路径。然而,我们可以看到有一些容器、卷和身份节点可能需要我们关注。

为了获得对我们系统更全面的概览,我们可以查看所有在少于十跳内将端点连接到任何关键资产的路径:

MATCH path = (start:Endpoint) -[*1..10]-> (end:PermissionSet)
WHERE (end.critical=true AND ALL(n IN nodes(path) WHERE size([m IN nodes(path) WHERE m = n]) = 1))
RETURN DISTINCT path LIMIT 1000

我们可以看到有两类(独立的)攻击路径:

类别 #1:攻击者可以通过任一coredns (⬤ Container)节点推进。 类别 #2:攻击者可以通过工作机(⬤ Node) kubehound.text.local-worker2推进。

尽管类别1和2都包含许多子路径,但通过专注于像这样的瓶颈点,我们可以极大地增强安全系统并切断大部分攻击路径。

通过将精力集中在真正重要的路径上,防御者确保了系统的最大安全性。这是图可视化特别适合的一项任务。强大的攻击图谱能够一眼识别漏洞,为防御者提供他们所需的洞察力和时间来加强防御。

总结

你现在已经体验了图可视化在网络世界中的强大力量。但这仅仅是个开始:Neo4j与G.V()的结合是一个强大的组合,可以从各个角度和尺度深入了解你系统的优势和脆弱性。

无论网络攻击多么复杂,它们总是遵循规则,这使得它们可以被预测。有了强大的图数据模型和勤勉的网络安全团队,没有一条攻击路径是你无法预见的。FINISHED CSD0tFqvECLokhw9aBeRqiK65lS164AuOwRpGElQ/J1I67XH0xjN3ntmGKL6/fqt/0LG+ziLqow4rZTDcQnq2HWaK/BNyTS5YvV5sj4GvMm27den3F/DPLhRKkrz0qVhPWXQFhmgJaFtDSa908jeBA2vpF0Jt5HzRPRRwlrdUnY=