导语:本系列博客文章介绍了有关执行弹性方法的更具技术性和规范性的策略指导。在这篇文章中,我们将展示如何使用Neo4j的Cypher查询语言和BloodHound接口组合生成分析和执行攻击路径分析的技术细节。
注意:这是两部分博客系列中的第三部分。本系列博客文章介绍了有关执行弹性方法的更具技术性和规范性的策略指导。适当时我将提供相关的上下文。对于完整的上下文,请参阅该系列博文中的第一篇博客文章。或点击阅读《红蓝对抗中的对手弹性方法论介绍(一)》,《红蓝对抗中的对手弹性方法论介绍(二)》
介绍和背景
在DEFCON 24大会上发布了BloodHound之后,我们几个人意识到虽然BloodHound对攻击者来说是一个很好的工具,但它作为防御工具的潜在应用更加引人注目。在第一篇博文中,我们介绍了如何解锁部分功能的高级策略,我们将其称为Active Directory 攻防对抗方法论。在这篇文章中,我们将展示如何使用Neo4j的Cypher查询语言和BloodHound接口组合生成分析和执行攻击路径分析的技术细节。
阶段1:枚举攻击路径
下载SharpHound.exe(或PowerShell版本)后,你需要在加入域的Windows计算机上运行二进制文件,该计算机具有对企业中所有其他加入域的Windows系统的逻辑访问权限。如果你正在处理网络分段的事情,则可能需要从网络中的多个位置运行SharpHound。我们建议运行一次SharpHound的默认集合:
C:\> SharpHound.exe
域信任收集本地管理员组成员身份,并且还将执行一个用户会话集合的循环。要收集全面的用户会话数据,我们建议你至少间隔一小时运行SharpHound的会话循环集合:
C:\> SharpHound.exe — CollectionMethod SessionLoop — MaxLoopTime 1h
最后,你需要运行SharpHound的ACL集合方法来从计算机,用户和域安全对象中收集ACE:
C:\> SharpHound.exe — CollectionMethod ACL
SharpHound会将CSV文件写入你当前的工作目录。在下一阶段,我们将这些CSV导入BloodHound的图形数据库。
阶段2:分析攻击路径
这里提供了几种下载和安装分析工具Neo4j和BloodHound UI的方式。你可以下载Neo4j服务器和BloodHound UI并自行设置,或利用Walter Legowski的Neo4j/BloodHound 自动安装程序。我们也整理了BloodHound的入门文档,可以在这里找到wiki。
在设置完毕Neo4j服务器并运行后,打开BloodHound UI并对Neo4j进行身份验证。使用“上传数据”按钮上传你在阶段1中生成的CSV:
如上图所示:BloodHound UI中的“上传数据”按钮。
选择你的CSV 文件,然后在常用对话窗口中点击“确定”。界面将自动解析CSV并将其加载到Neo4j数据库中。现在你已准备好进行一些分析工作了。
一旦你的数据导入到Neo4j数据库中,打开BloodHound,默认情况下会显示域管理员组的所有有效成员。右键单击Domain Admins组,然后单击“Shortest Paths to Here”:
这将在后端运行allShortestPaths查询,然后BloodHound UI将呈现生成的路径:
如上图所示:Domain Admins组的所有最短路径。
在后续的博客文章中,我们将向你展示如何有效地查找所有最短路径,不仅是Domain Admins组,还有所有为你提供Domain Admin等效权限的主体。
回想前面的“USER99”节点示例,一次性更改很少会对减轻攻击路径产生任何明显影响。相反,应该寻求识别有助于Domain Admin用户暴露的行为和特权模式。例如,通过单击Domain Admins组,我们可以看到有关该组的大量信息,包括该组中用户的用户会话数:
如上图所示:Domain Admins组的有效成员在117个不同的系统上进行了会话。
如果我们单击数字117,BloodHound UI将会把具有Domain Admins组成员会话的计算机绘制出来:
如上图所示:可视化的Domain Admins组有效成员的会话。
此外,你可以分析这些系统中有效本地管理员的总数。使用BloodHound界面,你可以一次分析一个系统,或者在Neo4j Web控制台上,你可以返回这些计算机的列表,以及每台计算机的有效管理员总数。运行Neo4j后,打开Web浏览器并导航到http://localhost:7474
如上图所示:Neo4j网络控制台。在带有美元符号的框中输入你的查询。
Cypher的查询语句是:
MATCH p = (u1:User)-[r:MemberOf|AdminTo*1..]->(c:Computer)-[r2:HasSession]->(u2:User)-[r3:MemberOf*1..]->(g:Group {name:’DOMAIN [email protected]’}) RETURN COUNT(DISTINCT(u1)) AS adminCount,c.name as computerName ORDER BY adminCount DESC
如上图所示:Neo4j Web控制台中上述命令的输出。
我们还可以度量Domain Admin用户对环境其他部分的暴露程度。我们使用了三个指标:具有DA路径的用户百分比,具有DA路径的计算机百分比以及平均攻击路径长度,在Neo4j Web控制台上运行以下内容:http://localhost:7474/
// Calculate the percentage of users with a path to DA MATCH (totalUsers:User {domain:'EXTERNAL.LOCAL'}) MATCH p = shortestPath((pathToDAUsers:User {domain:'EXTERNAL.LOCAL'})-[r*1..]->(g:Group {name:'DOMAIN [email protected]'})) WITH COUNT(DISTINCT(totalUsers)) as totalUsers, COUNT(DISTINCT(pathToDAUsers)) as pathToDAUsers RETURN 100.0 * pathToDAUsers / totalUsers AS percentUsersToDA // Calculate the percentage of computers with a path to DA MATCH (totalComputers:Computer {domain:'EXTERNAL.LOCAL'}) MATCH p = shortestPath((pathToDAComputers:Computer {domain:'EXTERNAL.LOCAL'})-[r*1..]->(g:Group {name:'DOMAIN [email protected]'})) WITH COUNT(DISTINCT(totalComputers)) as totalComputers, COUNT(DISTINCT(pathToDAComputers)) as pathToDAComputers RETURN 100.0 * pathToDAComputers / totalComputers AS percentComputersToDA // Calculate the average attack path length MATCH p = shortestPath((n {domain:'EXTERNAL.LOCAL'})-[r*1..]->(g:Group {name:'DOMAIN [email protected]'})) RETURN toInt(AVG(LENGTH(p))) as avgPathLength
阶段3:产生弹性假设
在第一篇文章中,我们决定测试以下假设的有效性:
如果我们采取以下措施,那么只有5%的用户和5%的计算机应该能够访问域管理员用户:
– 限制域管理员帐户仅登录到域控制器。
在Cypher中,我们可以发现Domain Admins登录的所有系统,这些系统不是域控制器:
//查找登录到非域控制器的所有系统DA MATCH (c2:Computer)-[r3:MemberOf*1..]->(g2:Group {name:’DOMAIN [email protected]’}) WITH COLLECT(c2.name) as domainControllers MATCH (c1:Computer)-[r1:HasSession]->(u1:User)-[r2:MemberOf*1..]->(g1:Group {name:’DOMAIN [email protected]’}) WHERE NOT (c1.name IN domainControllers) RETURN DISTINCT(c1.name) ORDER BY c1.name ASC
如上图所示:登录到非域控制器计算机DA的结果列表。
或者,我们可以返回一组路径并在BloodHound UI中渲染这些路径:
//查找登录到非域控制器的所有系统DA,并返回路径: MATCH (c2:Computer)-[r3:MemberOf*1..]->(g2:Group {name:’DOMAIN [email protected]’}) WITH COLLECT(c2.name) as domainControllers MATCH p = (c1:Computer)-[r1:HasSession]->(u1:User)-[r2:MemberOf*1..]->(g1:Group {name:’DOMAIN [email protected]’}) WHERE NOT (c1.name IN domainControllers) RETURN p
在Cypher中,我们可以通过修改原始查询来有效地删除这些边缘,这次是删除有问题的边缘。此时,你可能需要创建图数据库的副本,以便在必要时可以返回到原始副本:
//删除任何DA用户会话,其中这些会话位于任何非域控制器的计算机上。 MATCH (c2:Computer)-[r3:MemberOf*1..]->(g2:Group {name:’DOMAIN [email protected]’}) WITH COLLECT(c2.name) as domainControllers MATCH (c1:Computer)-[r1:HasSession]->(u1:User)-[r2:MemberOf*1..]->(g1:Group {name:’DOMAIN [email protected]’}) WHERE NOT (c1.name IN domainControllers) DETACH DELETE r1
结论和未来的一些工作
正如第一篇博客文章中所提到的,我们希望尽可能自动化“第2阶段:分析攻击路径”的工作,因为这个阶段目前是需要高度手动和繁琐操作的。灵感可以在John Dunagan,Alice Zheng和Daniel Simons 关于Heat-Ray的开创性白皮书中找到,他们描述了一种机器学习方法,用于自动向分析师提供一个优先的补救措施列表,以消除Active Directory中的身份雪球攻击路径。我们还将继续致力于自动化的分析阶段,而无需完整的机器学习模型和方法。
通过这些博客文章,我们希望激励其他人使用我们所描述的分析成果,同时也发现他们自己有趣的见解和分析(并希望分享它们!)。
如果你对弹性方法论有任何疑问,请随时通过[email protected]与我联系。