bloodhound-import icon indicating copy to clipboard operation
bloodhound-import copied to clipboard

Bloodhound 4.1 compatibility

Open WilliamBruneau opened this issue 2 years ago • 2 comments

WilliamBruneau avatar Feb 17 '22 08:02 WilliamBruneau

Successfully tested with data collected with the last version of bloodhound.py. Not tested with data collected with SharpHound.

WilliamBruneau avatar Feb 17 '22 09:02 WilliamBruneau

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:

  1. There is a typo on Line 179 of importer.py, it should be singular (session_type)

  2. 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 the build_add_edge_query function on Line 22, it defaults to objectid 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))
    

chvancooten avatar Oct 03 '22 15:10 chvancooten

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.

chvancooten avatar Nov 17 '22 20:11 chvancooten

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 load_entry_point('bloodhound-import==0.0.9', 'console_scripts', 'bloodhound-import')()

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.

y4yan avatar Nov 17 '22 20:11 y4yan

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 avatar Jan 25 '23 13:01 wowter-code

@wowter-code Try calling it as a module: python -m bloodhound_import

chvancooten avatar Jan 25 '23 14:01 chvancooten

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__```

wowter-code avatar Jan 25 '23 14:01 wowter-code

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 :)

chvancooten avatar Feb 03 '23 12:02 chvancooten