
感知检测的 Active Directory 攻击路径评分。 DreadHost Research | 与 OffsetInspect(PowerShell)和 OffsetScan(Rust)配套
BloodHound(以及在其之上构建的 PlumHound)能找到通往目标的某条路径。 NoiseHound 摄取相同的图数据,并按预期检测成本而非跳数对路径重新排序,因此操作员可以问“通往 Domain Admin 最安静的方式是什么”,而不只是“有什么方式”。
初次接触?操作员演练是了解本工具功能的最快途径——一份动手实践、以截图驱动的导览,从安装到实时 BloodHound CE 概念验证(评分写回 UI)、DeadAir 引擎,以及蓝队检测缺口报告。
项目状态(v1.2.0): 稳定,并已在多个域的真实 BloodHound 数据上测试。77 条语料边中有 37 条经过实验室实测,覆盖五个本地检测层级(Windows 审计、Defender for Endpoint、Elastic SIEM、Defender for Identity 运行时警报和 WDAC 审计),外加一个实测的 Azure/Entra 层级——以六个即用型配置文件形式随附于
profiles/,并有闭环证明表明它们会改变路径排名(docs/VALIDATION.md)。 语料包含 13 条 Azure/Entra 边(docs/AZURE.md),可直接从 AzureHound 输出摄取。 未实测的本地边和所有 Azure 边带有专家估算;校准工具(noisehound-calibrate)正是用来实测它们以及你自己环境的方式。请将未校准的排名视为有充分依据的指导,而非基准事实。
仅限授权参与使用。本工具针对你已获得书面许可测试的系统,为 OPSEC 规划对攻击路径进行评分。
NoiseHound 是一个独立的社区项目。它与 SpecterOps 或 BloodHound 项目无关联、未获其背书,也不与其相关;它使用 BloodHound 的开放数据格式。
.zip)、原始 JSON 文件或包含多个导出文件的目录,将其载入内部图。也接受规范化的 {nodes, edges} JSON 格式,用于离线分析和测试。AD CS ESC1-8 提权边会在加载时根据 BloodHound 收集的证书模板和 CA 事实合成(见下文)。effective_noise_score(0-100)。当多个权限连接同一对节点时,选择最安静的那个。语料库中不存在的边类型默认采用保守分数(60),以便在信息缺失时安全失败,而不是低报。可选的环境配置文件会根据目标声明的检测态势调整分数(见下文)。路径噪声刻意不采用简单求和。两次触发同一检测并不等于两倍响亮(SOC 分诊,而非原始事件计数)。NoiseHound 使用:
path_score = max(edge_scores) * 0.6 + mean(edge_scores) * 0.4
这种权重偏向于最响亮的单一步骤(一个糟糕的步骤往往会毁掉整个操作),同时仍然考虑累积暴露。权重是可配置的(--max-weight / --mean-weight),因此一旦从 APT29/Caldera 实验室获得真实检测数据,就可以根据经验进行调整。
每条路径还会报告一个检测概率——即触发相关告警的几率——它混合了最响亮的边与所有边的累积 noisy-OR(由 --correlation 调整)。它回答的问题与噪声评分不同:一条短但响亮的路径,其被捕获的总体概率可能低于一条长但安静的路径。使用 --rank-by probability 按此排序。
对于大型图,求解会被分派给 DeadAir,这是一个配套的 Rust 引擎(OffsetScan-to-OffsetInspect 层)。NoiseHound 仍然是功能丰富的前端——摄取、语料库、环境/Sigma、约束、报告——并将准备好的图交给求解它的任一引擎,因此无论哪种方式结果都相同。
--engine auto(默认):当找到 DeadAir 二进制文件且图很大(>= 5000 个节点)时使用 DeadAir;否则使用内置的 Python 求解器。--engine python:强制使用内置求解器(无需二进制文件)。--engine rust:强制使用 DeadAir(如果二进制文件缺失则报错)。DeadAir 的查找顺序为 $NOISEHOUND_DEADAIR、PATH,然后是同级 ../deadair/target/{release,debug}/ 构建。它在大型图上快 10-100 倍(25 万节点的图在 Python 中求解约需 30 秒,而它约需 2 秒),同时产生字节完全相同的排名。输出会记录运行的是哪个引擎。
噪声、跳数和检测概率会朝不同方向拉扯,因此 --pareto 返回帕累托前沿——即所有在三个指标上都不被其他路径同时击败的路径——而不是强行选出单一赢家。而真实操作存在约束:--avoid NODE 使路径避开特定主机(受 EDR 监控的跳板机、蜜罐),--avoid-edge TYPE 拒绝某种技术(例如 --avoid-edge DCSync)。两者都可重复使用,并会即时重新求解。
python -m noisehound -i export.zip -s jdoe -o "Domain Admins" --pareto
python -m noisehound -i export.zip -s jdoe -o "Domain Admins" --avoid FILESERVER01 --avoid-edge HasSession
加权 BloodHound 路径查找并非新事物,因此这里给出诚实的定位:
NoiseHound 的贡献在于组合:一个机器可读的 BloodHound 边到检测遥测语料库、一个以操作员 OPSEC(“通往 DA 的最安静方式”)为框架的噪声加权重新求解、一个适应目标声明姿态的环境模型,以及一个将实验室检测转化为实测分数的校准循环。图数学是通用商品;语料库和框架才是重点。其价值仅与语料库一样好,这就是为什么校准和社区贡献是一等公民——见下文。
cd NoiseHound
python -m pip install -r requirements.txt # networkx>=3.0
# optional editable install to get the `noisehound` command on PATH:
python -m pip install -e .
需要 Python 3.10+。
# Text summary (default)
python -m noisehound --input export.zip --objective "Domain Admins" --source jdoe
# JSON, for downstream tooling / correlation across the DreadHost suite
python -m noisehound -i export.zip -o "Domain Admins" -s jdoe -f json --out paths.json
# Self-contained HTML report
python -m noisehound -i export.zip -o "Domain Admins" -s jdoe -f html --out report.html
首先,对你的导出数据做一次解析器健全性检查(直方图 + 语料覆盖率,不进行路径分析)——这是在真实数据上验证 NoiseHound 最快的方式:
noisehound-inspect -i export.zip
无需使用 zip 文件,只需将 --input 指向 BloodHound CE 所填充的 Neo4j 数据库,NoiseHound 便会通过 Bolt 直接读取(已完成分析的)图:
pip install 'noisehound[neo4j]'
export NEO4J_PASSWORD=bloodhoundcommunityedition # match your BHCE compose
noisehound-inspect -i bolt://localhost:7687
python -m noisehound -i bolt://localhost:7687 -s jdoe -o "Domain Admins"
使用官方 compose 启动 BloodHound CE(在 7687 端口捆绑 Neo4j):
curl -L https://ghst.ly/getbhce | docker compose -f - up。
针对捆绑的示例进行尝试:
python -m noisehound -i samples/sample_graph.json -s jdoe -o "Domain Admins" -d CONTOSO.LOCAL
python -m noisehound -i samples/sample_bloodhound_ce.zip -s jdoe -o "Domain Admins"
python -m noisehound -i samples/sample_adcs_ce.zip -s jdoe -o "Domain Admins" # ADCS ESC1
# Full-spectrum export exercising every edge family (sessions, delegation, DCSync, ADCS, trusts):
python -m noisehound -i samples/sample_fullspectrum_ce.zip -s ALICE -o "Domain Admins" -d CONTOSO.LOCAL -k 3
最后那个例子最能说明这一论点:通往 Domain Admins 的最安静路径是 4 跳的会话路径,其排名高于 3 跳的 RDP 路径和 1 跳的 ADCS ESC1——跳数最多,噪声最小。
该示例展示了核心价值:最安静的路径是一条 4 跳的会话路径(得分 19.9),其排名高于一条 2 跳的 ForceChangePassword 捷径(36.4)。跳数更少并不意味着更安静。
最安静的路径正是检测最薄弱之处,因此添加 --defensive 可将输出切换为面向防御者的视角:它会标记出那些仅因遥测关闭或缺失才显得安静的边,将每条边映射到本可捕获它的控制措施,并按这些控制措施对最安静路径得分的提升幅度进行排序。
python -m noisehound -i export.zip -s jdoe -o "Domain Admins" --defensive
在全谱样本上,它发现通往 Domain Admins 的最安静路径取决于未被检测到的 LSASS 访问(HasSession,若被监控则从 20 升至 65),并建议部署 Sysmon Event 10——仅弥补这一处缺口就能将最安静路径的评分从 19.9 提升至 48.4。关于这一点以及模型其余部分的未来方向,请参阅 docs/ROADMAP.md。