CravateRouge/bloodyAD

"TypeError: 'NoneType' object is not subscriptable"

Closed this issue · 4 comments

Hi. Thank you for your work! This tool can hopefully fill the void after ACLPwn. I would very much like to try the tool but currently using pathgen.py fails with "TypeError: 'NoneType' object is not subscriptable".

I am using the standard installation of Bloodhound in Kali (which also includs Neo4j 4.2.1) and they are both running during testing of your tool. AD data is imported. I have also installed all the other requirements your tool requires. When executing the command "python3 pathgen.py -du neo4j -dp [password] -ds 'BIR-ADFS-GMSA$@search.htb' -dt 'tristan.davies@search.htb' I get the below stacktrace:

Traceback (most recent call last):
File "/root/pentest/bloodyAD/pathgen.py", line 30, in
main()
File "/root/pentest/bloodyAD/pathgen.py", line 18, in main
path = db.getPrivescPath(args.dbsource, args.dbtarget)
File "/root/pentest/bloodyAD/autobloody/database.py", line 11, in getPrivescPath
relationships = session.read_transaction(self._findShortestPath, source, target)
File "/root/pentest/virtual_env_bloodyad/lib/python3.9/site-packages/neo4j/work/simple.py", line 396, in read_transaction
return self._run_transaction(READ_ACCESS, transaction_function, *args, **kwargs)
File "/root/pentest/virtual_env_bloodyad/lib/python3.9/site-packages/neo4j/work/simple.py", line 325, in _run_transaction
result = transaction_function(tx, *args, **kwargs)
File "/root/pentest/bloodyAD/autobloody/database.py", line 64, in _findShortestPath
return result.single()[0].relationships
TypeError: 'NoneType' object is not subscriptable

Is there something I do wrong or does the code need updating?

Based on the stacktrace, the issue is that Neo4j doesn't find an exploitable path between BIR-ADFS-GMSA$@search.htb and tristan.davies@search.htb. So I see two potential hypothesis:

  • Least likely, there is not exploitable path between those two objects. You can easily verify in bloodhound/neo4j if there is a set of edges (automatically exploitable) between those two;
  • More likely, you gave the sAMAccountName instead of the node name of the object. The node name (also called label in neo4j) is the name that you can find in the extra properties of the object in the bloodhound interface. For example if BIR-ADFS-GMSA$ is the SAMAccountName of a computer, the node name is most likely BIR-ADFS-GMSA.search.htb.

I have been testing this some more after your reply. I tried using the names "BIR-ADFS-GMSA", "BIR-ADFS-GMSA@search.htb" and "BIR-ADFS-GMSA.search.htb". All of them give me the same error as earlier. This is interesting since if I use the name "BIR-ADFS-GMSA" instead of "BIR-ADFS-GMSA$" when exploiting this manually using your bloodyAD.py it fails. If I use "BIR-ADFS-GMSA$" it works.

manual

Above I used the exploitable path shown in Bloodhound below. "BIR-ADFS-GMSA/BIR-ADFS-GMSA$" has GenericAll rights on "tristan.davies".

bloodhound

You write that some paths cannot be exploited automatically. Is this one of them? A related question, would your tools be able to read the NT hash of the Group Managed Service Account "BIR-ADFS-GMSA$" if given the credentials of "sierra.frye" and then for example reset the password of "tristan.davies" as a part of automatic exploitation?

Neo4j is case sensitive so maybe try this:
python3 pathgen.py -du neo4j -dp [password] -ds 'BIR-ADFS-GMSA@SEARCH.HTB' -dt 'TRISTAN.DAVIES@SEARCH.HTB'

When using pathgen the parameters -ds and -dt use the Neo4j label because it queries the neo4j database. When using -u in bloody.py or autobloody.py you give the account name for NTLM authentication so the SAMAccountName and in your case it seems to be BIR-ADFS-GMSA$. I understand the confusion and I should maybe put emphasis on this in the README.

No you're right, this path can be exploited automatically using changePassword but the ReadGMSAPassword is not implemented yet but it could be interesting to add it.

That was it. I used the wrong case. Yes, this is a bit confusing although I understand the reasons for it. Take the following chained command for example:

"python pathgen.py -du neo4j -dp [password] -ds 'BIR-ADFS-GMSA@SEARCH.HTB' -dt 'TRISTAN.DAVIES@SEARCH.HTB' && python autobloody.py -d search.htb -u 'BIR-ADFS-GMSA$' -p 'e1e9fd9e46d0d747e1595167eedcec0f:e1e9fd9e46d0d747e1595167eedcec0f' --host 10.10.11.129"

Some input must be in upper case, some not. Pathgen.py uses the name in Bloodhound while autobloody .py uses the SAMAccountName (which still have to be inputted in upper case for some reason).

Yes it would be great to be able to read the NT hashes of GMSA accounts. I used the tool gMSADumper (https://github.com/micahvandeusen/gMSADumper) for that.

Thanks for your help! I look forward to using your tool in the future!