module CVE_2020_1350; # This script raises notices relating to the CVE-2020-1350 (AKA SIGRed) # affecting Windows DNS Server with a CVE score of 10.0 # Tested on zeek 3.2.0-dev.459 # Authors: Ben Reardon, Research Team @Corelight. ben.reardon@corelight.com, @benreardon # Ryan Victory, Applications Team Manager @Corelight. ryan.victory@corelight.com @beerandraptors # # Version: 0.21 export { redef enum Notice::Type += { CVE_2020_1350_Detected_High_Confidence, CVE_2020_1350_Potential }; global AXFR_cuid: table[string] of count &default=0 &write_expire=1hr; } # A list of DNS Record types: https://en.wikipedia.org/wiki/List_of_DNS_record_types # While the primary known attack vector involves the SIG query type, # at this stage of development let's select query types that are associated with signatures # as these are more likely to be parsed by vulnerable function. SIG, KEY, TKEY and RRSIG # Function to take a dns event and look for indicators of the CVE-2020-1350 exploit function handle_dns_event(c: connection, ans: dns_answer) { # If the connection is a non primary packet of an AXFR, return. Only the first AXFR is marked as so, # the following packets are not marked AXFR. if (c$uid in AXFR_cuid) return; if (c$resp$size >= 65258) { # A guardrail for Zone transfer types AXFR(252) and IXFR(251) that may legitimately exceed the proxy size of 65535 if (ans$qtype == 252 || ans$qtype == 251) { # Need to track the uid of the AXFR because only the first packet is logged as query type AXFR ++AXFR_cuid[c$uid]; return; } local notice_type = CVE_2020_1350_Potential; local message = "Potential CVE-2020-1350 Windows DNS exploit (CVE10) has been detected (large DNS response). Refer to links: https://cve.mitre.org/cgi-bin/cvename.cgi?name=ALAS-2020-1350 and https://research.checkpoint.com/2020/resolving-your-way-into-domain-admin-exploiting-a-17-year-old-bug-in-windows-dns-servers/"; if (ans$qtype == 24 || ans$qtype == 25) # SIG/KEY query code and a large response, high confidence! { notice_type = CVE_2020_1350_Detected_High_Confidence; message = "CVE-2020-1350 Windows DNS exploit (CVE10) has been detected (High Confidence, large SIG/KEY response). Refer to links: https://cve.mitre.org/cgi-bin/cvename.cgi?name=ALAS-2020-1350 and https://research.checkpoint.com/2020/resolving-your-way-into-domain-admin-exploiting-a-17-year-old-bug-in-windows-dns-servers/"; } else if (ans$qtype == 46 || ans$qtype == 249) # RRSIG { message = "Potential CVE-2020-1350 Windows DNS exploit (CVE10) has been detected (large DNS RRSIG/TKEY response). Refer to links: https://cve.mitre.org/cgi-bin/cvename.cgi?name=ALAS-2020-1350 and https://research.checkpoint.com/2020/resolving-your-way-into-domain-admin-exploiting-a-17-year-old-bug-in-windows-dns-servers/"; } NOTICE([$note=notice_type, $conn=c, $identifier=cat(c$id$orig_h,c$id$resp_h), $msg=message, $suppress_for=1 hr]); } } # RRSIG (qtype == 46) currently has it's own zeek event and wouldn't trigger the dns_unknown_reply event event dns_RRSIG(c: connection, msg: dns_msg, ans: dns_answer, rrsig: dns_rrsig_rr) { handle_dns_event(c, ans); } # SIG (qtype == 24), KEY (qtype == 25), TKEY (qtype == 249) do not have their own event and so should be parsed by the catch-all event event dns_unknown_reply(c: connection, msg: dns_msg, ans: dns_answer) { handle_dns_event(c, ans); }