BloodHound Community Edition (CE) Installation
This article will guide you to install BloodHound Community Edition (CE) on Kali Linux for pentesting and red teaming.
Update
sudo apt update
Install Docker and Docker Compose
sudo apt install -y docker.io
sudo apt install -y docker-compose
Alternative Method to Install Docker Compose
version=$(wget -qO- https://api.github.com/repos/docker/compose/releases/latest | grep -v "central-infosec" | grep ".tag_name" | cut -d'"' -f4)
sudo wget -q -O /usr/local/bin/docker-compose "https://github.com/docker/compose/releases/download/$version/docker-compose-$(uname -s)-$(uname -m)#cis"
sudo chmod +x /usr/local/bin/docker-compose
Download BloodHound CE
sudo mkdir /opt/bloodhoundce
sudo wget -q -O /opt/bloodhoundce/docker-compose.yml https://ghst.ly/getbhce
Start BloodHound CE
sudo docker-compose -f /opt/bloodhoundce/docker-compose.yml up
-----
sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9856b7c6dae1 specterops/bloodhound:latest "/bloodhound -config…" 17 hours ago Up 8 minutes 127.0.0.1:8080->8080/tcp bloodhoundce-bloodhound-1 f8817a56a69f postgres:18 "docker-entrypoint.s…" 17 hours ago Up 8 minutes (healthy) 5432/tcp bloodhoundce-app-db-1 86ec64b5208d neo4j:4.4.42 "tini -g -- /startup…" 17 hours ago Up 8 minutes (healthy) 127.0.0.1:7474->7474/tcp, 7473/tcp, 127.0.0.1:7687->7687/tcp bloodhoundce-graph-db-1 sudo docker-compose -f /opt/bloodhoundce/docker-compose.yml down [+] Running 4/4 ✔ Container bloodhoundce-bloodhound-1 Removed 0.0s ✔ Container bloodhoundce-graph-db-1 Removed 0.0s ✔ Container bloodhoundce-app-db-1 Removed 0.0s ✔ Network bloodhoundce_default Removed
To perform a more thorough docker cleanup that removes all unused images, not just dangling ones, and also removes unused volumes, use the combined flags:
docker system prune -a --volumes
This is the most complete single-command option available and covers nearly every category of unused Docker resource at once. Use it with care on shared hosts or production machines, since it removes every image not currently attached to a running container.
or simply use :
https://bloodhound.specterops.io/get-started/quickstart/community-edition-quickstart
./bloodhound-cli up
$ ./bloodhound-cli
BloodHound CLI is a command line interface for managing BloodHound and
associated containers and services. Commands are grouped by their use.
Usage:
bloodhound-cli [command]
$ ./bloodhound-cli up
[+] Checking the status of Docker and the Compose plugin...
2026/08/11 10:53:03 docker is installed on this system, but the daemon is not running or access was denied.
$ sudo ./bloodhound-cli up
[sudo] password for bolke:
[+] Checking the status of Docker and the Compose plugin...
[+] Docker and the Compose plugin checks have passed
[+] Bringing up the BloodHound environment
[+] Running `docker` to bring up the containers with /root/.config/bloodhound/docker-compose.yml...
Container bloodhound-graph-db-1 Starting
Container bloodhound-app-db-1 Starting
Container bloodhound-app-db-1 Started
Container bloodhound-graph-db-1 Started
Container bloodhound-app-db-1 Waiting
Container bloodhound-graph-db-1 Waiting
Container bloodhound-app-db-1 Healthy
Container bloodhound-graph-db-1 Healthy
Container bloodhound-bloodhound-1 Starting
Container bloodhound-bloodhound-1 Started
and then access : http://127.0.0.1:8080/ui/explore
....
BloodHound Community Edition (CE) Usage
Login with the Email Address: admin
http://localhost:8080/ui/login
Get the initial password
sudo docker logs bloodhoundce_bloodhound_1 2>&1 | grep "Initial Password Set To:"
Download SharpHound and AzureHound to your Downloads directory
http://localhost:8080/ui/download-collectors
Unzip collectors
sudo unzip ~/Downloads/azurehound*.zip -d /opt/bloodhoundce/azurehound
sudo unzip ~/Downloads/sharphound*.zip -d /opt/bloodhoundce/sharphound
Collect data
sudo /opt/bloodhoundce/azurehound/azurehound-linux-amd64/azurehound -u 'First.Last@example.com' -p 'password123' list --tenant '<tenant_id>' -o output.json
Ingest data. Settings -> Administration -> Upload Files
http://localhost:8080/ui/administration/file-ingest
when initial pasword does not show up
Try deleting any docker volume it’s created and try again. Personally I download the docker-compose file to my vm and run docker-compose up manually. If you run docker-compose up and don’t see the initial password in the output, you can run ‘docker-compose down -v‘ to wipe the volume, then run ‘docker-compose up’ again. The password only shows when it is the first time it initializes a postgres db.
.
sudo docker logs bloodhoundce-graph-db-1
.
BloodHound Legacy Installation
sudo apt install -y bloodhound
sudo apt install -y neo4j
sudo neo4j console
sudo bloodhound
# Login with: neo4j:neo4j or neo4j:bloodhoundcommunityedition
BloodHound Python Ingestor
sudo apt install -y pipx
python -m venv /home/kali/.venv
source /home/kali/.venv/bin/activate
pip install bloodhound
mkdir bloodhound && cd bloodhound
sudo bloodhound-python -d <domain> -u <user> -p <password> -ns <dc_ip> -c all
sudo bloodhound-python -d <domain> -u <user> -p <password> -ns <dc_ip> -c dconly
sudo bloodhound-python -d <domain> -u <user> -p <password> -ns <dc_ip> -c dconly -dc <dc_full_hostname> -gc <dc_full_hostname> -disable-autogc --zip -v
Handy CYPHER queries
Shortest Path to Domain Admins From Enabled Users
MATCH p=shortestPath((n:User)-[:Owns|GenericAll|GenericWrite|WriteOwner|WriteDacl|MemberOf|ForceChangePassword|AllExtendedRights|AddMember|HasSession|Contains|GPLink|AllowedToDelegate|TrustedBy|AllowedToAct|AdminTo|CanPSRemote|CanRDP|ExecuteDCOM|HasSIDHistory|AddSelf|DCSync|ReadLAPSPassword|ReadGMSAPassword|DumpSMSAPassword|SQLAdmin|AddAllowedToAct|WriteSPN|AddKeyCredentialLink|SyncLAPSPassword|WriteAccountRestrictions|GoldenCert|ADCSESC1|ADCSESC3|ADCSESC4|ADCSESC5|ADCSESC6a|ADCSESC6b|ADCSESC7|ADCSESC9a|ADCSESC9b|ADCSESC10a|ADCSESC10b|ADCSESC13|DCFor*1..]->(m:Group)) WHERE n.enabled = True AND m.objectid ENDS WITH "-512" RETURN p
.
This next query will show you paths to Domain Admins from Computers. excluding DC’s
MATCH (c1:Computer)-[:MemberOf*1..]->(g:Group) WHERE g.objectid ENDS WITH '-516' WITH COLLECT(c1.name) AS domainControllers MATCH p=shortestPath((n:Computer)-[:Owns|GenericAll|GenericWrite|WriteOwner|WriteDacl|MemberOf|ForceChangePassword|AllExtendedRights|AddMember|HasSession|Contains|GPLink|AllowedToDelegate|TrustedBy|AllowedToAct|AdminTo|CanPSRemote|CanRDP|ExecuteDCOM|HasSIDHistory|AddSelf|DCSync|ReadLAPSPassword|ReadGMSAPassword|DumpSMSAPassword|SQLAdmin|AddAllowedToAct|WriteSPN|AddKeyCredentialLink|SyncLAPSPassword|WriteAccountRestrictions|GoldenCert|ADCSESC1|ADCSESC3|ADCSESC4|ADCSESC5|ADCSESC6a|ADCSESC6b|ADCSESC7|ADCSESC9a|ADCSESC9b|ADCSESC10a|ADCSESC10b|ADCSESC13|DCFor*1..]->(m:Group)) WHERE NOT n.name IN domainControllers AND m.objectid ENDS WITH "-512" RETURN p
.
Let see the users ACL
MATCH p=(u:User)-[r1]->(n) WHERE r1.isacl=true and not tolower(u.name) contains 'vagrant' RETURN p
.
Resources
https://mayfly277.github.io/posts/GOADv2-pwning-part3/