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.30 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; # Change this to T to only monitor for the High Fidelilty SIG exploit. option only_enable_high_fidelity_notice: bool = F; } # 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, just return # because these packets are often large by design. if (c$uid in AXFR_cuid) return; if (c$resp$size >= 65258) { 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 (!only_enable_high_fidelity_notice && ans$qtype == 46 || ans$qtype == 249) # RRSIG/TKEY { 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/"; } if (only_enable_high_fidelity_notice && /^Potential/ in message) return; 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); } # We only want to run the dns_request event when the medium fidelity # notices are required, as this may be an expensive event @if (!only_enable_high_fidelity_notice) event dns_request(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count) { # A guardrail for query types Zone transfer types AXFR(252) # that may legitimately exceed the size limit if (qtype == 252) ++AXFR_cuid[c$uid]; } @endif