Last active
April 28, 2025 15:30
-
-
Save Esonhugh/00f2f2fbcd4dcfca56661d5d60a3b147 to your computer and use it in GitHub Desktop.
Revisions
-
Esonhugh revised this gist
Apr 28, 2025 . No changes.There are no files selected for viewing
-
Esonhugh revised this gist
Apr 28, 2025 . 1 changed file with 1 addition and 83 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -20,87 +20,5 @@ 3. connect with your k8s `neo4j://neo4j:yourpassword@<cluster-ip>:47687` ### Simple deployment with docker compose/swarm Use official docker-compose.yml -
Esonhugh revised this gist
Apr 28, 2025 . 1 changed file with 8 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -13,4 +13,12 @@ data: bhe_default_admin_last_name: "default admin" bhe_default_admin_email_address: "[email protected]" bhe_default_admin_password: "default_admin_passwords" ## Let it don't expire when start bhe_default_admin_expire_now: "false" ## New version bhe_disable_cypher_complexity_limit: 'false' bhe_enable_cypher_mutations: 'false' bhe_graph_driver: neo4j bhe_recreate_default_admin: 'false'
-
Esonhugh revised this gist
Jun 14, 2024 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ # Bloodhound as a service (Kubernetes Deployments/Docker Compose) ### Usage -
Esonhugh revised this gist
Jun 14, 2024 . 1 changed file with 88 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,7 +6,7 @@ 2. Change user (default user: esonhugh) 3. Change ingress host name to your team server 4. Deploy it! 5. `kubectl apply -f deployment-service.yaml -f ingress.yaml -f configmap.yaml # -n <change namespace you deploy> ` 6. use `pipx install git+https://github.com/exploide/bloodhound-cli.git` 7. `bhcli auth https://to/your/server` 8. Auth with username + password @@ -17,4 +17,90 @@ 1. uncomment service part of neo4j node port 2. change passwords for your neo4j 3. connect with your k8s `neo4j://neo4j:yourpassword@<cluster-ip>:47687` ### Simple deployment with docker compose/swarm ```yaml version: '3' services: app-db: image: docker.io/library/postgres:13.2 environment: - POSTGRES_USER=${POSTGRES_USER:-bloodhound} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-bloodhoundcommunityedition} - POSTGRES_DB=${POSTGRES_DB:-bloodhound} # Database ports are disabled by default. Please change your database password to something secure before uncommenting # ports: # - 127.0.0.1:${POSTGRES_PORT:-5432}:5432 volumes: - postgres-data:/var/lib/postgresql/data healthcheck: test: [ "CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-bloodhound} -d ${POSTGRES_DB:-bloodhound} -h 127.0.0.1 -p ${POSTGRES_PORT:-5432}" ] interval: 10s timeout: 5s retries: 5 start_period: 30s graph-db: image: docker.io/library/neo4j:4.4 environment: - NEO4J_AUTH=${NEO4J_USER:-neo4j}/${NEO4J_SECRET:-bloodhoundcommunityedition} - NEO4J_dbms_allow__upgrade=${NEO4J_ALLOW_UPGRADE:-true} # Database ports are disabled by default. Please change your database password to something secure before uncommenting ports: - 127.0.0.1:${NEO4J_DB_PORT:-7687}:7687 - 127.0.0.1:${NEO4J_WEB_PORT:-7474}:7474 volumes: - ${NEO4J_DATA_MOUNT:-neo4j-data}:/data healthcheck: test: [ "CMD-SHELL", "wget -O /dev/null -q http://localhost:${NEO4J_WEB_PORT:-7474} || exit 1" ] interval: 10s timeout: 5s retries: 5 start_period: 30s bloodhound: image: docker.io/specterops/bloodhound:${BLOODHOUND_TAG:-latest} environment: - bhe_disable_cypher_qc=${bhe_disable_cypher_qc:-false} - bhe_database_connection=user=${POSTGRES_USER:-bloodhound} password=${POSTGRES_PASSWORD:-bloodhoundcommunityedition} dbname=${POSTGRES_DB:-bloodhound} host=app-db - bhe_neo4j_connection=neo4j://${NEO4J_USER:-neo4j}:${NEO4J_SECRET:-bloodhoundcommunityedition}@graph-db:7687/ - bhe_default_admin_first_name="default admin" - bhe_default_admin_last_name="default admin" - bhe_default_admin_email_address="[email protected]" - bhe_default_admin_password="default_admin_passwords" # Change it - bhe_default_admin_principal_name="esonhugh" # Change it ### Add additional environment variables you wish to use here. ### For common configuration options that you might want to use environment variables for, see `.env.example` ### example: bhe_database_connection=${bhe_database_connection} ### The left side is the environment variable you're setting for bloodhound, the variable on the right in `${}` ### is the variable available outside of Docker ports: ### Default to localhost to prevent accidental publishing of the service to your outer networks ### These can be modified by your .env file or by setting the environment variables in your Docker host OS - ${BLOODHOUND_HOST:-127.0.0.1}:${BLOODHOUND_PORT:-8080}:8080 ### Uncomment to use your own bloodhound.config.json to configure the application # volumes: # - ./bloodhound.config.json:/bloodhound.config.json:ro depends_on: app-db: condition: service_healthy graph-db: condition: service_healthy volumes: neo4j-data: postgres-data: ``` -
Esonhugh revised this gist
Jun 14, 2024 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -11,6 +11,7 @@ 7. `bhcli auth https://to/your/server` 8. Auth with username + password 9. bhcli queries ./custom-queries.json to import it 10. upload collected data: http://<your teamserver - bloodhound server>/ui/administration/file-ingest (support json and zip) ### exposure neo4j service -
Esonhugh revised this gist
Jun 14, 2024 . 2 changed files with 23 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -11,3 +11,9 @@ 7. `bhcli auth https://to/your/server` 8. Auth with username + password 9. bhcli queries ./custom-queries.json to import it ### exposure neo4j service 1. uncomment service part of neo4j node port 2. change passwords for your neo4j 3. connect with your k8s `neo4j://neo4j:yourpassword@<cluster-ip>:47687` This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -73,3 +73,20 @@ spec: port: 8080 targetPort: 8080 type: ClusterIP #### # # Uncommented following if you just need neo4j service # # Warning: change your neo4j user and password in configmap! #apiVersion: v1 #kind: Service #metadata: # name: bloodhound-neo4j #spec: # selector: # app: bloodhound # ports: # - protocol: TCP # port: 7687 # targetPort: 7687 # nodePort: 47687 # type: nodePort -
Esonhugh created this gist
Jun 14, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,13 @@ # Bloodhound as a service (Kubernetes Deployments) ### Usage 1. Change password (default password: default_admin_passwords) 2. Change user (default user: esonhugh) 3. Change ingress host name to your team server 4. Deploy it! 5. `kubectl apply -f deployment-service.yaml ingress.yaml configmap.yaml # -n <change namespace you deploy> ` 6. use `pipx install git+https://github.com/exploide/bloodhound-cli.git` 7. `bhcli auth https://to/your/server` 8. Auth with username + password 9. bhcli queries ./custom-queries.json to import it This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,16 @@ apiVersion: v1 kind: ConfigMap metadata: name: bloodhound-config data: NEO4J_AUTH: "neo4j/bloodhoundcommunityedition" POSTGRES_USER: "bloodhound" POSTGRES_PASSWORD: "bloodhoundcommunityedition" bhe_database_connection: "user=bloodhound password=bloodhoundcommunityedition dbname=bloodhound host=127.0.0.1" bhe_neo4j_connection: "neo4j://neo4j:[email protected]:7687/" bhe_default_admin_principal_name: "esonhugh" bhe_default_admin_first_name: "default admin" bhe_default_admin_last_name: "default admin" bhe_default_admin_email_address: "[email protected]" bhe_default_admin_password: "default_admin_passwords"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,190 @@ [ { "name": "ALL Path from Domain Users to High Value Targets", "query": "MATCH (g:Group) WHERE g.name STARTS WITH 'DOMAIN USERS' MATCH (n {highvalue:true}),p=shortestPath((g)-[r*1..]->(n)) return p" }, { "name": "Find all active Domain Admin sessions", "query": "MATCH (n:User)-[:MemberOf]->(g:Group) WHERE g.objectid ENDS WITH '-512' MATCH p = (c:Computer)-[:HasSession]->(n) return p" }, { "name": "Find all computers with Unconstrained Delegation", "query": "MATCH (c:Computer {unconstraineddelegation:true}) return c" }, { "name": "Find all computers with unsupported operating systems", "query": "MATCH (H:Computer) WHERE H.operatingsystem =~ '.*(2000|2003|2008|xp|vista|7|me)*.' RETURN H" }, { "name": "Find all Kerberoastable Users", "query": "MATCH (n:User)WHERE n.hasspn=true RETURN n" }, { "name": "Find all the unconstrained delegation systems that are not part of the domain controllers group", "query": "MATCH (dc:Computer)-[:MemberOf*1..]->(g:Group) WHERE g.objectsid ENDS WITH \"516\" WITH COLLECT(dc) as domainControllers MATCH p = (d:Domain)-[:Contains*1..]->(c:Computer {unconstraineddelegation:true}) WHERE NOT c in domainControllers RETURN COUNT(p)" }, { "name": "Find all users a part of the VPN group", "query": "Match p=(u:User)-[:MemberOf]->(g:Group) WHERE toUPPER (g.name) CONTAINS 'VPN' return p" }, { "name": "Find all users that have local admin rights", "query": "MATCH p=(m:User)-[r:AdminTo]->(n:Computer) RETURN p" }, { "name": "Find All Users with an SPN/Find all Kerberoastable Users with passwords last set > 5 years ago", "query": "MATCH (u:User) WHERE u.hasspn=true AND u.pwdlastset < (datetime().epochseconds - (1825 * 86400)) and NOT u.pwdlastset IN [-1.0, 0.0] RETURN u" }, { "name": "Find All Users with an SPN/Find all Kerberoastable Users with passwords last set less than 5 years ago", "query": "MATCH (u:User) WHERE u.hasspn=true AND u.pwdlastset < (datetime().epochseconds - (1825 * 86400)) AND NOT u.pwdlastset IN [-1.0, 0.0] RETURN u.name, u.pwdlastset order by u.pwdlastset " }, { "name": "Find computers that allow unconstrained delegation that AREN\u2019T domain controllers.", "query": "MATCH (c1:Computer)-[:MemberOf*1..]->(g:Group) WHERE g.objectid ENDS WITH '-516' WITH COLLECT(c1.name) AS domainControllers MATCH (c2:Computer {unconstraineddelegation:true}) WHERE NOT c2.name IN domainControllers RETURN c2" }, { "name": "Find computers with constrained delegation permissions and the corresponding targets where they allowed to delegate", "query": "MATCH (c:Computer) WHERE c.allowedtodelegate IS NOT NULL RETURN c" }, { "name": "Find constrained delegation", "query": "MATCH p=(u:User)-[:AllowedToDelegate]->(c:Computer) RETURN p" }, { "name": "Find groups that can reset passwords (Warning: Heavy)", "query": "MATCH p=(m:Group)-[r:ForceChangePassword]->(n:User) RETURN p" }, { "name": "Find groups that contain both users and computers", "query": "MATCH (c:Computer)-[r:MemberOf*1..]->(groupsWithComps:Group) WITH groupsWithComps MATCH (u:User)-[r:MemberOf*1..]->(groupsWithComps) RETURN DISTINCT(groupsWithComps) as groupsWithCompsAndUsers" }, { "name": "Find groups that have local admin rights (Warning: Heavy)", "query": "MATCH p=(m:Group)-[r:AdminTo]->(n:Computer) RETURN p" }, { "name": "Find if any domain user has interesting permissions against a GPO (Warning: Heavy)", "query": "MATCH p=(u:User)-[r:AllExtendedRights|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|GpLink*1..]->(g:GPO) RETURN p" }, { "name": "Find if unprivileged users have rights to add members into groups", "query": "MATCH (n:User {admincount:False}) MATCH p=allShortestPaths((n)-[r:AddMember*1..]->(m:Group)) RETURN p" }, { "name": "Find Kerberoastable users and where they are AdminTo", "query": "OPTIONAL MATCH (u1:User) WHERE u1.hasspn=true OPTIONAL MATCH (u1)-[r:AdminTo]->(c:Computer) RETURN u1" }, { "name": "Find Kerberoastable users who are members of high value groups", "query": "MATCH (u:User)-[r:MemberOf*1..]->(g:Group) WHERE g.highvalue=true AND u.hasspn=true RETURN u" }, { "name": "Find Kerberoastable Users with a path to DA", "query": "MATCH (u:User {hasspn:true}) MATCH (g:Group) WHERE g.objectid ENDS WITH '-512' MATCH p = shortestPath( (u)-[*1..]->(g) ) RETURN p" }, { "name": "Find Kerberoastable Users with a path to High Value", "query": "MATCH (u:User {hasspn:true}),(n {highvalue:true}),p = shortestPath( (u)-[*1..]->(n) ) RETURN p" }, { "name": "Find logged in Admins", "query": "MATCH p=(a:Computer)-[r:HasSession]->(b:User) WITH a,b,r MATCH p=shortestPath((b)-[:AdminTo|MemberOf*1..]->(a)) RETURN p" }, { "name": "Find machines Domain Users can RDP into", "query": "match p=(g:Group)-[:CanRDP]->(c:Computer) where g.objectid ENDS WITH '-513' return p" }, { "name": "Find Servers Domain Users can RDP To", "query": "match p=(g:Group)-[:CanRDP]->(c:Computer) where g.name STARTS WITH 'DOMAIN USERS' AND c.operatingsystem CONTAINS 'Server' return p" }, { "name": "Find users that can be AS-REP roasted", "query": "MATCH (u:User {dontreqpreauth: true}) RETURN u" }, { "name": "Find users that have never logged on and account is still active", "query": "MATCH (n:User) WHERE n.lastlogontimestamp=-1.0 AND n.enabled=TRUE RETURN n " }, { "name": "Find users that logged in within the last 90 days", "query": "MATCH (u:User) WHERE u.lastlogon < (datetime().epochseconds - (90 * 86400)) and NOT u.lastlogon IN [-1.0, 0.0] RETURN u" }, { "name": "Find users with passwords last set within the last 90 days", "query": "MATCH (u:User) WHERE u.pwdlastset < (datetime().epochseconds - (90 * 86400)) and NOT u.pwdlastset IN [-1.0, 0.0] RETURN u" }, { "name": "Find what groups can RDP", "query": "MATCH p=(m:Group)-[r:CanRDP]->(n:Computer) RETURN p" }, { "name": "Find what's next", "query": "MATCH p=shortestPath((c {owned: true})-[*1..3]->(s)) WHERE NOT c = s RETURN p" }, { "name": "Groups with Computer and User Objects", "query": "MATCH (c:Computer)-[r:MemberOf*1..]->(groupsWithComps:Group) WITH groupsWithComps MATCH (u:User)-[r:MemberOf*1..]->(groupsWithComps) RETURN DISTINCT(groupsWithComps) as groupsWithCompsAndUsers" }, { "name": "List all owned computers", "query": "MATCH (m:Computer) WHERE m.owned=TRUE RETURN m" }, { "name": "List all owned groups", "query": "MATCH (m:User) WHERE m.owned=TRUE RETURN m" }, { "name": "List all owned users", "query": "MATCH (m:User) WHERE m.owned=TRUE RETURN m" }, { "name": "List the groups of all owned users", "query": "MATCH (m:User) WHERE m.owned=TRUE WITH m MATCH p=(m)-[:MemberOf*1..]->(n:Group) RETURN p" }, { "name": "Non Admin Groups with High Value Privileges", "query": "MATCH p=(g:Group)-[r:Owns|:WriteDacl|:GenericAll|:WriteOwner|:ExecuteDCOM|:GenericWrite|:AllowedToDelegate|:ForceChangePassword]->(n:Computer) WHERE NOT g.name CONTAINS 'ADMIN' RETURN p" }, { "name": " Return the name of every computer in the database where at least one SPN for the computer contains the string 'MSSQL'", "query": "MATCH (c:Computer) WHERE ANY (x IN c.serviceprincipalnames WHERE toUpper(x) CONTAINS 'MSSQL') RETURN c" }, { "name": "Shortest Path from Domain Users to High Value Targets", "query": "MATCH (g:Group),(n {highvalue:true}),p=shortestPath((g)-[r*1..]->(n)) WHERE g.name STARTS WITH 'DOMAIN USERS' return p" }, { "name": "Show all high value target's groups", "query": "MATCH p=(n:User)-[r:MemberOf*1..]->(m:Group {highvalue:true}) RETURN p" }, { "name": "Show owned Nodes with Groups", "query": "MATCH (u:User {owned:true}), (g:Group), p=(u)-[:MemberOf]->(g) RETURN p" }, { "name": "Top Ten Computers with Most Admins", "query": "MATCH (n:User),(m:Computer), (n)-[r:AdminTo]->(m) WHERE NOT n.name STARTS WITH 'ANONYMOUS LOGON' AND NOT n.name='' WITH m, count(r) as rel_count order by rel_count desc LIMIT 10 MATCH p=(m)<-[r:AdminTo]-(n) RETURN p" }, { "name": "Top Ten Computers with Most Sessions", "query": "MATCH (n:User),(m:Computer), (n)<-[r:HasSession]-(m) WHERE NOT n.name STARTS WITH 'ANONYMOUS LOGON' AND NOT n.name='' WITH m, count(r) as rel_count order by rel_count desc LIMIT 10 MATCH p=(m)-[r:HasSession]->(n) RETURN n,r,m" }, { "name": "Top Ten Users with Most Local Admin Rights", "query": "MATCH (n:User),(m:Computer), (n)-[r:AdminTo]->(m) WHERE NOT n.name STARTS WITH 'ANONYMOUS LOGON' AND NOT n.name='' WITH n, count(r) as rel_count order by rel_count desc LIMIT 10 MATCH p=(m)<-[r:AdminTo]-(n) RETURN p" }, { "name": "Top Ten Users with Most Sessions", "query": "MATCH (n:User),(m:Computer), (n)<-[r:HasSession]-(m) WHERE NOT n.name STARTS WITH 'ANONYMOUS LOGON' AND NOT n.name='' WITH n, count(r) as rel_count order by rel_count desc LIMIT 10 MATCH p=(m)-[r:HasSession]->(n) RETURN p" }, { "name": "View all GPOs", "query": "Match (n:GPO) RETURN n" }, { "name": "View all groups that contain the word 'admin'", "query": "Match (n:Group) WHERE n.name CONTAINS 'ADMIN' RETURN n" } ] This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,75 @@ apiVersion: apps/v1 kind: Deployment metadata: name: bloodhound spec: replicas: 1 selector: matchLabels: app: bloodhound template: metadata: labels: app: bloodhound spec: containers: - name: graph-db image: docker.io/library/neo4j:4.4 resources: {} env: - name: NEO4J_AUTH valueFrom: configMapKeyRef: name: bloodhound-config key: NEO4J_AUTH - name: NEO4J_dbms_allow_upgrade value: "true" - name: app-db ports: - containerPort: 5432 image: docker.io/library/postgres:13.2 imagePullPolicy: Always resources: {} env: - name: POSTGRES_USER valueFrom: configMapKeyRef: name: bloodhound-config key: POSTGRES_USER - name: POSTGRES_PASSWORD valueFrom: configMapKeyRef: name: bloodhound-config key: POSTGRES_PASSWORD - name: POSTGRES_DATABASE value: bloodhound - name: bloodhound image: docker.io/specterops/bloodhound imagePullPolicy: Always resources: {} ports: - containerPort: 8080 env: - name: bhe_disable_cypher_qc value: "false" envFrom: - configMapRef: name: bloodhound-config volumes: - name: bloodhound-config configMap: name: bloodhound-config --- apiVersion: v1 kind: Service metadata: name: bloodhound-svc spec: selector: app: bloodhound ports: - protocol: TCP port: 8080 targetPort: 8080 type: ClusterIP This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,16 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: bloodhound-ingress spec: rules: - host: bloodhound.local http: paths: - pathType: Prefix path: / backend: service: name: bloodhound-svc port: number: 8080