
あなたのテンプレートベースのBloodHoundターミナルコンパニオンツール

Python3 製のターミナルアプリケーションで、Neo4j 用の BloodHound データセット向けサイファーと、それらを 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") |
params.*)プログラムはサイファーレンダリングに Jinja2 を使用します。set コマンドで実行時パラメータを定義し、YAML 内で {{ params.<key> }} として参照します。
CLI
set <key> <value...> # 例: set user [email protected]
unset <key> # 任意
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] }})
共通パラメータパターン
このリポジトリには、JSON ファイルから BloodHound CE UI へのクエリインポートを自動化する query-importer.py スクリプトが含まれています。また、ターミナルアプリケーション向けの YAML ファイルを query-importer.py および BloodHound CE が期待する JSON 形式に変換する bh_query_converter.py も提供されています。必要な 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 にクエリを自動インポートします。ターミナルアプリケーション向けの YAML ファイルを query-importer.py および BloodHound CE が期待する JSON 形式に変換する bh_query_converter.py も提供されています。
このスクリプトは、ターミナルアプリケーション向けの YAML を、query-importer.py スクリプトを介して BloodHound CE に簡単にインポートできる JSON ファイルに変換します。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 としてマークします。
使用方法
スクリプトを使用するには、2つのファイルを準備する必要があります:
BloodHound 形式のノード名を行ごとに含む .txt ファイル
[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 を指定する必要があります。
このスクリプトは、SpecterOps BloodHoundQueryLibrary の保存済みクエリを、BloodHound CE API を使用して 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 を次のように再フォーマットします:
cypherhound の機能が元の DPAT リポジトリにマージされていない場合は、機能を含む私の DPAT フォーク にアクセスしてください。
このスクリプトは、ターミナルアプリケーションからの生のエクスポート(具体的には、すべてのユーザーグループメンバーシップを一覧表示するサイファー)を解析し、このツールの出力がどのように解析されるかの例を示します。このエクスポートをスクリプトのパラメーターとして、NTDS.dit ファイル、出力ディレクトリとともに渡します。スクリプトは、グループ名ごとに DOMAIN\USER 形式のエントリを含む .txt ファイルを出力ディレクトリに生成します。これは DPAT と互換性があります。その後、このディレクトリを DPAT の -g コマンドライン引数で渡すことで、オペレーターはドメイン内のすべてのグループについてグループ固有の統計情報を生成できます。
スクリプトを使用するには、2つのファイルを準備する必要があります:
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]
Map users to groups from memberships file and match against NTDS dump.
options:
-m, --memberships-file MEMBERSHIPS_FILE
Path to memberships file (BloodHound-style lines) (default: None)
-d, --domain DOMAIN FQDN domain (e.g., EXAMPLE.COM) used in the membership regex (default: None)
-n, --ntds-file NTDS_FILE
Path to NTDS dump (DOMAIN\user:hash or pwdump-style) (default: None)
-o, --output-dir OUTPUT_DIR
Directory to write per-group output files (default: None)
--netbios NETBIOS NETBIOS/short domain to prefix when NTDS lines lack a domain (pwdump) (default: None)
--encoding ENCODING Encoding for input files (default: cp1252)
--debug Enable verbose debug output (default: False)
--no-index Name group files after the group instead of numbered files (unsafe chars replaced) (default: False)
-h, --help Show this help message and exit
このスクリプトは、すべての kerberoastable ユーザーを一覧表示する生のエクスポートを解析し、ユーザーを NTDS.dit 内のエントリと照合し、ダンプから kerberoastable なユーザーハッシュエントリをすべて含む出力ファイルを生成します。その後、この出力ファイルを DPAT に -kz フラグで渡すことで、クラックされた kerberoastable アカウントの統計情報を提供します。
使用方法
usage: parse-kerberoastable.py [-k KERB_FILE] [-n NTDS_FILE] [-d DOMAIN] [-o OUTPUT] [--encoding ENCODING] [--debug] [-h]
Match kerberoastable usernames against an NTDS.dit dump file
options:
-k, --kerb-file KERB_FILE
Path to Kerberoast output file (default: None)
-n, --ntds-file NTDS_FILE
Path to NTDS dump file (default: None)
-d, --domain DOMAIN Domain (e.g., EXAMPLE.COM) for regex matching (default: None)
-o, --output OUTPUT Path to write matches (default: None)
--encoding ENCODING File encoding to use when reading input files (default: cp1252)
--debug Enable verbose debug output (default: False)
-h, --help Show this help message and exit
Neo4j データベースと URI を使用するように設定されていますBloodHound 4.3.1 以降のバージョン向けに構築されています。以前のバージョンでは特定のエッジが機能しません2023年7月15日、私はプロジェクトにいくつかの変更を加えることにしました。この日以降、本プロジェクトは、スポンサー向けのプライベートバージョンよりも常に1バージョン古い状態で公開されます。最新のサイファー、機能、バグ修正にアクセスするには、スポンサーになってください。このティアでスポンサーになると、公開していない追加のプライベートリポジトリにもアクセスできるようになります!
Azure エッジ用のサイファーを追加問題を報告する際は、具体的に記述し、可能であれば出力を提供してください(該当する場合)。
desc | クエリの説明 |
cypher | Neo4j形式のクエリ本文 |
msg_template | サイファー変数に基づくターミナル出力用のJinja2テンプレート。Neo4j変数にはエイリアスを使用し、Jinjaがネスト変数としてレンダリングしようとするのを防ぐ |
| パラメータキー | 値の例 | サイファー内での使用法 |
|---|
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 }} |