Skip to content

Instantly share code, notes, and snippets.

@Esonhugh
Last active April 28, 2025 15:30
Show Gist options
  • Select an option

  • Save Esonhugh/00f2f2fbcd4dcfca56661d5d60a3b147 to your computer and use it in GitHub Desktop.

Select an option

Save Esonhugh/00f2f2fbcd4dcfca56661d5d60a3b147 to your computer and use it in GitHub Desktop.

Revisions

  1. Esonhugh revised this gist Apr 28, 2025. No changes.
  2. Esonhugh revised this gist Apr 28, 2025. 1 changed file with 1 addition and 83 deletions.
    84 changes: 1 addition & 83 deletions README.md
    Original 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

    ```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:

    ```
    Use official docker-compose.yml
  3. Esonhugh revised this gist Apr 28, 2025. 1 changed file with 8 additions and 0 deletions.
    8 changes: 8 additions & 0 deletions configmap.yaml
    Original 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'


  4. Esonhugh revised this gist Jun 14, 2024. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # Bloodhound as a service (Kubernetes Deployments)
    # Bloodhound as a service (Kubernetes Deployments/Docker Compose)

    ### Usage

  5. Esonhugh revised this gist Jun 14, 2024. 1 changed file with 88 additions and 2 deletions.
    90 changes: 88 additions & 2 deletions README.md
    Original 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 ingress.yaml configmap.yaml # -n <change namespace you deploy> `
    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`
    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:

    ```
  6. Esonhugh revised this gist Jun 14, 2024. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions README.md
    Original 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

  7. Esonhugh revised this gist Jun 14, 2024. 2 changed files with 23 additions and 0 deletions.
    6 changes: 6 additions & 0 deletions README.md
    Original 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`
    17 changes: 17 additions & 0 deletions deployment-service.yaml
    Original 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
  8. Esonhugh created this gist Jun 14, 2024.
    13 changes: 13 additions & 0 deletions README.md
    Original 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
    16 changes: 16 additions & 0 deletions configmap.yaml
    Original 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"

    190 changes: 190 additions & 0 deletions custom-queries.json
    Original 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"
    }
    ]
    75 changes: 75 additions & 0 deletions deployment-service.yaml
    Original 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
    16 changes: 16 additions & 0 deletions ingress.yaml
    Original 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