
Tu herramienta de acompañante de terminal de BloodHound basada en plantillas

Una aplicación de terminal Python3 que contiene consultas Neo4j para conjuntos de datos de BloodHound con un script para automatizar su importación en BloodHound CE.
Terminal

Informe HTML

Informe HTML (continuación)

BloodHound es una herramienta fundamental para todo probador de penetración. Sin embargo, tiene algunos efectos secundarios negativos debido a su diseño. Cubriré los mayores puntos débiles que he experimentado y lo que esta herramienta pretende abordar:
JSON exportados, necesito los resultados del gráfico en un formato línea por línea en un archivo .txt para realmente atacar cosas desde otras herramientasEsta herramienta puede proporcionar un valor significativo tanto para equipos rojos como azules.
¡Recupera el control de tus datos de BloodHound con CypherHound!
grep/cut/awkcustomqueries.json de BloodHound Legacy a BloodHound CE incluidoAsegúrate de tener python3 instalado y ejecuta:
python3 -m pip install -r requirements.txt
Inicia el programa con: python3 cypherhound.py -c config.json -y queries.yaml
El programa leerá un archivo de configuración en formato json. A continuación se muestra un ejemplo de este archivo:
{
"user": "neo4j",
"pwd": "password",
"database": "neo4j"
}
donde:
user es tu nombre de usuario de Neo4jpwd es tu contraseña de Neo4jdatabase es tu base de datos de Neo4jEl programa lee consultas de un archivo YAML en el siguiente formato. Se ha proporcionado ad-queries.yaml como ejemplo que contiene consultas relacionadas con Active Directory. msg_template no es necesario para consultas de caminos más cortos, pero deben devolver la variable que contiene el camino
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] }})
A continuación se muestra una tabla de desglose de los pares clave/valor:
params.*)El programa utiliza Jinja2 para renderizar Cypher. Define parámetros de ejecución con el comando set y haz referencia a ellos en YAML como {{ params.<key> }}.
CLI
set <key> <value...> # e.g., set user [email protected]
unset <key> # optional
show # optional
Ejemplo 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] }})
Patrones de Parámetros Comunes
Este repositorio proporciona un script query-importer.py para automatizar la importación de consultas en la UI de BloodHound CE desde un archivo JSON. También se ha proporcionado bh_query_converter.py para convertir un archivo YAML destinado a la aplicación de terminal al formato JSON esperado por query-importer.py y BloodHound CE. A continuación se muestra un ejemplo del formato JSON requerido:
{
"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"
}
]
}
El menú completo de comandos se muestra a continuación:
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

El script query-importer.py automatizará la importación de consultas en la UI de BloodHound CE desde un archivo JSON. También se ha proporcionado bh_query_converter.py para convertir un archivo YAML destinado a la aplicación de terminal al formato JSON esperado por query-importer.py y BloodHound CE.
Este script convertirá un YAML destinado a la aplicación de terminal en un archivo JSON para facilitar su importación en BloodHound CE a través del script query-importer.py. Se ha proporcionado ad-queries.json como ejemplo de cómo se ve un archivo de salida y está listo para query-importer.py e importar las consultas en BloodHound CE.
Este script leerá un archivo customqueries.json de BloodHound Legacy e importará todas las consultas en la nueva versión de BloodHound Community Edition con tus credenciales de API. Se proporciona para que las consultas que hayas creado para BloodHound Legacy aún puedan usarse con Community Edition.
Este script eliminará todas las consultas guardadas de BloodHound para restablecerlas para futuras importaciones. Es para BloodHound CE.
Este script leerá una lista de nombres de nodos desde un archivo .txt y los marcará como 'owned' o 'high-value' en la base de datos.
Uso
Para usar el script, debes tener dos archivos preparados:
.txt línea por línea que contenga nombres de nodos en el formato de BloodHound
[email protected][email protected]COMPUTER.DOMAIN.LOCALjson que contenga tu nombre de usuario, contraseña y base de datos de Neo4j (ejemplo mostrado arriba)El script tiene las siguientes opciones:
-h, --help show this help message and exit
-c CONFIG, --config CONFIG
Config file
-l LIST, --list LIST List of node names
-o, --owned Set target nodes as owned
-v, --high-value Set target nodes as high-value
Debes especificar al menos -o o -v
Este script importa las consultas guardadas de SpecterOps BloodHoundQueryLibrary en BloodHound Community Edition usando la API de BloodHound CE.
Queries.json / Queries.zip localQueries.json / Queries.zipplatforms (sin distinción de mayúsculas/minúsculas)/api/v2/saved-queries)429) usando Retry-After cuando está presenteSpecterOps publica
Queries.jsonyQueries.zipcomo artefactos de versión (no almacenados en el repositorio). Las URL de descarga de la última versión son:
https://github.com/SpecterOps/BloodHoundQueryLibrary/releases/latest/download/Queries.jsonhttps://github.com/SpecterOps/BloodHoundQueryLibrary/releases/latest/download/Queries.zip
Uso (archivo local)
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"
Uso (URL directa)
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"
Uso (automático: última versión)
python3 scripts/bhql/query-importer.py \
--token-id "<TOKEN_ID>" \
--token-key "<TOKEN_KEY>" \
--bhql-latest \
--base-url "http://127.0.0.1:8080"
Importación filtrada por plataforma (ejemplos)
# Importar solo consultas que soporten 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"
# Importar consultas para múltiples plataformas (cualquier coincidencia)
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"
Consejo: Puedes crear un token en BloodHound CE y usar su ID/Clave de Token aquí. Si deseas "empezar de nuevo" antes de importar, usa el script de purga incluido (ver
scripts/bloodhound-ce/purge-queries.py).
Re-formatea un YAML existente de consultas de BloodHound para que:
Si no ves la funcionalidad de cypherhound fusionada en el repositorio original de DPAT, accede a mi fork de DPAT que la tendrá.
Este script analizará una exportación en bruto de la aplicación de terminal, específicamente la consulta para listar todas las pertenencias a grupos de usuarios como ejemplo de cómo se puede analizar la salida de esta herramienta. Pasarás esta exportación como parámetro al script, un archivo NTDS.dit y un directorio de salida. Luego producirá archivos .txt en el directorio de salida para cada nombre de grupo con entradas en formato DOMINIO\USUARIO, compatible con DPAT. Luego pasarás este directorio con el argumento de línea de comandos -g a DPAT, permitiendo al operador producir estadísticas específicas de grupo para cada grupo en un dominio.
Para usar el script, debes tener dos archivos preparados:
NTDS.dit con líneas en el siguiente formato: dominio\usuario:RID:LMhash:NTLMhash:::Uso
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
Este script analizará la exportación en bruto para listar todos los usuarios kerberoastable, emparejará los usuarios con entradas en un NTDS.dit y producirá un archivo de salida que contiene todas las entradas de hash de usuario kerberoastable del volcado. Luego pasarás este archivo de salida a DPAT con la bandera -kz para proporcionar estadísticas de cuentas kerberoastable descifradas.
Uso
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
URI predeterminadas de Neo4jBloodHound 4.3.1 o superiores, ciertos bordes no funcionarán en versiones anterioresEl 15 de julio de 2023 decidí hacer algunos cambios al proyecto. Después de esta fecha, este proyecto siempre se mantendrá una versión por detrás de la versión privada para patrocinadores. Asegúrate de patrocinarme para acceder a las consultas, funciones y correcciones de errores más recientes. Al patrocinarme en este nivel, también obtendrás acceso a repositorios privados adicionales que no he publicado al público.
AzurePor favor, sé descriptivo con cualquier problema que decidas abrir y, si es posible, proporciona la salida (si corresponde).
| Clave |
|---|
| Descripción |
|---|
group | El grupo al que pertenece esta consulta, los grupos son definidos por el usuario, ej. "general" |
desc | La descripción de la consulta |
cypher | La consulta en sí en formato Neo4j |
msg_template | Plantilla Jinja2 para la salida de terminal basada en variables de consulta, usa alias para las variables de Neo4j para evitar que Jinja intente renderizar como variables anidadas |
| Clave de parámetro | Valor de ejemplo | Uso en 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 }} |