Skip to content
This repository was archived by the owner on Dec 6, 2023. It is now read-only.

Commit 4069cb7

Browse files
committed
Add module - Set as owned in BloodHound
1 parent 1820cc1 commit 4069cb7

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

cme/modules/bh_owned.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Author:
2+
# Romain Bentz (pixis - @hackanddo)
3+
# Website:
4+
# https://beta.hackndo.com [FR]
5+
# https://en.hackndo.com [EN]
6+
7+
import json
8+
import sys
9+
10+
11+
class CMEModule:
12+
name = 'bh_owned'
13+
description = "Set pwned computer as owned in Bloodhound"
14+
supported_protocols = ['smb']
15+
opsec_safe = True
16+
multiple_hosts = True
17+
18+
def options(self, context, module_options):
19+
"""
20+
URI URI for Neo4j database (default: 127.0.0.1)
21+
PORT Listeninfg port for Neo4j database (default: 7687)
22+
USER Username for Neo4j database (default: 'neo4j')
23+
PASS Password for Neo4j database (default: 'neo4j')
24+
"""
25+
26+
self.neo4j_URI = "127.0.0.1"
27+
self.neo4j_Port = "7687"
28+
self.neo4j_user = "neo4j"
29+
self.neo4j_pass = "neo4j"
30+
31+
if module_options and 'URI' in module_options:
32+
self.neo4j_URI = module_options['URI']
33+
if module_options and 'PORT' in module_options:
34+
self.neo4j_Port = module_options['PORT']
35+
if module_options and 'USER' in module_options:
36+
self.neo4j_user = module_options['USER']
37+
if module_options and 'PASS' in module_options:
38+
self.neo4j_pass = module_options['PASS']
39+
40+
def on_admin_login(self, context, connection):
41+
try:
42+
from neo4j.v1 import GraphDatabase
43+
except:
44+
from neo4j import GraphDatabase
45+
46+
from neo4j.exceptions import AuthError, ServiceUnavailable
47+
48+
if context.local_auth:
49+
domain = connection.conn.getServerDNSDomainName()
50+
else:
51+
domain = connection.domain
52+
53+
54+
host_fqdn = (connection.hostname + "." + domain).upper()
55+
uri = "bolt://{}:{}".format(self.neo4j_URI, self.neo4j_Port)
56+
57+
try:
58+
driver = GraphDatabase.driver(uri, auth=(self.neo4j_user, self.neo4j_pass), encrypted=False)
59+
except AuthError as e:
60+
context.log.error(
61+
"Provided Neo4J credentials ({}:{}) are not valid. See --options".format(self.neo4j_user, self.neo4j_pass))
62+
sys.exit()
63+
except ServiceUnavailable as e:
64+
context.log.error("Neo4J does not seem to be available on {}. See --options".format(uri))
65+
sys.exit()
66+
except Exception as e:
67+
context.log.error("Unexpected error with Neo4J")
68+
context.log.debug("Error : ".format(str(e)))
69+
sys.exit()
70+
71+
with driver.session() as session:
72+
with session.begin_transaction() as tx:
73+
result = tx.run(
74+
"MATCH (c:Computer {{name:\"{}\"}}) SET c.owned=True RETURN c.name AS name".format(host_fqdn))
75+
if len(result.value()) > 0:
76+
context.log.success("Node {} successfully set as owned in BloodHound".format(host_fqdn))
77+
else:
78+
context.log.error(
79+
"Node {} does not appear to be in Neo4J database. Have you imported correct data?".format(host_fqdn))
80+
driver.close()

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ ldapdomaindump==0.9.2
2121
lsassy==2.1.2
2222
markupsafe==1.1.1
2323
msgpack==1.0.0
24+
neo4j==1.7.6
2425
ntlm-auth==1.4.0
2526
paramiko==2.7.1
2627
pyasn1==0.4.8

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
'lsassy',
2828
'termcolor',
2929
'msgpack',
30+
'neo4j',
3031
'pylnk3',
3132
'pypsrp',
3233
'paramiko',

0 commit comments

Comments
 (0)