Add targeted Kerberoasting by injecting/removing temporary SPNs#840
Add targeted Kerberoasting by injecting/removing temporary SPNs#840NeffIsBack merged 19 commits intoPennyw0rth:mainfrom
Conversation
|
In the description I said that “Kerberos authentication with ldap3 is problematic because it relies on native GSSAPI libraries (libkrb5, etc.).” The new helper introduced in add ldap3 Kerberos authentication function performs a pure-Python SASL/GSS-SPNEGO bind through ldap3; it does not depend on any system libraries or extra packages. Once that PR is merged, this PR:
Below are two quick screenshots that prove the point: AES 128 :
KCACHE :
|
db68443 to
7df50ab
Compare
|
I refactored the code and replaced
|
|
Do we really want to modify&request STs for every person on the domain by default? That would result in hundreds or thousands of modification and TGT/ST requests in large domain. Should we perhaps limit this to some requested users that were specified? Thoughts everyone? |
Fair point, doing this for every user by default would be too noisy in large domains. One thing to consider : verifying the right to add SPNs before trying would introduce another problem. Sometimes we can't read the ntsecuritydescriptor (e.g. ACLs) but we can still modify the attribute. In those cases, a pre-check would incorrectly skip accounts we could actually modify, so we'd miss some valid targets. We could also make this option only work when one or more users are explicitly specified, idk what do you think ? |
Yeah I think for this the operator should have to explicitly list which user(s) to edit since this is actually making the environment less secure. |
We don't do a pre-check at the moment, or do we? I think we should just try to add it because of exactly these issues and as far as I can tell that's also the way it is implemented.
Yeah that sounds good. The question would be how to properly specify them. Maybe something similar to the asreproast/kerberoast combination?
Agreed, but one small detail: The SPN is removed afterwards, so there is nothing that gets more insecure. |
Well, assuming it gets removed correctly :P |
No, we don’t do a pre-check right now, we look for users without SPNs and try to add one to them without checking if we actually have the rights to do so, which is what targetedKerberoast does and what I based this on. On a large domain this can indeed be an issue, but adding a rights-check before adding SPNs also multiplies the LDAP queries and can lead to false negatives. The middle ground would be to avoid trying on every user in the domain and only target the users provided, and still skip the rights check and just try to add the SPN directly |
Exactly, I think we could just do something like |
Mixing the purpose of args is not a good idea. This will likely lead to a problem in the logic and is unintuitive. We should probably do it like the |
You’re right, I hadn’t thought of that, but it actually sounds like the best approach |
|
I've made the suggested changes @NeffIsBack, let me know if it looks good to you.
|
NeffIsBack
left a comment
There was a problem hiding this comment.
Fyi, I extracted the logic for the no-preauth roasting as this does not have anything to do with the rest of the kerberoasting logic.
Please integrate targeted kerberoasting into the existing kerberoasting logic, so that we don't have so much duplicate code. Meaning, similar to the kerberoast_account logic we should build a different filter, only retrieving the specified users. Then, before we actually get the ST we have to check if we need to modify the SPNs (is the arg set) and then add/remove the SPNs accordingly.
Pretty much, we shouldn't have all of the kerberoast logic 2x in the code.
NeffIsBack
left a comment
There was a problem hiding this comment.
A few small things left to do.






Description
The attack is possible when the authenticated user has GenericAll, GenericWrite, WriteProperty, or Validated-SPN rights over a target account.
By adding a temporary SPN (ServicePrincipalName) to such a user, the account becomes Kerberoastable. The function requests a ST for the injected SPN, extracts the hash, and immediately removes the SPN afterward to reduce detection.
Type of change
Insert an "x" inside the brackets for relevant items (do not delete options)
Setup guide for the review
Notes:
The current implementation uses a direct ldap3 bind for modifying SPNs. This only works when using NTLM authentication with username and password.
Kerberos authentication with ldap3 is problematic, as it relies on GSSAPI, which in turn depends on native system libraries like libkrb5 and gssapi bindings. This limits cross-platform compatibility, particularly in containerized or constrained environments.
To test the feature, use an account with permissions over user objects (e.g., Account Operators group). No additional GPO or registry changes are required.
Limitation:
To fully support all authentication methods (NT hash, AES key, kerberos ccache), the current workaround is to use NTLM (username + password). Integrating broader support would require implementing full LDAP authentication logic using Impacket, as ldap3 does not natively support these methods without relying on GSSAPI.
Screenshots (if appropriate):
The screenshot below demonstrates a successful targeted Kerberoasting attack. It shows:
Checklist:
Insert an "x" inside the brackets for completed and relevant items (do not delete options)
poetry run python -m ruff check . --preview, use--fixto automatically fix what it can)tests/e2e_commands.txtfile if necessary (new modules or features are required to be added to the e2e tests)