:::tip
Lately I've found that using [bloodhoundcli](pentesting/internal/bloodhoundcli) is really easy to use.  But below I've included some instructions to manually get BloodHound Community up and running.
:::

# BloodHound Community

## Install BloodHound Community edition
Reference the [custom install](https://bloodhound.specterops.io/get-started/custom-installation) for more information.

```
# Download BloodHound
git clone https://github.com/SpecterOps/BloodHound

# Make a BH directory
mkdir bhce
cd bhce

# Download config files
curl -L -O https://raw.githubusercontent.com/SpecterOps/BloodHound/refs/heads/main/examples/docker-compose/docker-compose.yml
curl -L -O https://raw.githubusercontent.com/SpecterOps/BloodHound/refs/heads/main/examples/docker-compose/bloodhound.config.json
```

In `docker-compose.yml`, look for:

```
 - bhe_graph_driver=${GRAPH_DRIVER:-neo4j}
```

Change `neo4j` to `pg`.

Then startup with:
```
sudo docker-compose up
```

If you need to do maintenance, shut stuff down with:
```
sudo docker-compose down
```

If for some reason you don't get an admin account generated when Docker fires up, take the instance down, and then edit `docker-compose.yml` and adjust this line so that `recreate_default_admin=-true`:

```
  - bhe_recreate_default_admin=${bhe_recreate_default_admin:-false}
```

## Parse list of machine names from a cypher query
This used to work on the old (non-Community) edition when you needed to grep a list of endpoints affected by a specific query to create a nice, clean list of machines (one per line).  I need to test against Community:

```
grep -o '"label":"[^"]*"' machine-names.json | cut -d':' -f2 | tr -d '"' | uniq | sort -V
```
Or it might be this one:
```
cat comps.json | jq '.data[].Properties.name' | sed 's/"//g' | sort -f > allmachines.txt
```

## This script pulls computer names and dates and converts from Unix timestamp with newest date at the top
```
jq -r '.data | sort_by(.Properties.whencreated) | reverse[] | "\(.Properties.name) \(.Properties.whencreated | todate)"' 20240918113133_computers.json
```

## Get a list of all users that have a non-empty description (h/t BusyR)
```
cat *_users.json | jq -r ' .data[].Properties | select ( .enabled == true) | select (.description != null) .name + ":" + .description' | tee users_with_description.txt
```

## Create a txt file with all enabled users (h/t BusyR)
```
cat *_users.json | jq -r ' .data[].Properties | select ( .enabled == true) | .samaccountname' | tee users.txt
```

## Reset BloodHound password
See [this BloodHound Slack](https://bloodhoundhq.slack.com/archives/C20NG2L87/p1718833277532419) advice.  You could also go "nuclear" with the next section:

## Delete all BloodHound containers and images and start over
Sometimes my BloodHound doesn't seem to start smoothly and/or hangs weirdly so I do the following when my body is filled with rage:

:::danger
I'm ok with this "nuclear" option because my BH VM has nothing but BH on it.  So uhh...maybe don't run this stuff if you have docker-y things on your system you care about.

```
docker rm desktop_app-db_1
docker rm desktop_bloodhound_1
docker rm desktop_graph-db_1
docker rmi neo4j:4.4
docker rmi postgres:16
docker rmi specterops/bloodhound
docker system prune --volumes --force
```
:::

## Admin session enumeration explained
Sometimes I get confused about how local admin sessions are enumerated.  A fine friend from the [BloodHound Slack](https://bloodhoundhq.slack.com/archives/C02JG9SE3FX/p1758573134642609) clarified:

*Assuming you collected with SharpHound collection method All, SharpHound will attempt to collect local groups directly from the hosts in scope. That requires admin rights by default however. It will fallback to creating AdminTo edges based on GPO settings. I believe there is an edge property that reveals if the edge is based on GPO. These edges may be false positives as BloodHound does not take GPO filtering into account, for example*

## Queries
The [BloodHound Query Library](https://queries.specterops.io/) is *the* place to go for good BH queries, but here's a few I like.

### Find all computers without SMB signing
```
MATCH (n:Computer)
WHERE n.smbsigning = False
RETURN n
```

### Find computers with WebClient
```
MATCH (c:Computer)
WHERE c.webclientrunning = True
RETURN c LIMIT 1000
```

### Find computers with WebClient AND with live sessions
```
match p=(U:User)<-[:HasSession]-(C:Computer)
where C.webclientrunning = True
return p limit 1000
```
