kerberos, dcerpc: tunnel KDC traffic through pkg/transport#26
Merged
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
f2b1d59 to
efcc4f9
Compare
The embedded gokrb5/v8 library hard-coded net.DialTimeout for AS/TGS
exchanges, bypassing -proxy and leaking the operator's source IP to the
KDC (UDP/88 first, TCP/88 fallback). The DCERPC Kerberos auth path used
a separate library (oiweiwei/gokrb5.fork/v9 via go-msrpc) that leaked the
same way.
Vendor jcmturner/gokrb5/v8 in-tree at pkg/third_party/gokrb5 with a
required KDCDialer first argument on every client constructor, so
proxy-bypass becomes a compile error. Wire kerberos.TransportKDCDialer
everywhere a gokrb5 client is built. Stamp udp_preference_limit=1 and
dns_lookup_kdc/realm=false unconditionally so KRB5 is TCP-only and the
OS resolver is never consulted; /etc/krb5.conf and $KRB5_CONFIG are
deliberately not read.
For DCERPC: set krbConfig.KDCDialer on every krb5.Config, pass
dcerpc.WithDialer(transport.ContextDialer{}) on every dcerpc.Dial, and
use the "ncacn_ip_tcp:" StringBinding prefix on the OXID-pivot dial so
go-msrpc's hard-coded pre-dial net.LookupIP is skipped (defers FQDN
resolution to the SOCKS5 proxy).
Verified against a live GOAD lab: 8 Kerberos-touching tools plus 5
NTLM/password/PtH regressions all operate through SOCKS5 with zero
direct packets to the AD subnet. Negative control (no -proxy)
immediately emits direct SYNs to the KDC, confirming both the leak
class and the fix.
efcc4f9 to
8eea029
Compare
This was referenced May 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
-proxybecause the embeddedjcmturner/gokrb5/v8used hard-codednet.DialTimeoutfor KDC I/O, bypassingpkg/transportentirely. DCSync (viaoiweiwei/go-msrpc/ssp/krb5) and the four DCOM tools leaked the same way through a second Kerberos library.jcmturner/gokrb5/v8in-tree atpkg/third_party/gokrb5with a requiredKDCDialerfirst argument on every client constructor — proxy-bypass is now a compile error.kerberos.TransportKDCDialer{}is the only production dialer;client.DirectDialer{}exists as an explicit escape hatch.krbConfig.KDCDialeron everykrb5.Config, passdcerpc.WithDialer(transport.ContextDialer{})on everydcerpc.Dial, and use the\"ncacn_ip_tcp:\"StringBinding prefix on the OXID-pivot dial to sidestep go-msrpc's hard-coded pre-dialnet.LookupIP(so FQDN resolution stays on the SOCKS5 proxy).udp_preference_limit=1anddns_lookup_kdc/realm=falsestamped unconditionally;/etc/krb5.confand$KRB5_CONFIGdeliberately not read.Test plan
End-to-end verified against a live GOAD lab with SOCKS5 over IAP-tunneled SSH:
getTGT(sevenkingdoms / north / essos)smbclient -k(all three DCs)GetUserSPNs -k(Kerberoast — exchanges TGS via proxy)GetNPUsers(AS-REP — directtransport.Dial)getST(S4U2self/S4U2proxy)secretsdump -kDCSync — extractedkrbtgtwmiexec -k—whoamireturnednorth\\administratorsmbexec -k— returnednt authority\\systemsmbclient,wmiexec,smbexec,secretsdump, PtHwmiexec -hashes— all cleannet 10.10.10.0/24 and not host 127.0.0.1): zero packets during the entire test matrixgetTGTwithout-proxy): immediately emits direct SYNs to KDC, confirming leak class is real and detectablego build ./...,go vet ./...,go test ./...all cleanConflict note
Branched from
main@4890b97; remote has since merged 9 PRs. Likely conflicts ongo.mod/go.sum(Azure/go-ntlmssp bump), possiblyKNOWN_ISSUES.md,pkg/registry/hive.go-adjacent docs, andpkg/dcerpc/drsuapi/*(out-of-scope for this PR but on the same merge path). Will rebase before merge.