)
-class ApexNSHandler(QnameHandler, StaticResponseHandler):
+class ApexNSHandler(QnameQtypeHandler, StaticResponseHandler):
qnames = ["example.net."]
qtypes = [dns.rdatatype.NS]
answer = [rrset(qnames[0], dns.rdatatype.NS, f"ns.{qnames[0]}")]
additional = [rrset(f"ns.{qnames[0]}", dns.rdatatype.A, "10.53.0.3")]
+class AttackDnameHandler(QnameHandler, StaticResponseHandler):
+ qnames = ["www.example.attack.example.net", "isc.attack.example.net."]
+ answer = [rrset("attack.example.net.", dns.rdatatype.DNAME, "org.")]
+
+
class BadCnameHandler(QnameHandler, StaticResponseHandler):
qnames = ["badcname.example.net."]
answer = [rrset(qnames[0], dns.rdatatype.CNAME, "badcname.example.org.")]
answer = [rrset(qnames[0], dns.rdatatype.CNAME, "ok.sub.example.org.")]
+class ExampleOrgHandler(QnameQtypeHandler, StaticResponseHandler):
+ qnames = ["example.org."]
+ qtypes = [dns.rdatatype.A]
+ answer = [rrset(qnames[0], qtypes[0], "1.2.3.4")]
+
+
class FooBadDnameHandler(QnameHandler, StaticResponseHandler):
qnames = ["foo.baddname.example.net."]
answer = [
answer = [rrset(qnames[0], dns.rdatatype.CNAME, "goodcname.example.org.")]
+class IscHandler(QnameQtypeHandler, StaticResponseHandler):
+ qnames = ["isc.org."]
+ qtypes = [dns.rdatatype.A]
+ answer = [rrset(qnames[0], qtypes[0], "1.2.3.4")]
+
+
class LameExampleOrgDelegation(DelegationHandler):
domains = ["lame.example.org."]
server_number = 3
-class LargeReferralHandler(QnameHandler, StaticResponseHandler):
+class LargeReferralHandler(QnameQtypeHandler, StaticResponseHandler):
qnames = ["large-referral.example.net."]
qtypes = [dns.rdatatype.NS]
authority = [
]
+class WwwGoodDnameHandler(QnameHandler, StaticResponseHandler):
+ qnames = ["www.example.gooddname.example.net"]
+ answer = [rrset("gooddname.example.net.", dns.rdatatype.DNAME, "org.")]
+
+
class WwwHandler(QnameHandler):
qnames = ["www.example.net."]
server = AsyncDnsServer(default_aa=True, default_rcode=dns.rcode.NOERROR)
server.install_response_handlers(
ApexNSHandler(),
+ AttackDnameHandler(),
BadCnameHandler(),
BadGoodDnameNsHandler(),
CnameSubHandler(),
+ ExampleOrgHandler(),
FooBadDnameHandler(),
FooBarSubTld1Handler(),
FooGoodDnameHandler(),
Gl6412Ns2Handler(),
Gl6412Ns3Handler(),
GoodCnameHandler(),
+ IscHandler(),
LameExampleOrgDelegation(),
LargeReferralHandler(),
LongCnameHandler(),
OkSubHandler(),
PartialFormerrHandler(),
WwwDnameSubHandler(),
+ WwwGoodDnameHandler(),
WwwHandler(),
)
import time
+import dns.message
+
import isctest
# The ttl being lower than 300 (provided by fake authoritative) proves
# the cache is still in use
assert res.answer[0].ttl < 300
+
+
+# GL#5930
+def test_resolver_dname_target_filter_attack():
+ # Control check - this should return 'attack.example.net. DNAME org.',
+ # which then should result in resolving 'www.example.org. AAAA', which
+ # should be SERVAIL because example.org is in 'deny-answer-aliases'.
+ msg = isctest.query.create("www.example.attack.example.net.", "AAAA")
+ res = isctest.query.udp(msg, "10.53.0.1")
+ isctest.check.servfail(res)
+
+ # Execute the attack - this should return 'attack.example.net. DNAME org.',
+ # which then should result in resolving isc.org and caching the DNAME.
+ msg = isctest.query.create("isc.attack.example.net.", "A")
+ res = isctest.query.udp(msg, "10.53.0.1")
+ answer = """;ANSWER
+attack.example.net. 300 IN DNAME org.
+isc.attack.example.net. 300 IN CNAME isc.org.
+isc.org. 300 IN A 1.2.3.4
+;AUTHORITY
+;ADDITIONAL
+"""
+ expected_answer = dns.message.from_text(answer)
+ isctest.check.noerror(res)
+ isctest.check.rrsets_equal(res.answer, expected_answer.answer)
+ isctest.check.rrsets_equal(res.authority, expected_answer.authority)
+ isctest.check.rrsets_equal(res.additional, expected_answer.additional)
+
+ # Vulnerability check - this should return 'attack.example.net. DNAME org.'
+ # which then should result in resolving 'www.example.org. A', which
+ # should still be SERVAIL because example.org is in 'deny-answer-aliases',
+ # unless the attack on the previous step was successful.
+ msg = isctest.query.create("www.example.attack.example.net.", "A")
+ res = isctest.query.udp(msg, "10.53.0.1")
+ isctest.check.servfail(res)
+
+ # Exception check - this should return 'gooddname.example.net. DNAME org.'
+ # which then should result in resolving 'www.example.org. A', which
+ # should be NOERROR because while example.org is in 'deny-answer-aliases',
+ # gooddname.example.net is in the exceptions list.
+ msg = isctest.query.create("www.example.gooddname.example.net.", "A")
+ res = isctest.query.udp(msg, "10.53.0.1")
+ isctest.check.noerror(res)