神刀安全网

利用“数学建模-图论模型”进行自动化内网渗透测试

0×00 前言

活动目录域中的权限提升是大多数入侵者与内网管理员斗争过程中非常重要的一部分。尽管获得域或企业内网管理员权限并非评估的最终目的,但它往往使被测试的目标更容易被拿下。  

典型的域中的权限提升过程是围绕收集纯文本的凭证或者是已登录到系统的用户的令牌或者是使用 Mimikatz 等工具进行提权。找到域管理员登录过的系统,并收集管理员的登录凭证。

但是,如果你在一个更复杂的情况下,你没有很快拿到管理员权限,或者你并没有在内网中定位到管理员的机器,那么你可能会在内网中入侵一个,两个,三个等等的主机作为跳板继续渗透,这需要对入侵的路线做相当多的分析(并且有可能是错误的)。

在最近的一次实战中,我们获得了普通域用户的权限,在这个内网环境中有着成千上万的工作站和服务器加入到了 Active Directory 林中的多个不受信任的域中。我们的目标是将权限提升至企业管理员权限(如果有可能的话),幸运的是,内网网络的拓扑图是偏平化的没有那么复杂。但是,客户端主机的配置使用了极其严格的最小权限的方式,有效的阻止了常规的提权方法。在找到一种可以进行提权的方法后,我们最终就有可能拿到一台服务器的管理员帐户,暂且称这个管理员为“Steve-Admin”。

“Steve-Admin”是一个服务器上的管理员,同时,他需要是一个能登录到内网中任何一台服务器的管理员。我们将会获得内网中服务器的列表,并找到哪些用户已登录到这些服务器。之后,我们要决定我们需要分析哪些用户。那些未登录的用户,暂且可以当作域管理员没有登录的那些主机的管理员看待。我需要选择一个帐户并找到一台或多台此帐户在这些主机拥有管理员权限的主机。之后,继续列举登录到这些主机的用户,并且,按照这样的方式继续下去,直到我们最终发现了一条可行的路线。在拥有数十万的计算机和用户的环境中,这个过程可能需要很多天甚至数周。

在这篇文章中,我将会解释,证明这种想法并将这个过程自动化。    

0×01 开始前的准备工作

这个想法的证明过程在很大程度上依赖于一些已经存在的工具和那些慷慨分享且非常聪明努力工作的人。

–  衍生本地管理员工具 by Justin Warner ( @sixdub ) – http://www.sixdub.net/?p=591

–  一个使用 PowerShell 实现了 Dijkstra算法的程序 by Jim Truher (@jwtruher) – https://jtruher3.wordpress.com/2006/10/16/dijkstra/

–  活动目录控制路径工具 by Emmanuel Gras and Lucas Bouillot – https://github.com/ANSSI-FR/AD-control-paths

–  域信任节点分析工具 by Justin Warner ( @sixdub )- http://www.sixdub.net/?p=285

0×02 图论

试想一下,将试图找到“Steve-Admin”到企业管理员的路线,当作是找到从西雅图,华盛顿到俄勒冈州波特兰市的路径。作为一个人,你可以看看地图,之后很容易就能确定五号州际公路将是一个很好的选择。那么一台计算机可以利用数学找到西雅图和波特兰之间的路径,同样也可以找到“Steve-Admin”到企业管理员(如果存在)之间的路径。

Power View 可以给我们找到从“Steve-Admin”到企业管理员的路径的自动化过程中的大部分数据。其余的数据可以利用欧拉在18世纪所创建的数学的一个分支现在被称为“图论”的方法得到。

–  顶点(Vertices)一个顶点(或节点)代表了被表示的系统中的单个元素的点。你可以把地图中的城市作为一个顶点。

–  边(Edges)一条边被用来连接多个顶点。边可以是有向的(如:单向)也可以是无向(如:双向)。边一般代表了一种关系。如果西雅图和波特兰被当作是顶点,那五号洲际公路Ⅰ-5可被认为是一个连接这些城市的双向的边。

–  轨迹(Path)轨迹是连接到一个节点的边和节点再连接到另一个节点的集合,这些节点可以是相邻的也可以是不相邻的。

–  邻接(adjacency)共享一条边的顶点可以认为是相邻的。

0×03 图形设计

对于上述想法的证明,我在想出这个问题再到设计时考虑到了一个目标 —— 自动寻找到一个域管理员的最短路径的过程中,无需写入磁盘或需要离线分析。因此,该图的设计可能不适合于其他问题。

在设计这个图时,我主要侧重于简单性。在许多错误的开始之后,我终于得到了一个可行的设计方案:

–  每个用户和计算机是一个顶点。

–  所有的边都是有向的且未加权的。

–  从一个用户到一台计算机的有向边表示本地管理员权限。

–  从一台计算机到一个用户的有向边表示已登录的用户。

可以先想象一个只由两台电脑和两个用户组成的一个非常基本的网络。 “管理员”帐户在这两个系统上都拥有管理员权限。其中一个系统上有一个名为“mnelson”的用户已经登录。使用上述设计方案,该系统的可视化表示应该是这样的:

利用“数学建模-图论模型”进行自动化内网渗透测试

每个用户和计算机都是一个顶点。橙色的边告诉我们,管理员帐户在两个系统上均拥有管理员权限。蓝色的边告诉我们,用户“mnelson”在主机 HR-WS-002 上已经登录。在这个设计中,边总是意味着源顶点可能会危及到目标顶点的安全 —— 管理员可以危及到主机 HR-WS-002,并且主机 HR-WS-002(如:在本机上的SYSTEM帐户)可能会危及到用户“mnelson”的登录凭证。

0×04 构建图形

找到适合上图论中的顶点的对象再简单不过了。因为我们将每个用户和计算机都作为了一个节点,使用 PowerView 的 两个 cmdlet – Get-NetUser 和 Get-NetComputer 是非常简单的:

利用“数学建模-图论模型”进行自动化内网渗透测试

此时可以将上述图论可视化的表示为:

利用“数学建模-图论模型”进行自动化内网渗透测试

为运行 Dijkstra 算法做准备,我们需要给每个顶点设置以下属性:

–  名称 – 顶点的名称。例如:“mnelson” 或 “HR-WS-002”

–  边 – 顶点数组,该顶点有一个边,初始值为 $Null。

–  距离 – 从源顶点到该顶点所需的跳级数。初始值为无穷大。请注意,这是一个未加权的图。

–  访问 – 到该节点的最短路径是否已到终点,初始值为 $False。

–  前身顶点 – 在从源顶点到该顶点的路径上的前一个顶点的名称。初始值为 $Null。

利用“数学建模-图论模型”进行自动化内网渗透测试

确定每个顶点的边稍微有点复杂。这次,我们可以利用 PowerView 的另一个 cmdlet —— Get-NetSession。此 cmdlet 返回了我们针对某台计算机运行的会话信息,可以让我们看到哪些用户产生了会话以及该会话的来源,有效地使我们能够确定用户在哪里已经登录 —— 所有没有提升的权限。利用这些信息,我们可以使用边,填充计算机顶点到已经登录的用户的点。接下来,在每一台我们已获得用户登录信息的计算机上递归枚举本地管理员用户。这一信息使我们可以用边填充相应的用户顶点,这表示了到该计算机的本地管理员权限的边。

利用“数学建模-图论模型”进行自动化内网渗透测试

在我的测试实验室里,用所有的边完成的图可以直观地表示如下:

利用“数学建模-图论模型”进行自动化内网渗透测试

回想一下,一个用户 -> 计算机的边表示管理员权限,一台计算机 -> 用户的边表示已登录的用户。

显然,“Administrator”账户是这三台计算机上的管理员。“mnelson”用户是主机 OPS-WS-002 的管理员。“jwarner”用户是主机 IT-SRV-002 的管理员。

主机 HR-WS-002 上有一个已登录用户:mnelson。 OPS-WS-002有一个已登录的用户:jwarner。最后,主机 IT-SRV-002 上有三个已登录的用户: rwinchester, jfrank, 和 Administrator。“jdimmock ”用户既不是管理员也没有在任何地方登录(他可能在PTO)。

现在,我们有了需要找到任何一个顶点到其他任何顶点的最短路径的一切。

回想我之前提到的情况。从“Steve-Admin”开始,我们有几十个计算机和用户可以作为目标,其中没有一个可以使我们可以快速访问到域管理员帐户。与其花费几小时,几天,甚至几周分析每种可能(或者更糟:通过我们在尝试和错误的方法中去选择),却不如我们使用一个算法在几分钟内来找到我们需要的这条“捷径”。

0×05 Dijkstra 算法

我在学习 Dijkstra 算法所花的时间越多,我越承认并欣赏创建了这种优雅、高效的方法的天才。

–  1.确定一个源顶点。设置它的距离为0。设置每个顶点到无穷远的距离。

–  2.使用最小的距离值确定未访问的顶点并标记为当前顶点。

–  3.考虑当前顶点的边。比较当前顶点的每个邻接的顶点到当前顶点的距离加 1 后的值 —— 如果计算出的距离小于当前值则会更新相邻顶点的距离,并更新该相邻顶点的前身的值为当前顶点的名称。

–  4.跳到步骤 2 ,直到所有的顶点都被访问过。

利用“数学建模-图论模型”进行自动化内网渗透测试

一旦算法完成,每个顶点的距离的值会告诉我们是否可以通过源顶点到达该顶点,并有多少跳级数。另外,我们有一个访问路径记录可以回到我们的源顶点,这是因为在每个顶点中都包含了一个前身属性:

–  1.取出目标顶点的名称,并将它添加到我们的路径数组中。

–  2.取出路径数组中最新添加的顶点,并找到它的前身。将其前身添加到路径数组中。

–  3.重复上述步骤,直到没有前身。此时,我们就已经达到了我们的源顶点。

利用“数学建模-图论模型”进行自动化内网渗透测试

0×06 结论及验证

我们仅仅触及到了这里的一些“皮毛”。还有很多非常令人兴奋的运用图论(和数学等领域的知识)到 Active Directory 攻防中的可能性(看看这篇由 Brandon Helms 又名 cr0n1c所写的精彩文章。例如,通过反转该图的每条边的方向,并使用管理权限来获得更多的已登录的用户数据,我们可以指定“Administrator” 用户作为源点和终点,并使用 Dijkstra 算法进行一次迭代计算,在 AD 中的所有帐户都可能危及到“Administrator”账户。

你可以在 github 找到 POC 脚本。

*原文地址: wald0.com ,斯诺登编译,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » 利用“数学建模-图论模型”进行自动化内网渗透测试

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
分享按钮