bloodhound-import
bloodhound-import copied to clipboard
Bloodhound 4.1 compatibility
Successfully tested with data collected with the last version of bloodhound.py. Not tested with data collected with SharpHound.
Hey @WilliamBruneau, thanks for this great PR! With some modifications I'm using it in a project to programmatically ingest BloodHound 4.2 (non-Azure) data and it works really well.
I didn't want to open a PR on a PR, but I did want to share my fixes:
-
There is a typo on Line 179 of
importer.py
, it should be singular (session_type
) -
I encountered an issue where the ACL target for Computer-originated ACLs was not an object, but just a string with the target object identifier. Other ACLs did have a full object as a reference. As a workaround, I implemented the following fix:
- I added a new
type
parameter to thebuild_add_edge_query
function on Line 22, it defaults toobjectid
so it is not breaking to existing function calls:
def build_add_edge_query(source_label: str, target_label: str, edge_type: str, edge_props: str, type: str = "objectid") -> str: """Build a standard edge insert query based on the given params""" insert_query = 'UNWIND $props AS prop MERGE (n:Base {{{0}: prop.source}}) ON MATCH SET n:{1} ON CREATE SET n:{1} MERGE (m:Base {{objectid: prop.target}}) ON MATCH SET m:{2} ON CREATE SET m:{2} MERGE (n)-[r:{3} {4}]->(m)' return insert_query.format(type, source_label, target_label, edge_type, edge_props)
- I then added a check in the loop on Line 167 to split branches based on the type of destination object. If the target is just specified with a string, it constructs a generic ACL using the newly added argument from the above point:
for target in targets: if isinstance(target, str): query = build_add_edge_query('Base', 'Computer', edge_name, '{isacl:false, fromgpo: false}', "name") tx.run(query, props=dict(source=target, target=identifier)) else: query = build_add_edge_query(target['ObjectType'], 'Computer', edge_name, '{isacl:false, fromgpo: false}') tx.run(query, props=dict(source=target['ObjectIdentifier'], target=identifier))
- I added a new
Hey @y4yan, I believe that error is caused by the typo mentioned in my previous comment under point 1. Perhaps fixing that typo solves your problem as well.
Hey @y4yan, I believe that error is caused by the typo mentioned in my previous comment under point 1. Perhaps fixing that typo solves your problem as well.
Hey @chvancooten thanks for your fix ! but I have an other one now :/
sudo bloodhound-import -du neo4j -dp neo4j --database 127.0.0.1 -p 7687 /tmp/json/20221117141902_computers.json
` /tmp/json/20221117141902_computers.json [INFO] 2022-11-17 21:33:08,301 - Parsing 1 files [INFO] 2022-11-17 21:33:08,301 - Parsing bloodhound file: /tmp/json/20221117141902_computers.json [INFO] 2022-11-17 21:33:08,445 - Parsed 63 out of 637 records in /tmp/json/20221117141902_computers.json. [INFO] 2022-11-17 21:33:08,573 - Parsed 126 out of 637 records in /tmp/json/20221117141902_computers.json. [INFO] 2022-11-17 21:33:08,704 - Parsed 189 out of 637 records in /tmp/json/20221117141902_computers.json.
/usr/lib/python3/dist-packages/requests/init.py:89: RequestsDependencyWarning: urllib3 (1.26.10) or chardet (5.0.0) doesn't match a supported version! warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported "
Traceback (most recent call last):
File "/usr/local/bin/bloodhound-import", line 11, in
File "/usr/local/lib/python3.8/dist-packages/bloodhound_import-0.0.9-py3.8.egg/bloodhound_import/init.py", line 46, in main
File "/usr/local/lib/python3.8/dist-packages/bloodhound_import-0.0.9-py3.8.egg/bloodhound_import/importer.py", line 363, in parse_file
File "/usr/local/lib/python3.8/dist-packages/neo4j/_sync/work/session.py", line 437, in write_transaction return self._run_transaction(
File "/usr/local/lib/python3.8/dist-packages/neo4j/_sync/work/session.py", line 333, in _run_transaction result = transaction_function(tx, *args, **kwargs)
File "/usr/local/lib/python3.8/dist-packages/bloodhound_import-0.0.9-py3.8.egg/bloodhound_import/importer.py", line 186, in parse_computer KeyError: 'UserId'`
EDIT: It seems that I have a workaround by replacing UserId by UserSID.
Hello guys!
After modifying the files as mentioned above, I have a similar issue with @y4yan :
File "/usr/local/bin/bloodhound-import", line 33, in <module>
sys.exit(load_entry_point('bloodhound-import==0.0.9', 'console_scripts', 'bloodhound-import')())
File "/usr/local/bin/bloodhound-import", line 25, in importlib_load_entry_point
return next(matches).load()
File "/usr/lib/python3.10/importlib/metadata/__init__.py", line 173, in load
return functools.reduce(getattr, attrs, module)
AttributeError: module 'bloodhound_import' has no attribute '__main__'. Did you mean: '__name__'?
@wowter-code Try calling it as a module: python -m bloodhound_import
I tried with python -m bloodhound_import, but without success:
Traceback (most recent call last):
File "/usr/lib/python3.10/runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
exec(code, run_globals)
File "/home/kali/Desktop/bloodhound-import/bloodhound_import/__main__.py", line 4, in <module>
asyncio.run(main())
File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
return future.result()
File "/home/kali/Desktop/bloodhound-import/bloodhound_import/__init__.py", line 47, in main
await parse_file(filename, driver)
File "/home/kali/Desktop/bloodhound-import/bloodhound_import/importer.py", line 359, in parse_file
with driver.session() as session:
AttributeError: __enter__```
For me, everything works great with the latest master branch and the changes from PR https://github.com/fox-it/bloodhound-import/pull/37 now :)