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 ()
0 commit comments