diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 70d59b30cf..83a44df5fe 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -3544,6 +3544,66 @@ type dns_tsig_additional: record { is_query: count; ##< TODO. }; +## A DNSSEC RRSIG record. +## +## .. bro:see:: dns_RRSIG_addl +type dns_rrsig_additional: record { + query: string; ##< Query. + answer_type: count; ##< Ans type. + type_covered: count; ## qtype covered by RRSIG RR. + algorithm: count; ##< Algorithm. + labels: count; ##< labels in the owner's name. + orig_ttl: interval; ##< original TTL + sig_exp: time; ##< Time when signed RR expires. + sig_incep: time; ##< Time when signed. + key_tag: count; ## key tag value + signer_name: string; ##< Signature. + signature: string; ##< Hash of the RRDATA + is_query: count; ##< The RR is a query/Response. +}; + +## A DNSSEC DNSKEY record. +## +## .. bro:see:: dns_DNSKEY_addl +type dns_dnskey_additional: record { + query: string; ##< Query. + answer_type: count; ##< Ans type. + flags: count; ##< flags filed. + protocol: count; ##< Protocol, should be always 3 for DNSSEC. + algorithm: count; ##< Algorithm for Public Key. + public_key: string; ##< Public Key + is_query: count; ##< The RR is a query/Response. +}; + +## A DNSSEC NSEC3 record. +## +## .. bro:see:: dns_NSEC3_addl +type dns_nsec3_additional: record { + query: string; ##< Query. + answer_type: count; ##< Ans type. + nsec_flags: count; ##< flags field. + nsec_hash_algo: count; ##< Hash algorithm. + nsec_iter: count; ##< Iterations. + nsec_salt_len: count; ##< salt length. + nsec_salt: string; ##< Salt value + nsec_hlen: count; ##< Hash length. + nsec_hash: string; ##< Hash value. + is_query: count; ##< The RR is a query/Response. +}; + +## A DNSSEC DS record. +## +## .. bro:see:: dns_DS_addl +type dns_ds_additional: record { + query: string; ##< Query. + answer_type: count; ##< Ans type. + key_tag: count; ##< flags filed. + algorithm: count; ##< Algorithm for Public Key. + digest_type: count; ##< Digest Type. + digest_val: string; ##< Digest Value. + is_query: count; ##< The RR is a query/Response. +}; + # DNS answer types. # # .. bro:see:: dns_answerr diff --git a/scripts/base/protocols/dns/consts.bro b/scripts/base/protocols/dns/consts.bro index dfcbc4031f..b62f923041 100644 --- a/scripts/base/protocols/dns/consts.bro +++ b/scripts/base/protocols/dns/consts.bro @@ -76,4 +76,34 @@ export { [254] = "C_NONE", [255] = "C_ANY", } &default = function(n: count): string { return fmt("qclass-%d", n); }; + + ## Possible values of the algorithms used in DNSKEY, DS and RRSIG records + const algorithms = { + [0] = "reserved0", + [1] = "RSA_MD5", + [2] = "Diffie_Hellman", + [3] = "DSA_SHA1", + [4] = "Elliptic_Curve", + [5] = "RSA_SHA1", + [6] = "DSA_NSEC3_SHA1", + [7] = "RSA_SHA1_NSEC3_SHA1", + [8] = "RSA_SHA256", + [10] = "RSA_SHA512", + [12] = "GOST_R_34_10_2001", + [13] = "ECDSA_curveP256withSHA256", + [14] = "ECDSA_curveP384withSHA384", + [252] = "Indirect", + [253] = "PrivateDNS", + [254] = "PrivateOID", + [255] = "reserved255", + } &default = function(n: count): string { return fmt("algorithm-%d", n); }; + + const digests = { + [0] = "reserved0", + [1] = "SHA1", + [2] = "SHA256", + [3] = "GOST_R_34_11_94", + [4] = "SHA384", + } &default = function(n: count): string { return fmt("digest-%d", n); }; + } diff --git a/scripts/base/protocols/dns/main.bro b/scripts/base/protocols/dns/main.bro index a6104e12a3..5a902cacf8 100644 --- a/scripts/base/protocols/dns/main.bro +++ b/scripts/base/protocols/dns/main.bro @@ -466,6 +466,45 @@ event dns_SRV_reply(c: connection, msg: dns_msg, ans: dns_answer, target: string # # } +event dns_RRSIG_addl(c: connection, msg: dns_msg, ans: dns_answer, rrsig: dns_rrsig_additional) + { + local rrsig_rec: string = fmt("RRSIG_Signer_%s", rrsig$signer_name); + if ( rrsig$signer_name == "") + rrsig_rec = fmt("RRSIG_Signer_"); + + hook DNS::do_reply(c, msg, ans, rrsig_rec); + } + +event dns_DNSKEY_addl(c: connection, msg: dns_msg, ans: dns_answer, dnskey: dns_dnskey_additional) + { + local dnskey_rec: string = fmt("DNSKEY_for_%s", ans$query); + if (ans$query == "") + dnskey_rec = fmt("DNSKEY_for_"); + hook DNS::do_reply(c, msg, ans, dnskey_rec); + } + +event dns_NSEC_addl(c: connection, msg: dns_msg, ans: dns_answer, next_name: string, bitmaps: string_vec) + { + hook DNS::do_reply(c, msg, ans, next_name); + } + +event dns_NSEC3_addl(c: connection, msg: dns_msg, ans: dns_answer, nsec3: dns_nsec3_additional, bitmaps: string_vec) + { + local nsec3_rec: string = fmt("NSEC3_for_%s", ans$query); + if (ans$query == "") + nsec3_rec = fmt("NSEC3_for_"); + + hook DNS::do_reply(c, msg, ans, nsec3_rec); + } + +event dns_DS_addl(c: connection, msg: dns_msg, ans: dns_answer, ds: dns_ds_additional) + { + local ds_rec: string = fmt("DS_for_%s", ans$query); + if (ans$query == "") + ds_rec = fmt("DS_for_"); + hook DNS::do_reply(c, msg, ans, ds_rec); + } + event dns_rejected(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count) &priority=5 { if ( c?$dns ) diff --git a/scripts/policy/protocols/dns/addl-dnskey.bro b/scripts/policy/protocols/dns/addl-dnskey.bro new file mode 100644 index 0000000000..ef36b5433b --- /dev/null +++ b/scripts/policy/protocols/dns/addl-dnskey.bro @@ -0,0 +1,42 @@ +##! This script adds additional fields for the DNSKEY dns response of current +##! query to the DNS log. It can cause severe overhead. + +@load base/protocols/dns/main +@load base/protocols/dns/consts + +redef dns_skip_all_auth = F; +redef dns_skip_all_addl = F; + +module DNS; + +export { + redef record Info += { + + dnskey_flags: vector of count &log &optional; + dnskey_algo: vector of string &log &optional; + dnskey_proto: vector of count &log &optional; + dnskey_pubkey: vector of string &log &optional; + }; +} + +event dns_DNSKEY_addl(c: connection, msg: dns_msg, ans: dns_answer, dnskey: dns_dnskey_additional) + { + if ( c?$dns ) + { + if ( ! c$dns?$dnskey_flags ) + c$dns$dnskey_flags = vector(); + c$dns$dnskey_flags[|c$dns$dnskey_flags|] = dnskey$flags; + + if ( ! c$dns?$dnskey_algo ) + c$dns$dnskey_algo = vector(); + c$dns$dnskey_algo[|c$dns$dnskey_algo|] = DNS::algorithms[dnskey$algorithm]; + + if ( ! c$dns?$dnskey_proto ) + c$dns$dnskey_proto = vector(); + c$dns$dnskey_proto[|c$dns$dnskey_proto|] = dnskey$protocol; + + if ( ! c$dns?$dnskey_pubkey) + c$dns$dnskey_pubkey = vector(); + c$dns$dnskey_pubkey[|c$dns$dnskey_pubkey|] = bytestring_to_hexstr(dnskey$public_key); + } + } diff --git a/scripts/policy/protocols/dns/addl-ds.bro b/scripts/policy/protocols/dns/addl-ds.bro new file mode 100644 index 0000000000..aa9b2eddab --- /dev/null +++ b/scripts/policy/protocols/dns/addl-ds.bro @@ -0,0 +1,42 @@ +##! This script adds additional fields for the DS dns response of current +##! query to the DNS log. It can cause severe overhead. + +@load base/protocols/dns/main +@load base/protocols/dns/consts + +redef dns_skip_all_auth = F; +redef dns_skip_all_addl = F; + +module DNS; + +export { + redef record Info += { + + ds_key_tag: vector of count &log &optional; + ds_algo: vector of string &log &optional; + ds_digestType: vector of string &log &optional; + ds_digest: vector of string &log &optional; + }; +} + +event dns_DS_addl(c: connection, msg: dns_msg, ans: dns_answer, ds: dns_ds_additional) + { + if ( c?$dns ) + { + if ( ! c$dns?$ds_key_tag ) + c$dns$ds_key_tag = vector(); + c$dns$ds_key_tag[|c$dns$ds_key_tag|] = ds$key_tag; + + if ( ! c$dns?$ds_algo ) + c$dns$ds_algo = vector(); + c$dns$ds_algo[|c$dns$ds_algo|] = DNS::algorithms[ds$algorithm]; + + if ( ! c$dns?$ds_digestType ) + c$dns$ds_digestType = vector(); + c$dns$ds_digestType[|c$dns$ds_digestType|] = DNS::digests[ds$digest_type]; + + if ( ! c$dns?$ds_digest) + c$dns$ds_digest = vector(); + c$dns$ds_digest[|c$dns$ds_digest|] = bytestring_to_hexstr(ds$digest_val); + } + } diff --git a/scripts/policy/protocols/dns/addl-nsec3.bro b/scripts/policy/protocols/dns/addl-nsec3.bro new file mode 100644 index 0000000000..13dd5f6aa4 --- /dev/null +++ b/scripts/policy/protocols/dns/addl-nsec3.bro @@ -0,0 +1,76 @@ +##! This script adds additional fields for the NSEC3 dns response of current +##! query to the DNS log. It can cause severe overhead. + +@load base/protocols/dns/main +@load base/protocols/dns/consts + +redef dns_skip_all_auth = F; +redef dns_skip_all_addl = F; + +module DNS; + +export { + redef record Info += { + + nsec_flags: vector of count &log &optional; + nsec_hash_algo: vector of count &log &optional; + nsec_iter: vector of count &log &optional; + nsec_salt_len: vector of count &log &optional; + nsec_salt: vector of string &log &optional; + nsec_hlen: vector of count &log &optional; + nsec_hash: vector of string &log &optional; + nsec_bitmaps: vector of string &log &optional; + }; +} + +event dns_NSEC3_addl(c: connection, msg: dns_msg, ans: dns_answer, nsec3: dns_nsec3_additional, bitmaps: string_vec) + { + if ( c?$dns ) + { + if ( ! c$dns?$nsec_flags ) + c$dns$nsec_flags = vector(); + c$dns$nsec_flags[|c$dns$nsec_flags|] = nsec3$nsec_flags; + + if ( ! c$dns?$nsec_hash_algo ) + c$dns$nsec_hash_algo = vector(); + c$dns$nsec_hash_algo[|c$dns$nsec_hash_algo|] = nsec3$nsec_hash_algo; + + if ( ! c$dns?$nsec_iter ) + c$dns$nsec_iter = vector(); + c$dns$nsec_iter[|c$dns$nsec_iter|] = nsec3$nsec_iter; + + if ( ! c$dns?$nsec_salt_len) + c$dns$nsec_salt_len = vector(); + c$dns$nsec_salt_len[|c$dns$nsec_salt_len|] = nsec3$nsec_salt_len; + + if ( ! c$dns?$nsec_salt) + c$dns$nsec_salt = vector(); + c$dns$nsec_salt[|c$dns$nsec_salt|] = bytestring_to_hexstr(nsec3$nsec_salt); + + if ( ! c$dns?$nsec_hlen) + c$dns$nsec_hlen = vector(); + c$dns$nsec_hlen[|c$dns$nsec_hlen|] = nsec3$nsec_hlen; + + if ( ! c$dns?$nsec_hash) + c$dns$nsec_hash = vector(); + c$dns$nsec_hash[|c$dns$nsec_hash|] = bytestring_to_hexstr(nsec3$nsec_hash); + + if ( ! c$dns?$nsec_bitmaps) + c$dns$nsec_bitmaps = vector(); + + if ( |bitmaps| != 0) + { + local bitmap_strings: string = ""; + + for ( i in bitmaps ) + { + if ( i > 0 ) + bitmap_strings += " "; + + bitmap_strings += fmt("bitmap %d %s", |bitmaps[i]|, bitmaps[i]); + } + c$dns$nsec_bitmaps[|c$dns$nsec_bitmaps|] = bitmap_strings; + } + + } + } diff --git a/scripts/policy/protocols/dns/addl-rrsig.bro b/scripts/policy/protocols/dns/addl-rrsig.bro new file mode 100644 index 0000000000..9216432ba6 --- /dev/null +++ b/scripts/policy/protocols/dns/addl-rrsig.bro @@ -0,0 +1,64 @@ +##! This script adds additional fields corresponding to the RRSIG record responses for the current +##! query to the DNS log. It can cause severe overhead. + +@load base/protocols/dns/main +@load base/protocols/dns/consts + +module DNS; + +export { + redef record Info += { + rrsig_type_covered: vector of string &log &optional; + rrsig_orig_ttl: vector of interval &log &optional; + rrsig_key_tag: vector of count &log &optional; + rrsig_algo: vector of string &log &optional; + rrsig_labels: vector of count &log &optional; + rrsig_signer_name: vector of string &log &optional; + rrsig_signature: vector of string &log &optional; + rrsig_sig_exp: vector of time &log &optional; + rrsig_sig_inc: vector of time &log &optional; + }; +} + +event dns_RRSIG_addl(c: connection, msg: dns_msg, ans: dns_answer, rrsig: dns_rrsig_additional) + { + if ( c?$dns ) + { + if ( ! c$dns?$rrsig_type_covered ) + c$dns$rrsig_type_covered = vector(); + c$dns$rrsig_type_covered[|c$dns$rrsig_type_covered|] = DNS::query_types[rrsig$type_covered]; + + if ( ! c$dns?$rrsig_orig_ttl ) + c$dns$rrsig_orig_ttl = vector(); + c$dns$rrsig_orig_ttl[|c$dns$rrsig_orig_ttl|] = rrsig$orig_ttl; + + if ( ! c$dns?$rrsig_key_tag ) + c$dns$rrsig_key_tag = vector(); + c$dns$rrsig_key_tag[|c$dns$rrsig_key_tag|] = rrsig$key_tag; + + if ( ! c$dns?$rrsig_algo ) + c$dns$rrsig_algo = vector(); + c$dns$rrsig_algo[|c$dns$rrsig_algo|] = DNS::algorithms[rrsig$algorithm]; + + if ( ! c$dns?$rrsig_labels ) + c$dns$rrsig_labels = vector(); + c$dns$rrsig_labels[|c$dns$rrsig_labels|] = rrsig$labels; + + if ( ! c$dns?$rrsig_signer_name ) + c$dns$rrsig_signer_name = vector(); + c$dns$rrsig_signer_name[|c$dns$rrsig_signer_name|] = rrsig$signer_name; + + if ( ! c$dns?$rrsig_signature ) + c$dns$rrsig_signature = vector(); + c$dns$rrsig_signature[|c$dns$rrsig_signature|] = bytestring_to_hexstr(rrsig$signature); + + if ( ! c$dns?$rrsig_sig_exp ) + c$dns$rrsig_sig_exp = vector(); + c$dns$rrsig_sig_exp[|c$dns$rrsig_sig_exp|] = rrsig$sig_exp; + + if ( ! c$dns?$rrsig_sig_inc ) + c$dns$rrsig_sig_inc = vector(); + c$dns$rrsig_sig_inc[|c$dns$rrsig_sig_inc|] = rrsig$sig_incep; + } + + } diff --git a/src/NetVar.cc b/src/NetVar.cc index 93533b9627..c524d35f4a 100644 --- a/src/NetVar.cc +++ b/src/NetVar.cc @@ -115,6 +115,10 @@ RecordType* dns_answer; RecordType* dns_soa; RecordType* dns_edns_additional; RecordType* dns_tsig_additional; +RecordType* dns_rrsig_additional; +RecordType* dns_dnskey_additional; +RecordType* dns_nsec3_additional; +RecordType* dns_ds_additional; TableVal* dns_skip_auth; TableVal* dns_skip_addl; int dns_skip_all_auth; @@ -430,7 +434,14 @@ void init_net_var() internal_type("dns_edns_additional")->AsRecordType(); dns_tsig_additional = internal_type("dns_tsig_additional")->AsRecordType(); - + dns_rrsig_additional = + internal_type("dns_rrsig_additional")->AsRecordType(); + dns_dnskey_additional = + internal_type("dns_dnskey_additional")->AsRecordType(); + dns_nsec3_additional = + internal_type("dns_nsec3_additional")->AsRecordType(); + dns_ds_additional = + internal_type("dns_ds_additional")->AsRecordType(); dns_skip_auth = internal_val("dns_skip_auth")->AsTableVal(); dns_skip_addl = internal_val("dns_skip_addl")->AsTableVal(); dns_skip_all_auth = opt_internal_int("dns_skip_all_auth"); diff --git a/src/NetVar.h b/src/NetVar.h index 023be18867..f559eab922 100644 --- a/src/NetVar.h +++ b/src/NetVar.h @@ -118,6 +118,10 @@ extern RecordType* dns_answer; extern RecordType* dns_soa; extern RecordType* dns_edns_additional; extern RecordType* dns_tsig_additional; +extern RecordType* dns_rrsig_additional; +extern RecordType* dns_dnskey_additional; +extern RecordType* dns_nsec3_additional; +extern RecordType* dns_ds_additional; extern TableVal* dns_skip_auth; extern TableVal* dns_skip_addl; extern int dns_skip_all_auth; diff --git a/src/analyzer/protocol/dns/DNS.cc b/src/analyzer/protocol/dns/DNS.cc index 145d19950f..190de97220 100644 --- a/src/analyzer/protocol/dns/DNS.cc +++ b/src/analyzer/protocol/dns/DNS.cc @@ -312,6 +312,26 @@ int DNS_Interpreter::ParseAnswer(DNS_MsgInfo* msg, status = ParseRR_TSIG(msg, data, len, rdlength, msg_start); break; + case TYPE_RRSIG: + status = ParseRR_RRSIG(msg, data, len, rdlength, msg_start); + break; + + case TYPE_DNSKEY: + status = ParseRR_DNSKEY(msg, data, len, rdlength, msg_start); + break; + + case TYPE_NSEC: + status = ParseRR_NSEC(msg, data, len, rdlength, msg_start); + break; + + case TYPE_NSEC3: + status = ParseRR_NSEC3(msg, data, len, rdlength, msg_start); + break; + + case TYPE_DS: + status = ParseRR_DS(msg, data, len, rdlength, msg_start); + break; + default: if ( dns_unknown_reply && ! msg->skip_event ) @@ -724,6 +744,20 @@ void DNS_Interpreter::ExtractOctets(const u_char*& data, int& len, len -= dlen; } +void DNS_Interpreter::ExtractStream(const u_char*& data, int& len, + BroString** p, int siglen) + { + + int dlen = min(len, siglen); // Len in bytes of the algorithm use + + if ( p ) + *p = new BroString(data, dlen, 0); + + data += dlen; + len -= dlen; + + } + int DNS_Interpreter::ParseRR_TSIG(DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start) @@ -769,6 +803,418 @@ int DNS_Interpreter::ParseRR_TSIG(DNS_MsgInfo* msg, return 1; } +int DNS_Interpreter::ParseRR_RRSIG(DNS_MsgInfo* msg, + const u_char*& data, int& len, int rdlength, + const u_char* msg_start) + { + + unsigned int type_covered = ExtractShort(data, len); + // split the two bytes for algo and labels extraction + uint32 algo_lab = ExtractShort(data, len); + unsigned int algo = (algo_lab >> 8) & 0xff; + unsigned int lab = algo_lab & 0xff; + + uint32 orig_ttl = ExtractLong(data, len); + uint32 sign_exp = ExtractLong(data, len); + uint32 sign_incp = ExtractLong(data, len); + unsigned int key_tag = ExtractShort(data, len); + + //implement signer's name with the msg_start offset + const u_char* data_start = data; + u_char name[513]; + int name_len = sizeof(name) - 1; + + u_char* name_end = ExtractName(data, len, name, name_len, msg_start); + if ( ! name_end ) + return 0; + + int sig_len = rdlength - ((data - data_start) + 18); + DNSSEC_Algo dsa = DNSSEC_Algo(algo); + BroString* sign; + + switch ( dsa ) { + + case RSA_MD5: + ExtractStream(data, len, &sign, sig_len); + analyzer->Weird("DNSSEC_RRSIG_NotRecommended_ZoneSignAlgo", fmt("%d", algo)); + break; + + case Diffie_Hellman: + ExtractStream(data, len, &sign, sig_len); + break; + + case DSA_SHA1: + ExtractStream(data, len, &sign, sig_len); + break; + + case Elliptic_Curve: + ExtractStream(data, len, &sign, sig_len); + break; + + case RSA_SHA1: + ExtractStream(data, len, &sign, sig_len); + break; + + case DSA_NSEC3_SHA1: + ExtractStream(data, len, &sign, sig_len); + break; + + case RSA_SHA1_NSEC3_SHA1: + ExtractStream(data, len, &sign, sig_len); + break; + + case RSA_SHA256: + ExtractStream(data, len, &sign, sig_len); + break; + + case RSA_SHA512: + ExtractStream(data, len, &sign, sig_len); + break; + + case GOST_R_34_10_2001: + ExtractStream(data, len, &sign, sig_len); + break; + + case ECDSA_curveP256withSHA256: + ExtractStream(data, len, &sign, sig_len); + break; + + case ECDSA_curveP384withSHA384: + ExtractStream(data, len, &sign, sig_len); + break; + + case Indirect: + ExtractStream(data, len, &sign, sig_len); + analyzer->Weird("DNSSEC_RRSIG_Indirect_ZoneSignAlgo", fmt("%d", algo)); + break; + + case PrivateDNS: + ExtractStream(data, len, &sign, sig_len); + analyzer->Weird("DNSSEC_RRSIG_PrivateDNS_ZoneSignAlgo", fmt("%d", algo)); + break; + + case PrivateOID: + ExtractStream(data, len, &sign, sig_len); + analyzer->Weird("DNSSEC_RRSIG_PrivateOID_ZoneSignAlgo", fmt("%d", algo)); + break; + + default: + ExtractStream(data, len, &sign, sig_len); + analyzer->Weird("DNSSEC_RRSIG_unknown_ZoneSignAlgo", fmt("%d", algo)); + break; + } + + msg->rrsig = new RRSIG_DATA; + msg->rrsig->type_covered = type_covered; + msg->rrsig->orig_ttl = orig_ttl; + msg->rrsig->sig_exp = sign_exp; + msg->rrsig->sig_incep = sign_incp; + msg->rrsig->key_tag = key_tag; + msg->rrsig->algorithm = algo; + msg->rrsig->labels = lab; + msg->rrsig->signer_name = new BroString(name, name_end - name, 1); + msg->rrsig->signature = sign; + + val_list* vl = new val_list; + + vl->append(analyzer->BuildConnVal()); + vl->append(msg->BuildHdrVal()); + vl->append(msg->BuildAnswerVal()); + vl->append(msg->BuildRRSIG_Val()); + + analyzer->ConnectionEvent(dns_RRSIG_addl, vl); + + return 1; + } + +int DNS_Interpreter::ParseRR_DNSKEY(DNS_MsgInfo* msg, + const u_char*& data, int& len, int rdlength, + const u_char* msg_start) + { + + unsigned int dflags = ExtractShort(data, len); + // split the two bytes for protocol and algorithm extraction + uint32 proto_algo = ExtractShort(data, len); + unsigned int dprotocol = (proto_algo >> 8) & 0xff; + unsigned int dalgorithm = proto_algo & 0xff; + + if (dflags != 256 and dflags != 257 and dflags != 0) + analyzer->Weird("DNSSEC_DNSKEY_Invalid_Flag", fmt("%d", dflags)); + + if ( dprotocol != 3 ) + analyzer->Weird("DNSSEC_DNSKEY_Invalid_Protocol", fmt("%d", dprotocol)); + + //Evaluating the size of remaining bytes for Public Key + int sig_len = rdlength - 4; + DNSSEC_Algo dsa = DNSSEC_Algo(dalgorithm); + BroString* sign; + + switch ( dsa ) { + + case RSA_MD5: + ExtractStream(data, len, &sign, sig_len); + analyzer->Weird("DNSSEC_DNSKEY_NotRecommended_ZoneSignAlgo", fmt("%d", dalgorithm)); + break; + + case Diffie_Hellman: + ExtractStream(data, len, &sign, sig_len); + break; + + case DSA_SHA1: + ExtractStream(data, len, &sign, sig_len); + break; + + case Elliptic_Curve: + ExtractStream(data, len, &sign, sig_len); + break; + + case RSA_SHA1: + ExtractStream(data, len, &sign, sig_len); + break; + + case DSA_NSEC3_SHA1: + ExtractStream(data, len, &sign, sig_len); + break; + + case RSA_SHA1_NSEC3_SHA1: + ExtractStream(data, len, &sign, sig_len); + break; + + case RSA_SHA256: + ExtractStream(data, len, &sign, sig_len); + break; + + case RSA_SHA512: + ExtractStream(data, len, &sign, sig_len); + break; + + case GOST_R_34_10_2001: + ExtractStream(data, len, &sign, sig_len); + break; + + case ECDSA_curveP256withSHA256: + ExtractStream(data, len, &sign, sig_len); + break; + + case ECDSA_curveP384withSHA384: + ExtractStream(data, len, &sign, sig_len); + break; + + case Indirect: + ExtractStream(data, len, &sign, sig_len); + analyzer->Weird("DNSSEC_DNSKEY_Indirect_ZoneSignAlgo", fmt("%d", dalgorithm)); + break; + + case PrivateDNS: + ExtractStream(data, len, &sign, sig_len); + analyzer->Weird("DNSSEC_DNSKEY_PrivateDNS_ZoneSignAlgo", fmt("%d", dalgorithm)); + break; + + case PrivateOID: + ExtractStream(data, len, &sign, sig_len); + analyzer->Weird("DNSSEC_DNSKEY_PrivateOID_ZoneSignAlgo", fmt("%d", dalgorithm)); + break; + + default: + ExtractStream(data, len, &sign, sig_len); + analyzer->Weird("DNSSEC_DNSKEY_unknown_ZoneSignAlgo", fmt("%d", dalgorithm)); + break; + } + + msg->dnskey = new DNSKEY_DATA; + msg->dnskey->dflags = dflags; + msg->dnskey->dprotocol = dprotocol; + msg->dnskey->dalgorithm = dalgorithm; + msg->dnskey->public_key = sign; + + val_list* vl = new val_list; + + vl->append(analyzer->BuildConnVal()); + vl->append(msg->BuildHdrVal()); + vl->append(msg->BuildAnswerVal()); + vl->append(msg->BuildDNSKEY_Val()); + + analyzer->ConnectionEvent(dns_DNSKEY_addl, vl); + + return 1; + } + +int DNS_Interpreter::ParseRR_NSEC(DNS_MsgInfo* msg, + const u_char*& data, int& len, int rdlength, + const u_char* msg_start) + { + + const u_char* data_start = data; + u_char name[513]; + int name_len = sizeof(name) - 1; + + u_char* name_end = ExtractName(data, len, name, name_len, msg_start); + if ( ! name_end ) + return 0; + + int typebitmaps_len = rdlength - (data - data_start); + + VectorVal* char_strings = new VectorVal(string_vec); + + while (typebitmaps_len > 0) + { + BroString* bitmap; + uint32 block_bmlen = ExtractShort(data, len); + unsigned int win_blck = ( block_bmlen >> 8) & 0xff; + unsigned int bmlen = block_bmlen & 0xff; + if (bmlen == 0) + { + analyzer->Weird("DNSSEC_NSEC_bitmapLen0", fmt("%d", win_blck)); + break; + } + ExtractStream(data, len, &bitmap, bmlen); + + char_strings->Assign(char_strings->Size(), new StringVal(bitmap)); + typebitmaps_len = typebitmaps_len - (2 + bmlen); + } + + val_list* vl = new val_list; + + vl->append(analyzer->BuildConnVal()); + vl->append(msg->BuildHdrVal()); + vl->append(msg->BuildAnswerVal()); + vl->append(new StringVal(new BroString(name, name_end - name, 1))); + vl->append(char_strings); + + analyzer->ConnectionEvent(dns_NSEC_addl, vl); + + return 1; + } + +int DNS_Interpreter::ParseRR_NSEC3(DNS_MsgInfo* msg, + const u_char*& data, int& len, int rdlength, + const u_char* msg_start) + { + const u_char* data_start = data; + uint32 halgo_flags = ExtractShort(data, len); + unsigned int hash_algo = ( halgo_flags >> 8) & 0xff; + unsigned int nsec_flags = halgo_flags & 0xff; + unsigned int iter = ExtractShort(data,len); + + uint8 salt_len = data[0]; + ++data; + --len; + + BroString* salt_val; + ExtractStream(data, len, &salt_val, static_cast(salt_len)); + + uint8 hash_len = data[0]; + ++data; + --len; + + BroString* hash_val; + ExtractStream(data, len, &hash_val, static_cast(hash_len)); + + int typebitmaps_len = rdlength - (data - data_start); + + VectorVal* char_strings = new VectorVal(string_vec); + + while (typebitmaps_len > 0) + { + BroString* bitmap; + uint32 block_bmlen = ExtractShort(data, len); + unsigned int win_blck = ( block_bmlen >> 8) & 0xff; + unsigned int bmlen = block_bmlen & 0xff; + if (bmlen == 0) + { + analyzer->Weird("DNSSEC_NSEC_bitmapLen0", fmt("%d", win_blck)); + break; + } + ExtractStream(data, len, &bitmap, bmlen); + + char_strings->Assign(char_strings->Size(), new StringVal(bitmap)); + typebitmaps_len = typebitmaps_len - (2 + bmlen); + } + + msg->nsec3 = new NSEC3_DATA; + msg->nsec3->nsec_flags = nsec_flags; + msg->nsec3->nsec_hash_algo = hash_algo; + msg->nsec3->nsec_iter = iter; + msg->nsec3->nsec_salt_len = salt_len; + msg->nsec3->nsec_salt = salt_val; + msg->nsec3->nsec_hlen = hash_len; + msg->nsec3->nsec_hash = hash_val; + + val_list* vl = new val_list; + + vl->append(analyzer->BuildConnVal()); + vl->append(msg->BuildHdrVal()); + vl->append(msg->BuildAnswerVal()); + vl->append(msg->BuildNSEC3_Val()); + vl->append(char_strings); + + analyzer->ConnectionEvent(dns_NSEC3_addl, vl); + + return 1; + } + +int DNS_Interpreter::ParseRR_DS(DNS_MsgInfo* msg, + const u_char*& data, int& len, int rdlength, + const u_char* msg_start) + { + + unsigned int ds_key_tag = ExtractShort(data, len); + // split the two bytes for algorithm and digest type extraction + uint32 ds_algo_dtype = ExtractShort(data, len); + unsigned int ds_algo = ( ds_algo_dtype >> 8) & 0xff; + unsigned int ds_dtype = ds_algo_dtype & 0xff; + + int digest_len = rdlength - 4; + DNSSEC_Digest ds_digest_type = DNSSEC_Digest(ds_dtype); + BroString* ds_digest; + + switch ( ds_digest_type ) { + + case SHA1: + ExtractStream(data, len, &ds_digest, digest_len); + break; + + case SHA256: + ExtractStream(data, len, &ds_digest, digest_len); + break; + + case GOST_R_34_11_94: + ExtractStream(data, len, &ds_digest, digest_len); + break; + + case SHA384: + ExtractStream(data, len, &ds_digest, digest_len); + break; + + case reserved0: + ExtractStream(data, len, &ds_digest, digest_len); + analyzer->Weird("DNSSEC_DS_ResrevedDigestType", fmt("%d", ds_dtype)); + break; + + default: + ExtractStream(data, len, &ds_digest, digest_len); + analyzer->Weird("DNSSEC_DS_unknown_DigestType", fmt("%d", ds_dtype)); + break; + } + + msg->ds = new DS_DATA; + msg->ds->key_tag = ds_key_tag; + msg->ds->algorithm = ds_algo; + msg->ds->digest_type = ds_dtype; + msg->ds->digest_val = ds_digest; + + val_list* vl = new val_list; + + vl->append(analyzer->BuildConnVal()); + vl->append(msg->BuildHdrVal()); + vl->append(msg->BuildAnswerVal()); + vl->append(msg->BuildDS_Val()); + + analyzer->ConnectionEvent(dns_DS_addl, vl); + + return 1; + } + int DNS_Interpreter::ParseRR_A(DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength) { @@ -1003,6 +1449,10 @@ DNS_MsgInfo::DNS_MsgInfo(DNS_RawMsgHdr* hdr, int arg_is_query) answer_type = DNS_QUESTION; skip_event = 0; tsig = 0; + rrsig = 0; + dnskey = 0; + nsec3 = 0; + ds = 0; } DNS_MsgInfo::~DNS_MsgInfo() @@ -1063,7 +1513,7 @@ Val* DNS_MsgInfo::BuildEDNS_Val() // Need to break the TTL field into three components: // initial: [------------- ttl (32) ---------------------] - // after: [DO][ ext rcode (7)][ver # (8)][ Z field (16)] + // after: [ ext rcode (8)][ver # (8)][ Z field (16) ] unsigned int ercode = (ttl >> 24) & 0xff; unsigned int version = (ttl >> 16) & 0xff; @@ -1104,6 +1554,90 @@ Val* DNS_MsgInfo::BuildTSIG_Val() return r; } +Val* DNS_MsgInfo::BuildRRSIG_Val() + { + RecordVal* r = new RecordVal(dns_rrsig_additional); + + Ref(query_name); + r->Assign(0, query_name); + r->Assign(1, new Val(int(answer_type), TYPE_COUNT)); + r->Assign(2, new Val(rrsig->type_covered, TYPE_COUNT)); + r->Assign(3, new Val(rrsig->algorithm, TYPE_COUNT)); + r->Assign(4, new Val(rrsig->labels, TYPE_COUNT)); + r->Assign(5, new IntervalVal(double(rrsig->orig_ttl), Seconds)); + r->Assign(6, new Val(double(rrsig->sig_exp), TYPE_TIME)); + r->Assign(7, new Val(double(rrsig->sig_incep), TYPE_TIME)); + r->Assign(8, new Val(rrsig->key_tag, TYPE_COUNT)); + r->Assign(9, new StringVal(rrsig->signer_name)); + r->Assign(10, new StringVal(rrsig->signature)); + r->Assign(11, new Val(is_query, TYPE_COUNT)); + + delete rrsig; + rrsig = 0; + + return r; + } + +Val* DNS_MsgInfo::BuildDNSKEY_Val() + { + RecordVal* r = new RecordVal(dns_dnskey_additional); + + Ref(query_name); + r->Assign(0, query_name); + r->Assign(1, new Val(int(answer_type), TYPE_COUNT)); + r->Assign(2, new Val(dnskey->dflags, TYPE_COUNT)); + r->Assign(3, new Val(dnskey->dprotocol, TYPE_COUNT)); + r->Assign(4, new Val(dnskey->dalgorithm, TYPE_COUNT)); + r->Assign(5, new StringVal(dnskey->public_key)); + r->Assign(6, new Val(is_query, TYPE_COUNT)); + + delete dnskey; + dnskey = 0; + + return r; + } + +Val* DNS_MsgInfo::BuildNSEC3_Val() + { + RecordVal* r = new RecordVal(dns_nsec3_additional); + + Ref(query_name); + r->Assign(0, query_name); + r->Assign(1, new Val(int(answer_type), TYPE_COUNT)); + r->Assign(2, new Val(nsec3->nsec_flags, TYPE_COUNT)); + r->Assign(3, new Val(nsec3->nsec_hash_algo, TYPE_COUNT)); + r->Assign(4, new Val(nsec3->nsec_iter, TYPE_COUNT)); + r->Assign(5, new Val(nsec3->nsec_salt_len, TYPE_COUNT)); + r->Assign(6, new StringVal(nsec3->nsec_salt)); + r->Assign(7, new Val(nsec3->nsec_hlen, TYPE_COUNT)); + r->Assign(8, new StringVal(nsec3->nsec_hash)); + r->Assign(9, new Val(is_query, TYPE_COUNT)); + + delete nsec3; + nsec3 = 0; + + return r; + } + +Val* DNS_MsgInfo::BuildDS_Val() + { + RecordVal* r = new RecordVal(dns_ds_additional); + + Ref(query_name); + r->Assign(0, query_name); + r->Assign(1, new Val(int(answer_type), TYPE_COUNT)); + r->Assign(2, new Val(ds->key_tag, TYPE_COUNT)); + r->Assign(3, new Val(ds->algorithm, TYPE_COUNT)); + r->Assign(4, new Val(ds->digest_type, TYPE_COUNT)); + r->Assign(5, new StringVal(ds->digest_val)); + r->Assign(6, new Val(is_query, TYPE_COUNT)); + + delete ds; + ds = 0; + + return r; + } + Contents_DNS::Contents_DNS(Connection* conn, bool orig, DNS_Interpreter* arg_interp) : tcp::TCP_SupportAnalyzer("CONTENTS_DNS", conn, orig) diff --git a/src/analyzer/protocol/dns/DNS.h b/src/analyzer/protocol/dns/DNS.h index 58a263637e..0291056811 100644 --- a/src/analyzer/protocol/dns/DNS.h +++ b/src/analyzer/protocol/dns/DNS.h @@ -57,7 +57,12 @@ typedef enum { TYPE_TKEY = 249, ///< Transaction Key (RFC 2930) TYPE_TSIG = 250, ///< Transaction Signature (RFC 2845) TYPE_CAA = 257, ///< Certification Authority Authorization (RFC 6844) - + // DNSSEC RR's + TYPE_RRSIG = 46, ///< RR Signature record type (RFC4043) + TYPE_NSEC = 47, ///< Next Secure record (RFC4043) + TYPE_DNSKEY = 48, ///< DNS Key record (RFC 4034) + TYPE_DS = 43, ///< Delegation signer (RFC 4034) + TYPE_NSEC3 = 50, // The following are only valid in queries. TYPE_AXFR = 252, TYPE_ALL = 255, @@ -75,6 +80,33 @@ typedef enum { DNS_ADDITIONAL, } DNS_AnswerType; +typedef enum { + reserved0 = 0, + RSA_MD5 = 1, ///< [RFC2537] NOT RECOMMENDED + Diffie_Hellman = 2, ///< [RFC2539] + DSA_SHA1 = 3, ///< [RFC2536] OPTIONAL + Elliptic_Curve = 4, + RSA_SHA1 = 5, ///< [RFC3110] MANDATORY + DSA_NSEC3_SHA1 = 6, + RSA_SHA1_NSEC3_SHA1 = 7, + RSA_SHA256 = 8, + RSA_SHA512 = 10, + GOST_R_34_10_2001 = 12, + ECDSA_curveP256withSHA256 = 13, + ECDSA_curveP384withSHA384 =14, + Indirect = 252, ///< + PrivateDNS = 253, ///< OPTIONAL + PrivateOID = 254, ///< OPTIONAL + reserved255 = 255, +} DNSSEC_Algo; + +typedef enum { + reserved = 0, + SHA1 = 1, ///< [RFC3110] MANDATORY + SHA256 = 2, + GOST_R_34_11_94 = 3, + SHA384 = 4, +} DNSSEC_Digest; struct DNS_RawMsgHdr { unsigned short id; @@ -105,6 +137,42 @@ struct TSIG_DATA { unsigned short rr_error; }; +struct RRSIG_DATA { + unsigned short type_covered; // 16 : ExtractShort(data, len) + unsigned short algorithm; // 8 + unsigned short labels; // 8 + uint32 orig_ttl; // 32 + unsigned long sig_exp; // 32 + unsigned long sig_incep; // 32 + unsigned short key_tag; //16 + BroString* signer_name; + BroString* signature; +}; + +struct DNSKEY_DATA { + unsigned short dflags; // 16 : ExtractShort(data, len) + unsigned short dalgorithm; // 8 + unsigned short dprotocol; // 8 + BroString* public_key; // Variable lenght Public Key +}; + +struct NSEC3_DATA { + unsigned short nsec_flags; + unsigned short nsec_hash_algo; + unsigned short nsec_iter; + unsigned short nsec_salt_len; + BroString* nsec_salt; + unsigned short nsec_hlen; + BroString* nsec_hash; +}; + +struct DS_DATA { + unsigned short key_tag; // 16 : ExtractShort(data, len) + unsigned short algorithm; // 8 + unsigned short digest_type; // 8 + BroString* digest_val; // Variable lenght Digest of DNSKEY RR +}; + class DNS_MsgInfo { public: DNS_MsgInfo(DNS_RawMsgHdr* hdr, int is_query); @@ -114,6 +182,10 @@ public: Val* BuildAnswerVal(); Val* BuildEDNS_Val(); Val* BuildTSIG_Val(); + Val* BuildRRSIG_Val(); + Val* BuildDNSKEY_Val(); + Val* BuildNSEC3_Val(); + Val* BuildDS_Val(); int id; int opcode; ///< query type, see DNS_Opcode @@ -143,9 +215,14 @@ public: ///< for forward lookups // More values for spesific DNS types. - // struct EDNS_ADDITIONAL* edns; - + //struct EDNS_ADDITIONAL* edns; + //DNSSEC_Algo dnssec_algo; struct TSIG_DATA* tsig; + struct RRSIG_DATA* rrsig; + struct DNSKEY_DATA* dnskey; + struct NSEC3_DATA* nsec3; + struct DS_DATA* ds; + }; @@ -183,6 +260,8 @@ protected: uint32 ExtractLong(const u_char*& data, int& len); void ExtractOctets(const u_char*& data, int& len, BroString** p); + void ExtractStream(const u_char*& data, int& len, BroString** p, int sig_len); + int ParseRR_Name(DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start); @@ -218,7 +297,21 @@ protected: int ParseRR_TSIG(DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start); - + int ParseRR_RRSIG(DNS_MsgInfo* msg, + const u_char*& data, int& len, int rdlength, + const u_char* msg_start); + int ParseRR_DNSKEY(DNS_MsgInfo* msg, + const u_char*& data, int& len, int rdlength, + const u_char* msg_start); + int ParseRR_NSEC(DNS_MsgInfo* msg, + const u_char*& data, int& len, int rdlength, + const u_char* msg_start); + int ParseRR_NSEC3(DNS_MsgInfo* msg, + const u_char*& data, int& len, int rdlength, + const u_char* msg_start); + int ParseRR_DS(DNS_MsgInfo* msg, + const u_char*& data, int& len, int rdlength, + const u_char* msg_start); void SendReplyOrRejectEvent(DNS_MsgInfo* msg, EventHandlerPtr event, const u_char*& data, int& len, BroString* question_name); @@ -270,7 +363,6 @@ public: void Done() override; void ConnectionClosed(tcp::TCP_Endpoint* endpoint, tcp::TCP_Endpoint* peer, int gen_event) override; - void ExpireTimer(double t); static analyzer::Analyzer* Instantiate(Connection* conn) diff --git a/src/analyzer/protocol/dns/events.bif b/src/analyzer/protocol/dns/events.bif index ae796c8e4c..b780a1bf71 100644 --- a/src/analyzer/protocol/dns/events.bif +++ b/src/analyzer/protocol/dns/events.bif @@ -493,6 +493,69 @@ event dns_EDNS_addl%(c: connection, msg: dns_msg, ans: dns_edns_additional%); ## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth event dns_TSIG_addl%(c: connection, msg: dns_msg, ans: dns_tsig_additional%); +## Generated for DNS replies of type *RRSIG*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## rrsig: The parsed RRSIG reply. +event dns_RRSIG_addl%(c: connection, msg: dns_msg, ans: dns_answer, rrsig: dns_rrsig_additional%); + +## Generated for DNS replies of type *DNSKEY*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## dnskey: The parsed DNSKEY reply. +event dns_DNSKEY_addl%(c: connection, msg: dns_msg, ans: dns_answer, dnskey: dns_dnskey_additional%); + +## Generated for DNS replies of type *NSEC*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## next_name: The parsed next secure domain name. +## bitmaps: vector of strings in hex for the bit maps present. +event dns_NSEC_addl%(c: connection, msg: dns_msg, ans: dns_answer, next_name: string, bitmaps: string_vec%); + +## Generated for DNS replies of type *NSEC3*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## nsec3: The parsed RDATA of Nsec3 reply. +## bitmaps: vector of strings in hex for the bit maps present. +event dns_NSEC3_addl%(c: connection, msg: dns_msg, ans: dns_answer, nsec3: dns_nsec3_additional, bitmaps: string_vec%); + +## Generated for DNS replies of type *DS*. For replies with multiple answers, +## an individual event of the corresponding type is raised for each. +## +## c: The connection, which may be UDP or TCP depending on the type of the +## transport-layer session being analyzed. +## +## msg: The parsed DNS message header. +## +## ans: The type-independent part of the parsed answer record. +## ds: The parsed RDATA of DS reply. +## +event dns_DS_addl%(c: connection, msg: dns_msg, ans: dns_answer, ds: dns_ds_additional%); + ## Generated at the end of processing a DNS packet. This event is the last ## ``dns_*`` event that will be raised for a DNS query/reply and signals that ## all resource records have been passed on. diff --git a/testing/btest/Baseline/scripts.base.protocols.dns.rrsig-test/dns.log b/testing/btest/Baseline/scripts.base.protocols.dns.rrsig-test/dns.log new file mode 100644 index 0000000000..93fc583b44 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.dns.rrsig-test/dns.log @@ -0,0 +1,13 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path dns +#open 2018-09-05-15-35-13 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id rtt query qclass qclass_name qtype qtype_name rcode rcode_name AA TC RD RA Z answers TTLs rejected +#types time string addr port addr port enum count interval string count string count string count string bool bool bool bool count vector[string] vector[interval] bool +1533309955.393636 ClEkJM2Vm5giqnMf4h 35.184.172.191 10267 128.175.13.16 53 udp 17129 0.003405 virgo.sas.upenn.edu 1 C_INTERNET 1 A 0 NOERROR T F F F 1 128.91.234.142,RRSIG_Signer_upenn.edu 30.000000,30.000000 F +1533309959.571738 C4J4Th3PJpwUYZZ6gc 35.184.172.191 50056 128.175.13.16 53 udp 26222 0.003363 virgo.sas.upenn.edu 1 C_INTERNET 1 A 0 NOERROR T F F F 1 128.91.234.142,RRSIG_Signer_upenn.edu 30.000000,30.000000 F +1533309959.968589 CtPZjS20MLrsMUOJi2 35.184.172.191 39975 128.175.13.16 53 udp 27118 0.003748 workfamily.sas.upenn.edu 1 C_INTERNET 1 A 0 NOERROR T F F F 1 quasar.sas.upenn.edu,RRSIG_Signer_upenn.edu,128.91.234.145,RRSIG_Signer_upenn.edu 900.000000,900.000000,30.000000,30.000000 F +1533309950.391966 CHhAvVGS1DHFjwGM9 35.184.172.191 5386 128.175.13.16 53 udp 62809 - virgo.sas.upenn.edu 1 C_INTERNET 1 A - - F F F F 1 - - F +#close 2018-09-05-15-35-13 diff --git a/testing/btest/Baseline/scripts.policy.protocols.dns.nsec-addl-rec/dns.log b/testing/btest/Baseline/scripts.policy.protocols.dns.nsec-addl-rec/dns.log new file mode 100644 index 0000000000..3bc100d8d5 --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.dns.nsec-addl-rec/dns.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path dns +#open 2018-09-05-15-51-18 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id rtt query qclass qclass_name qtype qtype_name rcode rcode_name AA TC RD RA Z answers TTLs rejected auth addl +#types time string addr port addr port enum count interval string count string count string count string bool bool bool bool count vector[string] vector[interval] bool set[string] set[string] +1533310046.924340 CHhAvVGS1DHFjwGM9 35.184.172.191 57073 128.175.13.16 53 udp 130 - dla.library.upenn.edu 1 C_INTERNET 28 AAAA 0 NOERROR F F F F 1 - - F dlxssvr.library.upenn.edu,assailants.net.isc.upenn.edu,RRSIG_Signer_upenn.edu - +1533310049.812056 ClEkJM2Vm5giqnMf4h 35.184.172.191 50693 128.175.13.16 53 udp 51063 0.001515 www.upenn.edu 1 C_INTERNET 1 A 0 NOERROR T F F F 1 www.upenn.edgekey.net,RRSIG_Signer_upenn.edu 300.000000,300.000000 F - - +#close 2018-09-05-15-51-18 diff --git a/testing/btest/Traces/nsec-test.trace b/testing/btest/Traces/nsec-test.trace new file mode 100644 index 0000000000..355b782f1d Binary files /dev/null and b/testing/btest/Traces/nsec-test.trace differ diff --git a/testing/btest/Traces/rrsig.trace b/testing/btest/Traces/rrsig.trace new file mode 100644 index 0000000000..e9dbf73b96 Binary files /dev/null and b/testing/btest/Traces/rrsig.trace differ diff --git a/testing/btest/scripts/base/protocols/dns/rrsig-test.bro b/testing/btest/scripts/base/protocols/dns/rrsig-test.bro new file mode 100644 index 0000000000..9299257ad8 --- /dev/null +++ b/testing/btest/scripts/base/protocols/dns/rrsig-test.bro @@ -0,0 +1,4 @@ +# This tests the case where the queries and responses include DNSSEC RRs. +# +# @TEST-EXEC: bro -r $TRACES/rrsig.trace +# @TEST-EXEC: btest-diff dns.log diff --git a/testing/btest/scripts/policy/protocols/dns/nsec-addl-rec.bro b/testing/btest/scripts/policy/protocols/dns/nsec-addl-rec.bro new file mode 100644 index 0000000000..46ab1094c2 --- /dev/null +++ b/testing/btest/scripts/policy/protocols/dns/nsec-addl-rec.bro @@ -0,0 +1,4 @@ +# @TEST-EXEC: bro -r $TRACES/nsec-test.trace %INPUT +# @TEST-EXEC: btest-diff dns.log + +@load protocols/dns/auth-addl