fix(dns): resolve each address family separately when AF_UNSPEC fails - #1382
Draft
Marshall-Hallenbeck wants to merge 2 commits into
Draft
fix(dns): resolve each address family separately when AF_UNSPEC fails#1382Marshall-Hallenbeck wants to merge 2 commits into
Marshall-Hallenbeck wants to merge 2 commits into
Conversation
get_host_addr_info made a single AF_UNSPEC getaddrinfo call with no fallback, while the dnspython branch already queried A and AAAA separately. glibc fails an AF_UNSPEC lookup with EAI_AGAIN when one family's UDP answer is truncated, so a host that resolves fine per family was reported as unresolvable. That left kdcHost unset and broke kerberoasting and every other Kerberos operation against the domain. Retry each family on its own before giving up, keep the first address of each family to match the dnspython branch, and take canonname from the first record rather than the last loop iteration.
2536442 changed _is_signing_required from (self, conn, smbv1) to a method reading self.conn and self.smbv1, but the tests kept passing conn and smbv1 as arguments and failed with TypeError.
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.
Description
get_host_addr_info()resolved hostnames two different ways, and only one of them was resilient.The dnspython branch (used with
--dns-server/--dns-tcp) queries A and AAAA as two separate lookups, each in its owntry/except, so one family failing still yields a usable address. The system-resolver branch made a singleAF_UNSPECgetaddrinfo()call with notry/exceptand no per-family fallback.That asymmetry matters because glibc fails an
AF_UNSPEClookup outright withEAI_AGAINwhen one family's UDP answer is truncated, even when each family resolves fine on its own. Against a domain with many A and AAAA records:NetExec then treated the domain as unresolvable,
Connection.resolver()returnedNone, andldap.pyleftself.kdcHost = None. Every Kerberos operation broke, reporting the confusing:--dns-serverdoes not help, because impacket opens its Kerberos socket through the OS resolver, not through NetExec's dnspython resolver.This makes the system-resolver branch behave like the dnspython branch: try
AF_UNSPEC, and only if that yields nothing, retryAF_INETandAF_INET6separately. Two smaller issues in the same loop are fixed along the way — the first address of each family is now kept rather than the last (matchinganswers[0]in the dnspython branch), andcanonnameis taken from the first record rather than whatever the last loop iteration happened to hold, which could be empty and silently blanked a link-local IPv6 target.No new dependencies. No linked issue; this was found in the field rather than reported.
Second commit, unrelated to the DNS fix:
tests/test_smb_signing.pycurrently fails onmainwith 5 ×TypeError: _is_signing_required() got an unexpected keyword argument 'smbv1'. 2536442 changed_is_signing_requiredfrom(self, conn, smbv1)to a method readingself.conn/self.smbv1, but the tests were not updated. Included so this branch's suite is green; happy to split it out if you'd rather take it separately.tests/e2e_commands.txtis unchanged — this fixes existing resolution behaviour and adds no module or flag.AI disclosure: Claude Code (Opus 5). The diagnosis, the patch, the unit tests, and the first draft of this description were produced by the model, working from a live failure I hit during an engagement. I directed the work, reviewed the diff, and verified the fix by hand against a real DC (see the setup section below). Stating the extent plainly rather than understating it, per the project AI policy.
Type of change
Setup guide for the review
Tested on Kali Linux 6.12.25-amd64, Python 3.12, against a live Windows Server 2022 (Build 20348) DC in a large AD forest.
Reproducing the bug. You need a domain whose apex has enough A + AAAA records that the combined answer exceeds the 512-byte non-EDNS UDP limit, and a resolver config without
options edns0. The forest I hit this on publishes 21 A and 25 AAAA records for the domain name (AAAA answer = 764 bytes).AF_UNSPECto fail while each family succeeds:main, run any Kerberos operation without--kdcHost:Before the fix it ends with
DEBUG TGT: NoneandError retrieving TGT for <domain>\<user> from None. After the fix the same command resolves the KDC and roasts normally.If you cannot reproduce the DNS conditions,
tests/test_dns_resolution.pysimulates them with a stubbedgetaddrinfo; 6 of its 8 tests fail onmainand all 8 pass with this change.Screenshots (if appropriate)
Before, on
main(no--kdcHost, no--dns-server):After, same host, same command, glibc
AF_UNSPECstill failing:Test suite:
Checklist:
poetry run ruff check ., 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)Sources for the resolver behaviour:
resolv.conf(5)— see theedns0andsingle-requestoptions, which exist precisely because of the parallel A/AAAA truncation problem — andgetaddrinfo(3)forEAI_AGAIN.