From: Petr Špaček Date: Wed, 23 Jul 2025 15:25:18 +0000 (+0200) Subject: Test that unsolicited NS in positive answer cannot overwrite current NS X-Git-Tag: v9.21.17~14^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=658d2e9f8ec8408f227af034bd87cf4ff3189a88;p=thirdparty%2Fbind9.git Test that unsolicited NS in positive answer cannot overwrite current NS Before the fixes for CVE-2025-40778, an unsolicited in-bailiwick NS record was accepted from a (spoofed) answer, enabling a single spoofed A query/response to redirect traffic for a whole delegation. In short, the attacker tries to spoof at least one answer that has the following form: rcode NOERROR flags QR AA ;QUESTION trigger$RANDOM.victim. IN TXT ;ANSWER trigger$RANDOM.victim. 3600 IN TXT "spoofed answer with extra NS" ;AUTHORITY victim. 3600 IN NS ns.attacker. ;ADDITIONAL This attack was originally reported as "test case 1". Co-authored-by: Michał Kępień --- diff --git a/bin/tests/system/bailiwick/ans2/ans.py b/bin/tests/system/bailiwick/ans2/ans.py index be072a39e16..d0ddccbe62d 100644 --- a/bin/tests/system/bailiwick/ans2/ans.py +++ b/bin/tests/system/bailiwick/ans2/ans.py @@ -29,6 +29,32 @@ ATTACKER_IP = "10.53.0.3" TTL = 3600 +class UnsolicitedNsSpoofer(ResponseSpoofer, mode="unsolicited-ns"): + + qname = "trigger.victim." + + async def get_responses( + self, qctx: QueryContext + ) -> AsyncGenerator[ResponseAction, None]: + response = qctx.prepare_new_response(with_zone_data=False) + + txt_rrset = dns.rrset.from_text( + qctx.qname, + TTL, + qctx.qclass, + dns.rdatatype.TXT, + '"spoofed answer with extra NS"', + ) + response.answer.append(txt_rrset) + + ns_rrset = dns.rrset.from_text( + "victim.", TTL, qctx.qclass, dns.rdatatype.NS, "ns.attacker." + ) + response.authority.append(ns_rrset) + + yield DnsResponseSend(response, authoritative=True) + + def main() -> None: spoofing_server().run() diff --git a/bin/tests/system/bailiwick/tests_bailiwick.py b/bin/tests/system/bailiwick/tests_bailiwick.py index b068180265c..644fe5f24af 100644 --- a/bin/tests/system/bailiwick/tests_bailiwick.py +++ b/bin/tests/system/bailiwick/tests_bailiwick.py @@ -85,3 +85,12 @@ def test_bailiwick_sibling_ns_referral(servers: Dict[str, NamedInstance]) -> Non ns4 = servers["ns4"] send_trigger_query(ns4, "trigger.") check_domain_hijack(ns4) + + +def test_bailiwick_unsolicited_authority(servers: Dict[str, NamedInstance]) -> None: + set_spoofing_mode(ans1="none", ans2="unsolicited-ns") + + ns4 = servers["ns4"] + prime_cache(ns4) + send_trigger_query(ns4, "trigger.victim.") + check_domain_hijack(ns4)