
一款Python3终端应用程序,包含用于BloodHound数据集的Neo4j Cypher查询,并附带一个脚本,可自动将这些查询导入BloodHound CE。
终端

HTML报表

HTML报表(续)

BloodHound 是每位渗透测试人员的必备工具。然而,它的设计也带来了一些负面影响。以下是我遇到的最棘手的痛点,以及本工具旨在解决的问题:
JSON图之前,我需要将图结果以逐行格式的.txt文件呈现,才能从其他工具中实际攻击目标。本工具对红队和蓝队都极具价值。
用CypherHound重新掌控你的BloodHound数据!
grep/cut/awk友好格式的示例customqueries.json 导入脚本至BloodHound CE确保已安装python3并运行:
python3 -m pip install -r requirements.txt
启动程序:python3 cypherhound.py -c config.json -y queries.yaml
程序将读取json格式的配置文件。示例如下:
{
"user": "neo4j",
"pwd": "password",
"database": "neo4j"
}
其中:
user 是你的Neo4j用户名pwd 是你的Neo4j密码database 是你的Neo4j数据库程序从以下格式的YAML文件中读取查询。ad-queries.yaml 已作为示例提供,包含与Active Directory相关的查询。对于最短路径查询,msg_template不是必需的,但查询必须返回包含路径的变量
queries:
- group: general
desc: List all AddKeyCredentialLink privileges for owned principals
cypher: |-
MATCH (n {owned: true})-[r:AddKeyCredentialLink]->(m)
RETURN n.name AS n_name, m.name AS m_name, labels(m) AS labels_m, labels(n) AS labels_n
ORDER BY n.name
msg_template: |-
{{ n_name }} ({{ labels_n[0] }}/{{ labels_n[1] }}) has AddKeyCredentialLink over {{ m_name }} ({{
labels_m[0] }}/{{ labels_m[1] }})
键/值对说明见下表:
| 键 | 描述 |
|---|---|
group | 该查询所属的分组,分组由用户自定义,例如"general" |
desc |
params.*)程序使用Jinja2来渲染Cypher。使用set命令定义运行时参数,并在YAML中以{{ params.<键> }}引用它们。
CLI
set <键> <值...> # 例如:set user [email protected]
unset <键> # 可选
show # 可选
YAML示例
- group: user
desc: List all privileges for this user
cypher: |-
MATCH (n:User)-[r]->(m)
WHERE n.name =~ '((?i){{ params.user }})'
RETURN n.name AS n_name, TYPE(r) AS rel_type, labels(m) AS labels_m, m.name AS m_name
ORDER BY TYPE(r)
msg_template: |-
User {{ n_name }} has {{ rel_type }} over {{ m_name }} ({{ labels_m[0] }}/{{ labels_m[1] }})
常用参数模式
本仓库提供了一个query-importer.py脚本,用于从JSON文件自动将查询导入BloodHound CE UI。同时还提供了bh_query_converter.py,用于将面向终端应用程序的YAML文件转换为query-importer.py和BloodHound CE所期望的JSON格式。所需的JSON格式示例如下:
{
"queries": [
{
"name": "List all AddKeyCredentialLink privileges for owned principals",
"description": "List all AddKeyCredentialLink privileges for owned principals - General",
"query": "MATCH p=(n {owned: true})-[r:AddKeyCredentialLink]->(m)\nRETURN p\nORDER BY n.name"
},
{
"name": "List all AddKeyCredentialLink privileges for Users, Domain Users, Authenticated Users, and Everyone groups",
"description": "List all AddKeyCredentialLink privileges for Users, Domain Users, Authenticated Users, and Everyone groups - General",
"query": "MATCH p=(n:Group)-[r:AddKeyCredentialLink]->(m)\nWHERE (n.objectid =~ \"(?i)S-1-5-21-.*-513\" OR n.objectid =~ \"(?i).*-S-1-5-11\" OR n.objectid =~ \"(?i).*-S-1-1-0\" OR n.objectid =~ \"(?i).*-S-1-5-32-545\")\nRETURN p\nORDER BY n.name"
}
]
}
完整命令菜单如下:
Documented commands (use 'help -v' for verbose/'help <topic>' for details):
======================================================================================================
alias Manage aliases
clear Clear the terminal.
cls Clear the terminal.
edit Run a text editor and optionally open a file with it
export Run a query and save its results
help List available commands or provide detailed help for a specific command
history View, run, edit, save, or clear previously entered commands
list List queries by group.
macro Manage macros
report Run multiple queries and generate a HTML report
run Execute a query
run_pyscript Run a Python script file inside the console
run_script Run commands in script file that is encoded as either ASCII or UTF-8 text
search Full-text search through stored queries.
set Set a dynamic search parameter (set <TARGET> <VALUE...>)
shell Execute a command as if at the OS prompt
shortcuts List available shortcuts
show Show dynamic search parameters
unset Unset a dynamic search parameter (unset <TARGET>)
Undocumented commands:
======================
exit q quit stop

query-importer.py脚本将自动从JSON文件将查询导入BloodHound CE UI。同时还提供了bh_query_converter.py,用于将面向终端应用程序的YAML文件转换为query-importer.py和BloodHound CE所期望的JSON格式。
此脚本将面向终端应用程序的YAML文件转换为JSON文件,以便通过query-importer.py脚本轻松导入BloodHound CE。ad-queries.json已作为输出文件的示例提供,可直接用于query-importer.py并将查询导入BloodHound CE。
此脚本将读取BloodHound Legacy的customqueries.json文件,并通过API凭据将所有查询导入新版本的BloodHound Community Edition。提供该脚本是为了确保你为BloodHound Legacy创建的查询仍能与Community Edition一起使用。
此脚本将删除BloodHound中所有已保存的查询,以便重置以便将来导入。适用于BloodHound CE。
此脚本将从.txt文件中读取节点名称列表,并在数据库中将它们标记为owned或high-value。
用法
使用该脚本前,需准备两个文件:
.txt文件,格式为BloodHound格式
[email protected][email protected]COMPUTER.DOMAIN.LOCALNeo4j用户名、密码和数据库的json格式配置文件(示例如上)脚本的选项如下:
-h, --help 显示此帮助信息并退出
-c CONFIG, --config CONFIG
配置文件
-l LIST, --list LIST 节点名称列表
-o, --owned 将目标节点标记为owned
-v, --high-value 将目标节点标记为high-value
至少需要指定-o或-v
此脚本使用BloodHound CE API将SpecterOps BloodHoundQueryLibrary的已保存查询导入BloodHound Community Edition。
Queries.json / Queries.zipQueries.json / Queries.zip的URLplatforms(不区分大小写)过滤查询/api/v2/saved-queries)429),当存在Retry-After时使用SpecterOps将
Queries.json和Queries.zip作为发布工件发布(不存储在仓库中)。最新版本的下载URL为:
https://github.com/SpecterOps/BloodHoundQueryLibrary/releases/latest/download/Queries.jsonhttps://github.com/SpecterOps/BloodHoundQueryLibrary/releases/latest/download/Queries.zip
用法(本地文件)
python3 scripts/bhql/query-importer.py \
--token-id "<TOKEN_ID>" \
--token-key "<TOKEN_KEY>" \
--queries-file "/path/to/Queries.json" \
--base-url "http://127.0.0.1:8080"
用法(直接URL)
python3 scripts/bhql/query-importer.py \
--token-id "<TOKEN_ID>" \
--token-key "<TOKEN_KEY>" \
--queries-url "https://github.com/SpecterOps/BloodHoundQueryLibrary/releases/latest/download/Queries.json" \
--base-url "http://127.0.0.1:8080"
用法(自动:最新版本)
python3 scripts/bhql/query-importer.py \
--token-id "<TOKEN_ID>" \
--token-key "<TOKEN_KEY>" \
--bhql-latest \
--base-url "http://127.0.0.1:8080"
按平台过滤导入(示例)
# 仅导入支持Active Directory的查询
python3 scripts/bhql/query-importer.py \
--token-id "<TOKEN_ID>" \
--token-key "<TOKEN_KEY>" \
--bhql-latest \
--platforms "Active Directory" \
--base-url "http://127.0.0.1:8080"
# 导入多个平台的查询(任意匹配)
python3 scripts/bhql/query-importer.py \
--token-id "<TOKEN_ID>" \
--token-key "<TOKEN_KEY>" \
--bhql-latest \
--platforms "Active Directory" "Azure" \
--base-url "http://127.0.0.1:8080"
提示:你可以在BloodHound CE中创建一个令牌,并在此处使用其Token ID/Key。如果希望在导入前“重新开始”,可以使用附带的清理脚本(参见
scripts/bloodhound-ce/purge-queries.py)。
重新格式化现有的BloodHound查询YAML,以便:
如果在原始的DPAT仓库中看不到cypherhound功能已被合并,请访问我的DPAT分支,其中包含该功能。
此脚本将解析终端应用程序的原始导出结果,具体是列出所有用户组成员关系的Cypher查询,以此作为该工具输出解析的示例。你需要将此导出结果作为参数传递给脚本,同时传递一个NTDS.dit文件和一个输出目录。然后,脚本将在输出目录中为每个组名生成.txt文件,条目格式为DOMAIN\USER,与DPAT兼容。接着,你将该目录通过-g命令行参数传递给DPAT,从而使操作者能够为域中每个组生成组统计信息。
使用该脚本前,需准备两个文件:
NTDS.dit文件,行格式如下:domain\user:RID:LMhash:NTLMhash:::用法
usage: parse-memberships.py [-m MEMBERSHIPS_FILE] [-d DOMAIN] [-n NTDS_FILE] [-o OUTPUT_DIR] [--netbios NETBIOS] [--encoding ENCODING]
[--debug] [--no-index] [-h]
从成员关系文件映射用户到组,并与NTDS转储匹配。
options:
-m, --memberships-file MEMBERSHIPS_FILE
成员关系文件路径(BloodHound风格行)(默认:None)
-d, --domain DOMAIN FQDN域名(例如EXAMPLE.COM),用于成员关系正则匹配(默认:None)
-n, --ntds-file NTDS_FILE
NTDS转储文件路径(DOMAIN\user:hash 或 pwdump风格)(默认:None)
-o, --output-dir OUTPUT_DIR
写入每组输出文件的目录(默认:None)
--netbios NETBIOS NETBIOS/短域名,当NTDS行缺少域名(pwdump)时使用(默认:None)
--encoding ENCODING 输入文件的编码(默认:cp1252)
--debug 启用详细调试输出(默认:False)
--no-index 按组名命名组文件,而不是编号文件(不安全字符将被替换)(默认:False)
-h, --help 显示此帮助信息并退出
此脚本将解析列出所有可Kerberoast用户的原始导出结果,将用户与NTDS.dit中的条目匹配,并输出一个包含来自转储的所有可Kerberoast用户哈希条目的文件。然后,你可以将该输出文件通过-kz标志传递给DPAT,以提供破解后的可Kerberoast账户统计信息。
用法
usage: parse-kerberoastable.py [-k KERB_FILE] [-n NTDS_FILE] [-d DOMAIN] [-o OUTPUT] [--encoding ENCODING] [--debug] [-h]
将可Kerberoast用户名与NTDS.dit转储文件匹配
options:
-k, --kerb-file KERB_FILE
Kerberoast输出文件路径(默认:None)
-n, --ntds-file NTDS_FILE
NTDS转储文件路径(默认:None)
-d, --domain DOMAIN 域名(例如EXAMPLE.COM),用于正则匹配(默认:None)
-o, --output OUTPUT 写入匹配结果的路径(默认:None)
--encoding ENCODING 读取输入文件时使用的文件编码(默认:cp1252)
--debug 启用详细调试输出(默认:False)
-h, --help 显示此帮助信息并退出
Neo4j数据库和URIBloodHound 4.3.1及以上版本,某些边不适用于之前版本在2023年7月15日,我决定对项目做一些更改。在此日期之后,该项目将始终比赞助者使用的私有版本落后一个版本。请务必赞助我以获取最新查询、功能和错误修复。通过赞助这个层级,你还将获得我尚未公开的其他私有仓库的访问权限!
Azure边的查询如果你提交问题,请详细描述,并在可能的情况下提供输出结果(如果适用)。
| 查询的描述 |
cypher | 查询本身,采用Neo4j格式 |
msg_template | 基于Cypher变量的终端输出Jinja2模板,请使用Neo4j变量的别名,避免Jinja尝试将其渲染为嵌套变量 |
| 参数键 | 示例值 | 在Cypher中的使用 |
|---|
params.user | [email protected] | = {{ params.user }} |
params.user_regex | (?i)john\.doe(@example\.com)? | =~ '{{ params.user_regex }}' |
params.group | Domain [email protected] | = {{ params.group }} |
params.prefix | ACME- | STARTS WITH {{ params.prefix }} |