feat(ldap): add ADCS collection support via CertiHound integration#1054
feat(ldap): add ADCS collection support via CertiHound integration#10540x0Trace wants to merge 11 commits intoPennyw0rth:mainfrom
Conversation
Add Active Directory Certificate Services (ADCS) enumeration to the BloodHound collection workflow using CertiHound library. Changes: - Add 'adcs' to valid collection methods in resolve_collection_methods() - Add CertiHound as optional dependency (pip install netexec[adcs]) - Implement _collect_adcs_for_bloodhound() for ADCS data collection - Update bloodhound() to handle ADCS-only and combined collections - Export ADCS data in BloodHound CE v6 format
|
Consider this PR has DUP with this module
|
Thanks for flagging this! I see how it might look like a duplicate at first glance, but they actually do different things: |
|
Good... my idea is, because now there are lots of It's a good idea? how do you think? If this works, then you can move |
|
Thanks for the PR. I agree with @XiaoliChan, there are a lot of ADCS modules now and we have to make sure that they don't do duplicate functionality. As far as I know certipy is also capable of outputting bloodhound data so we can just use that. |
|
@0x0Trace is certihound open source? Can't find the repo |
Hello! Yes it is open source you can find it here : https://pypi.org/project/certihound/ |
|
Thanks for the suggestions! I looked into this , the issue is that certipy's JSON output doesn't contain the data structures BloodHound CE needs (like node/edge relationships, proper GUIDs, etc.). CertiHound isn't just a format converter - it collects the data differently to build the graph relationships BloodHound CE expects. Also worth noting: certipy v5.x actually removed the -bloodhound flags entirely, so there's no BloodHound output in current certipy at all. |
Great, please provide the source code on git repository, we can take a look TGT ^_^ |
Of course i would appreciate it ! I just pushed it you can check it here : https://github.com/0x0Trace/Certihound |
Great job bro, BTW, Happy new year! |
Thank you ! Happy new year to you also :D |
|
@NeffIsBack the source code for the library is here : https://github.com/0x0Trace/Certihound .Happy new year! |
Thanks and happy new year. I will take a look at it 👍 |
|
@NeffIsBack thanks for noticing it !It is fixed now |
|
@NeffIsBack did you managed to take a look at it?Thanks again for your time |
Not fully, but I took a short peek. I am still torn between "it would be really cool to have ADCS collection" and "oh no, yet another dependency with sub dependencies that have to be managed". The problem is that there are already certipy and bloodhound which both would be a great fit for such functionality, without much initial and long term work required for it to be integrated. If we decide to integrate your tool (which is really cool btw!) this should not be an optional dependency, but a normal one. Meaning, your tool as well as all sub dependencies must be checked and uploaded into the kali repositories. That is one of the reasons I am hesitating a bit to give it the approval, besides the normal dependency management that gets harder and harder the more there are (e.g. upgrading to new python versions is often a pain). One question: what is the reason ldap3 is used as a baseline for the tool? Why not impacket? And I have seen you have build an adapter for impacket connections, does this mean impacket ldap is used at the end or is this just used to create the ldap3 connection for querying? |
|
Hey @NeffIsBack, thanks for taking the time to look into this , I really appreciate the feedback. Let me address the ldap3 vs impacket question directly: The ImpacketLDAPAdapter doesn't actually use impacket's LDAP client for queries - it's just a thin translation layer (~100 lines). Here's how it works:
Why ldap3 as the baseline? CertiHound needs to work standalone (CLI mode) without requiring the full impacket stack. But when integrated with NetExec, ldap3 is not needed at runtime - the adapter handles all the translation. This keeps it portable for other tools too. Regarding dependencies for Kali packaging - I checked and the actual new dependencies CertiHound would bring to NetExec are I've also set it up as an optional dependency ( Totally understand the hesitation around dependency management though - it's a real concern for maintainability. Happy to help with the Kali packaging process if this moves forward, or answer any other questions about the architecture. |
Actually sounds pretty cool. The reason i asked is my long long term goal would be to fully remove ldap3 from the project and solely rely on impackets ldap implementation. However, this will probably not happen for the next few years because there are so many projects using ldap3 instead of impackets ldap, so this additional dependency doesn't matter for now.
That is good2know and definitely makes things much easier. So i have talked a bit with the others and i think for now this (CertiHound) is the best and easiest way to collect ADCS data, thanks for your work! So please:
|
Move CertiHound from optional to default dependencies and remove conditional import handling since it will always be installed. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
Hey @NeffIsBack , thanks for the green light! Really appreciate you and the team giving this a shot. I've made the changes you requested:
Pretty minimal diff, just a few lines each. Let me know if you want me to adjust anything else or if there's anything I missed. |
NeffIsBack
left a comment
There was a problem hiding this comment.
Minor things that have to be adjusted.
On a general note, is there a way to generlize the idea of the impacket-ldap adapter? Is this possible? What would be needed to adapt this to other projects? I haven't looked into it how this could be adapted, but a good idea would be to somehow integrate it into bloodhound-python as well.
The reason i am asking: The problem is that currently ldap3 does not support signing without TLS certs, so in situation where ldap signing is required, but the DC does not have a TLS cert for LDAPS, the bh-python collector crashes. For the future it would be nice if we either add the adapter to bh-python (if easily possible) or convince/implement dirk-jan to switch to impackets ldap, so collection is still possible if we encounter this situation.
nxc/protocols/ldap/proto_args.py
Outdated
| bgroup = ldap_parser.add_argument_group("Bloodhound Scan", "Options to play with Bloodhoud") | ||
| bgroup.add_argument("--bloodhound", action="store_true", help="Perform a Bloodhound scan") | ||
| bgroup.add_argument("-c", "--collection", default="Default", help="Which information to collect. Supported: Group, LocalAdmin, Session, Trusts, Default, DCOnly, DCOM, RDP, PSRemote, LoggedOn, Container, ObjectProps, ACL, All. You can specify more than one by separating them with a comma") | ||
| bgroup.add_argument("-c", "--collection", default="Default", help="Which information to collect. Supported: Group, LocalAdmin, Session, Trusts, Default, DCOnly, DCOM, RDP, PSRemote, LoggedOn, Container, ObjectProps, ACL, ADCS, All. You can specify more than one by separating them with a comma. ADCS requires: pip install netexec[adcs]") |
There was a problem hiding this comment.
Please remove the installation prompt.
There was a problem hiding this comment.
Maybe we should even add some AllAll (please someone provide a good name haha) collection method that indeed includes every option (All+LoggedOn+ADCS).
There was a problem hiding this comment.
Just looked at the Sharphound and bh-python pages. Sharphound does indeed include ADCS+LoggedOn in the All collection method, while bh-python does not. How about we change the All collection method to also include both of these options, similar to Sharphound? Imo that's less confusing. @mpgn @Dfte (or others of course) thoughts?
There was a problem hiding this comment.
With that said, i would also opt for including ADCS collection in the default collection method, similar to Sharphound.
nxc/protocols/ldap.py
Outdated
| collect = resolve_collection_methods("Default" if not self.args.collection else self.args.collection) | ||
| if not collect: | ||
| return | ||
| self.logger.highlight("Resolved collection methods: " + ", ".join(list(collect))) |
There was a problem hiding this comment.
While we are at it, i think a great addition would be to also display which collection methods have not been included/selected. If you have the time feel free to add it, otherwise i can do it next month.
|
Thanks for the review @NeffIsBack and sorry if i was late to answer, i wanted to address first the issues. So the changes have been done are the follow as you suggested :
Regarding the impacket-ldap adapter generalization for bh-python great idea for the future for sure! The ImpacketLDAPAdapter in certihound is designed to be protocol-agnostic so it could potentially be adapted. |
NeffIsBack
left a comment
There was a problem hiding this comment.
Thanks for the review @NeffIsBack and sorry if i was late to answer, i wanted to address first the issues.
Lol you are blazingly fast compared to the usual response times, no worries, i will also need a bit to test it.
So the changes have been done are the follow as you suggested
Sounds good, a few minor things left.
Regarding the impacket-ldap adapter generalization for bh-python great idea for the future for sure! The ImpacketLDAPAdapter in certihound is designed to be protocol-agnostic so it could potentially be adapted.
Very interesting! Could be a cool thing to look at in the future.
|
@NeffIsBack all good, i made the changes.Tell me if you want anything else. |
Adds Active Directory Certificate Services (ADCS) enumeration to BloodHound collection, enabling security assessors to collect PKI-related attack paths alongside traditional AD data.
Key Features:
-c ADCScollection method for certificate template and CA enumerationMotivation
ADCS misconfigurations (ESC1-ESC8) are among the most prevalent and impactful Active Directory attack vectors. Currently, NetExec users must run separate tools to collect this data. This integration brings ADCS collection directly into the existing
--bloodhoundworkflow, producing a single unified zip file for BloodHound CE import.Changes
pyproject.tomlcertihoundas optional dependency (netexec[adcs])nxc/protocols/ldap/proto_args.pynxc/protocols/ldap.pyadcsto valid/all methods, implement_collect_adcs_for_bloodhound()Installation
Usage
Example Output
Screenshots
Terminal Output
ESC1 Vulnerability Detected
ESC4 Vulnerability Detected
BloodHound Output
The zip file includes standard BloodHound files plus ADCS data:
certtemplates.jsonenterprisecas.jsonrootcas.jsonntauthstores.jsonaiacas.jsonTest Plan
-c ADCS) works without bloodhound-python-c All) includes ADCS data-c Group,ADCS) work correctlyNotes
Related
Checklist: