传送门:新型弹性防御技术解析(上)
写在前面的话
这篇文章是本系列的下集,在本系列文章的上集中主要讨论的是关于敌对弹性防御技术的高级策略。那么在这篇文章里,我们会将本文所介绍的理论技术付诸于实践,并介绍详细的技术实现细节。
弹性应对方法
任何好的方法都需要有明确的目标,我们的弹性方法目标非常简单:
- 找出攻击者最有可能使用的所有攻击路径,并抢在攻击者之前去执行这些攻击路径。
- 显著减少攻击路径的数量。
- 对于我们无法消除的攻击路径,我们要想办法防止/缓解攻击。
- 维护一个高弹性的活动目录,用于抵御凭证窃取以及对象控制攻击。
我们主要通过下列四个阶段来实现:
第一阶段:枚举攻击路径
第一阶段的目标就是要收集下列信息:
- 从所有加入的域中的系统里收集本地管理员组信息;
- 用户会话的位置;
- 从所有安全AD对象中手机ACE,包括用户、组和域对象;
- 活动目录域的信任对象;
这一步可以使用SharpHound来完成,下载地址如下:【传送门】
关于SharpHound的详细信息请参考【这篇文章】。
下载了SharpHound.exe之后,你需要在加入了目标域的计算机设备(这些设备理论上可以访问企业网络中已加入该域的其他计算机系统)上运行该程序。如果你需要处理网络切割的情况,那你可能需要在网络中的多台计算机上运行SharpHound。为了方便演示,我们直接将SharpHound.exe放到了C盘下:C:> SharpHound.exe
运行之后,工具将帮我们从域中所有可访问到的计算机中收集到本地管理员组成员信息和活动目录安全组成员,并循环收集用户会话信息。为了收集综合用户会话数据,我们建议大家运行下列命令,整个数据收集过程大约需要一个小时左右的时间:C:> SharpHound.exe — CollectionMethod SessionLoop — MaxLoopTime 1h
最后,我们需要运行SharpHound的ACL收集方法来从计算机、用户和域安全对象中收集ACE信息:C:> SharpHound.exe — CollectionMethod ACL
SharpHound将会在你当前的工作目录中写入CSV文件。接下来,我们需要将这些CSV文件导入到BloodHound的图形数据库中。
第二阶段:分析攻击路径
弹性技术的作用就是减少活动目录(AD)的攻击面,而BloodHound允许我们对任意节点的攻击路径进行分析。为了方便演示,我们选择最常见且任何组织都想要实现的目标:减少Domain Admin用户账号的攻击路径。
一般来说,红队调查报告中会给用户介绍攻击者的攻击路径,而这些攻击路径中往往都包括横向渗透以及通过活动目录实现提权。而BloodHound的攻击路径非常丰富,其中包括凭证窃取、本地管理员提权以及安全对象控制等等。
在安装分析工具时,我们有几种选项,即Neo4j和BloodHound UI。你可以自行下载Neo4j Server【下载地址】和BloodHound UI【下载地址】,并手动进行配置,或者你也可以选择Walter Legowski的Neo4j/BloodHound自动安装器【下载地址】来完成安装。关于BloodHound的操作指南,请参考【这篇WiKi文献】。
当你配置好并运行Neo4j服务器之后,我们需要打开BloodHound UI并完成Neo4j认证。接下来,点击“Upload Data”(上传数据)按钮并上传第一阶段提取出来的CSV文件:
选择你的CSV文件,然后点击文件选择框中的“OK”按钮。接下来,程序会自动对CSV文件进行解析,并将他们加载到Neo4j数据库中。接下来,你就可以对这些数据进行分析了。
当你的数据上传到Neo4j数据库之后,打开BloodHound,默认它会给大家显示域管理员组的所有有效成员。右键点击“域管理员组”按钮,然后选择“Shortest Paths to Here”:
接下来,程序将会在后台运行allShortestPaths语句,然后BloodHound UI将会给用户呈现出分析后的结果路径:
还记得之前例子中的“USER99”节点吗,像那种一次性的修改是不会对缓解攻击路径有显著影响的。相反,我们应该想办法寻找出那些可能会暴露域管理员用户的行为模式以及特殊权限。比如说,通过点击“域管理员组”选项,我们可以看到关于该组的很多信息,其中包括用户会话的数量:
如果我们点击上图中的数字“117”,BloodHound UI将会以图形化的形式显示出域管理员组成员的会话信息:
除此之外,你还可以分析出整个网络系统中有效的本地管理员数量。使用BloodHound接口,你可以每次单独分析一个系统,或者在Neo4j Web控制台中导入一个需要分析的计算机列表。在开启了Neo4j服务器的情况下,打开你的浏览器并访问http://localhost:7474:
Cyhper语句如下所示:
MATCH p = (u1:User)-[r:MemberOf|AdminTo*1..]->(c:Computer)-[r2:HasSession]->(u2:User)-[r3:MemberOf*1..]->(g:Group {name:’DOMAIN ADMINS@EXTERNAL.LOCAL’})
RETURN COUNT(DISTINCT(u1)) AS adminCount,c.name as computerName
ORDER BY adminCount DESC
下图显示的是Neo4j Web控制台中的输出结果:
我们还可以评估域管理员组中的某个用户对整个网络环境的影响程度。这里我们需要使用三个因素来进行评估:拥有指向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 ADMINS@EXTERNAL.LOCAL'}))
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 ADMINS@EXTERNAL.LOCAL'}))
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 ADMINS@EXTERNAL.LOCAL'}))
RETURN toInt(AVG(LENGTH(p))) as avgPathLength
第三阶段:弹性假设生成
在样本数据库中,我们发现很多计算机都登录了Domain Admin,数量跟域中的计算机总数几乎相同。这是一种很常见的问题,一般来说,我们会限制Domain Admin或引入域控制器系统。
在本系列文章的上集中,我们提出了如下所示的假设:
如果我们采取下列措施,那么只有5%的用户和5%的电脑能够访问Domain Admin用户-限制Domain Admin只能在域控制器中登录(以及从域控制器中移除不必要的本地管理员权限!)。
在Cypher中,我们可以搜索出所有登录了域管理员账号的系统,而这些系统并不在域控制器之中:
// Find all systems DAs were logged onto which are NOT domain controllers
MATCH (c2:Computer)-[r3:MemberOf*1..]->(g2:Group {name:’DOMAIN CONTROLLERS@EXTERNAL.LOCAL’})
WITH COLLECT(c2.name) as domainControllers
MATCH (c1:Computer)-[r1:HasSession]->(u1:User)-[r2:MemberOf*1..]->(g1:Group {name:’DOMAIN ADMINS@EXTERNAL.LOCAL’})
WHERE NOT (c1.name IN domainControllers)
RETURN DISTINCT(c1.name)
ORDER BY c1.name ASC
下图显示的是不在域控制器之中登录的计算机信息:
或者,我们也可以给BloodHound UI提供一套路径集合,并在BloodHound UI中以图形化的方式查看路径信息:
// Find all systems DAs were logged onto that are NOT domain controllers, and return paths:
MATCH (c2:Computer)-[r3:MemberOf*1..]->(g2:Group {name:’DOMAIN CONTROLLERS@EXTERNAL.LOCAL’})
WITH COLLECT(c2.name) as domainControllers
MATCH p = (c1:Computer)-[r1:HasSession]->(u1:User)-[r2:MemberOf*1..]->(g1:Group {name:’DOMAIN ADMINS@EXTERNAL.LOCAL’})
WHERE NOT (c1.name IN domainControllers)
RETURN p
在Cypher中,我们可以通过修改原始查询语句来移除这些存在问题的“安全边际”。此时,你需要在图形数据库中创建一份拷贝,这样就可以拿修改后的路径图跟原始数据进行对比了:
// Remove any DA user sessions where those sessions are on any computers that are NOT domain controllers.
MATCH (c2:Computer)-[r3:MemberOf*1..]->(g2:Group {name:’DOMAIN CONTROLLERS@EXTERNAL.LOCAL’})
WITH COLLECT(c2.name) as domainControllers
MATCH (c1:Computer)-[r1:HasSession]->(u1:User)-[r2:MemberOf*1..]->(g1:Group {name:’DOMAIN ADMINS@EXTERNAL.LOCAL’})
WHERE NOT (c1.name IN domainControllers)
DETACH DELETE r1
第四阶段:修复处理优先级
最后一个阶段就是对第三阶段所发现的问题进行优先级排序,我们认为这项技术可以帮助企业有效地维护活动目录,而本技术所提供的高弹性特点可以有效抵御很多基于权限的攻击。简而言之,我们要尽可能多地找出攻击路径,并想办法消除它们的影响。下图显示的是企业环境下的攻击路径可视化数据图:
经过了四轮修复之后,攻击路径统计如下:
总结
正如我们之前所说的,我们需要让第二阶段的操作尽可能地以自动化的形式去实现,不过目前这个阶段还是得手动完成,所以可能有些枯燥乏味了。John Dunagan、Alice Zheng和Daniel Simon等人提出了一种基于机器学习的自动化方法,感兴趣的同学可以参考一下【文章传送门】。
希望我们所介绍的方法可以帮助社区的安全研究人员对自己的网络系统环境有一个更加深刻的认识,如果你对本文所介绍的弹性防御技术有任何疑问或者想要帮助我们提升BloodHound功能的话,欢迎大家与我联系(mailto:andy@specterops.io),或在论坛(http://bloodhoundgang.herokuapp.com)中留言。