Skip to content

Add Kerberos authentication and improve usability#2

Merged
ThePirateWhoSmellsOfSunflowers merged 7 commits into
AlmondOffSec:mainfrom
Goultarde:add-kerberos-auth
May 14, 2026
Merged

Add Kerberos authentication and improve usability#2
ThePirateWhoSmellsOfSunflowers merged 7 commits into
AlmondOffSec:mainfrom
Goultarde:add-kerberos-auth

Conversation

@Goultarde
Copy link
Copy Markdown
Contributor

@Goultarde Goultarde commented May 7, 2026

I was investigating DC behavior in a trust relationship and ran into this tool, but it didn't work in my environment because Kerberos was not supported. This PR adds that support.

Summary

  • Add impacket-style Kerberos auth flags: -k, -no-pass, -aesKey, -dc-host. Switches the DCE-RPC bind to RPC_C_AUTHN_GSS_NEGOTIATE and uses KRB5CCNAME (with CLI fallback) for credentials.
  • When -dc-host is set, override the transport's remote name with the DC FQDN so the SPN is built correctly while keeping the IP for the TCP connection.
  • Replace the hardcoded Trust GUID not found! with the actual DCERPCSessionError code/message, so failures like ERROR_DS_DRA_ACCESS_DENIED or ERROR_DS_OBJ_NOT_FOUND are visible.
  • Auto-detect GUIDs passed in raw-byte format (e.g. from nxc --query objectGUID) and pre-swap them so they resolve to the correct binary GUID instead of double-swapping.

Test plan

  • -k with a TGT in KRB5CCNAME against a DC referenced by -dc-host <fqdn> and -t <ip> succeeds.
  • -k -aesKey <hex> (no ccache) succeeds.
  • Existing NTLM path (-p / --hashes) still works unchanged.
  • GUIDs from nxc --query and from PowerShell Get-ADObject both work.
  • Wrong DSA/TDO GUID prints the real DRS error instead of "Trust GUID not found!".

Introduce impacket-style flags to authenticate against the DRSUAPI
endpoint using Kerberos:

  -k / --kerberos       use Kerberos (ccache via KRB5CCNAME, then CLI creds)
  -no-pass / --no-pass  skip the password prompt (useful with -k)
  -aesKey               AES 128/256-bits key for Kerberos (implies -k)
  -dc-host              KDC hostname override

When -k is set, the DCE-RPC transport is configured with set_kerberos()
and the authentication type is switched to RPC_C_AUTHN_GSS_NEGOTIATE.
@ThePirateWhoSmellsOfSunflowers
Copy link
Copy Markdown
Contributor

Hello,

Thanks for the PR. One thing however: if the -dc-host is not set, the target is filled with the -t argument, not the domain part -d.

🌻

Goultarde added 4 commits May 10, 2026 21:32
hept_map set the transport's remote name to the -t value (an IP), so
the KDC was asked for an ST for host/<ip>@<REALM> and refused with
KDC_ERR_S_PRINCIPAL_UNKNOWN. Override the remote name with the DC
FQDN from -dc-host while keeping the IP for the TCP connection.
The script previously printed "Trust GUID not found!" for any
DCERPCSessionError raised by DRSGetNCChanges, masking the real cause
(e.g. ERROR_DS_DRA_ACCESS_DENIED, ERROR_DS_OBJ_NOT_FOUND on a wrong
DSA GUID, etc.). Print the impacket exception directly so the
underlying NT/DRS code is visible, and list the common causes.
Tools that read objectGUID directly from LDAP (e.g. nxc --query) emit
the 16 raw bytes formatted as a dashed UUID without applying the
mixed-endian byte swap that ADUC / PowerShell / DSInternals show.
impacket.uuid.string_to_bin then re-swaps the first three groups,
producing wrong bytes and an ERROR_DS_OBJ_NOT_FOUND from the DC.

AD objectGUID values are UUID v4, so in the standard form the third
group always starts with '4'. Detect that and pre-swap the input when
it doesn't, so both formats resolve to the correct binary GUID.
@Goultarde Goultarde force-pushed the add-kerberos-auth branch from 785f006 to 593d039 Compare May 10, 2026 20:07
@Goultarde
Copy link
Copy Markdown
Contributor Author

Hi,

Thanks for the catch. You are right, the help didn't match the actual behavior. I updated the -dc-host help and clarified -t so it documents that a FQDN is accepted as well (and amended a TGS reference from a previous commit to ST instead 🫣.)

@ThePirateWhoSmellsOfSunflowers
Copy link
Copy Markdown
Contributor

Hello,

The normalize_ad_guid is bugged: on my lab nxc retrieves this guid 12edfce5-bfea-444e-9edc-1af6675165eb and the "correct" one is e5fced12-eabf-4e44-9edc-1af6675165eb, however 12edfce5-bfea-444e-9edc-1af6675165eb is not swapped because 444e starts with a 4.

🌻

The "third group starts with 4" heuristic misses raw GUIDs whose
standard form is '4Y4W' (1/16 cases). Retry DRSGetNCChanges with
swapped GUIDs on failure, and add -r/--raw to skip the heuristic.
@Goultarde
Copy link
Copy Markdown
Contributor Author

Hi, yeah so we can't "cleanly" automate this, so I did both:

  • Retry with swap on failure
  • Check both GUIDs instead of one to reduce the chance of misinterpretation

Or you can just use -r/--raw to specify that it has to be swapped.

@ThePirateWhoSmellsOfSunflowers
Copy link
Copy Markdown
Contributor

Mhhh. Well, I'm not entirely satisfied with the solution, I think I prefer keeping the tool simple: the GUID must be provided in the "human readable" format (aka not the one returned by nxc, sorry). Can you please remove the normalize logic from your PR, I will merge it after that.

Anyway, thanks for your contribution 👍

🌻

@Goultarde
Copy link
Copy Markdown
Contributor Author

No problem, I understand!
I'll just keep the logic in my repo.

@ThePirateWhoSmellsOfSunflowers ThePirateWhoSmellsOfSunflowers merged commit 9e9c4a1 into AlmondOffSec:main May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants