DNSSEC support in Bro

This commit is contained in:
fatema 2018-09-05 14:12:07 -04:00
parent e055f9b36b
commit ff5c11975d
18 changed files with 1096 additions and 7 deletions

View file

@ -3544,6 +3544,66 @@ type dns_tsig_additional: record {
is_query: count; ##< TODO. 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. # DNS answer types.
# #
# .. bro:see:: dns_answerr # .. bro:see:: dns_answerr

View file

@ -76,4 +76,34 @@ export {
[254] = "C_NONE", [254] = "C_NONE",
[255] = "C_ANY", [255] = "C_ANY",
} &default = function(n: count): string { return fmt("qclass-%d", n); }; } &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); };
} }

View file

@ -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_<Root>");
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_<Root>");
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_<Root>");
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_<Root>");
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 event dns_rejected(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count) &priority=5
{ {
if ( c?$dns ) if ( c?$dns )

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}
}

View file

@ -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;
}
}

View file

@ -115,6 +115,10 @@ RecordType* dns_answer;
RecordType* dns_soa; RecordType* dns_soa;
RecordType* dns_edns_additional; RecordType* dns_edns_additional;
RecordType* dns_tsig_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_auth;
TableVal* dns_skip_addl; TableVal* dns_skip_addl;
int dns_skip_all_auth; int dns_skip_all_auth;
@ -430,7 +434,14 @@ void init_net_var()
internal_type("dns_edns_additional")->AsRecordType(); internal_type("dns_edns_additional")->AsRecordType();
dns_tsig_additional = dns_tsig_additional =
internal_type("dns_tsig_additional")->AsRecordType(); 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_auth = internal_val("dns_skip_auth")->AsTableVal();
dns_skip_addl = internal_val("dns_skip_addl")->AsTableVal(); dns_skip_addl = internal_val("dns_skip_addl")->AsTableVal();
dns_skip_all_auth = opt_internal_int("dns_skip_all_auth"); dns_skip_all_auth = opt_internal_int("dns_skip_all_auth");

View file

@ -118,6 +118,10 @@ extern RecordType* dns_answer;
extern RecordType* dns_soa; extern RecordType* dns_soa;
extern RecordType* dns_edns_additional; extern RecordType* dns_edns_additional;
extern RecordType* dns_tsig_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_auth;
extern TableVal* dns_skip_addl; extern TableVal* dns_skip_addl;
extern int dns_skip_all_auth; extern int dns_skip_all_auth;

View file

@ -312,6 +312,26 @@ int DNS_Interpreter::ParseAnswer(DNS_MsgInfo* msg,
status = ParseRR_TSIG(msg, data, len, rdlength, msg_start); status = ParseRR_TSIG(msg, data, len, rdlength, msg_start);
break; 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: default:
if ( dns_unknown_reply && ! msg->skip_event ) if ( dns_unknown_reply && ! msg->skip_event )
@ -724,6 +744,20 @@ void DNS_Interpreter::ExtractOctets(const u_char*& data, int& len,
len -= dlen; 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, int DNS_Interpreter::ParseRR_TSIG(DNS_MsgInfo* msg,
const u_char*& data, int& len, int rdlength, const u_char*& data, int& len, int rdlength,
const u_char* msg_start) const u_char* msg_start)
@ -769,6 +803,418 @@ int DNS_Interpreter::ParseRR_TSIG(DNS_MsgInfo* msg,
return 1; 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<int>(salt_len));
uint8 hash_len = data[0];
++data;
--len;
BroString* hash_val;
ExtractStream(data, len, &hash_val, static_cast<int>(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, int DNS_Interpreter::ParseRR_A(DNS_MsgInfo* msg,
const u_char*& data, int& len, int rdlength) 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; answer_type = DNS_QUESTION;
skip_event = 0; skip_event = 0;
tsig = 0; tsig = 0;
rrsig = 0;
dnskey = 0;
nsec3 = 0;
ds = 0;
} }
DNS_MsgInfo::~DNS_MsgInfo() DNS_MsgInfo::~DNS_MsgInfo()
@ -1063,7 +1513,7 @@ Val* DNS_MsgInfo::BuildEDNS_Val()
// Need to break the TTL field into three components: // Need to break the TTL field into three components:
// initial: [------------- ttl (32) ---------------------] // 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 ercode = (ttl >> 24) & 0xff;
unsigned int version = (ttl >> 16) & 0xff; unsigned int version = (ttl >> 16) & 0xff;
@ -1104,6 +1554,90 @@ Val* DNS_MsgInfo::BuildTSIG_Val()
return r; 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, Contents_DNS::Contents_DNS(Connection* conn, bool orig,
DNS_Interpreter* arg_interp) DNS_Interpreter* arg_interp)
: tcp::TCP_SupportAnalyzer("CONTENTS_DNS", conn, orig) : tcp::TCP_SupportAnalyzer("CONTENTS_DNS", conn, orig)

View file

@ -57,7 +57,12 @@ typedef enum {
TYPE_TKEY = 249, ///< Transaction Key (RFC 2930) TYPE_TKEY = 249, ///< Transaction Key (RFC 2930)
TYPE_TSIG = 250, ///< Transaction Signature (RFC 2845) TYPE_TSIG = 250, ///< Transaction Signature (RFC 2845)
TYPE_CAA = 257, ///< Certification Authority Authorization (RFC 6844) 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. // The following are only valid in queries.
TYPE_AXFR = 252, TYPE_AXFR = 252,
TYPE_ALL = 255, TYPE_ALL = 255,
@ -75,6 +80,33 @@ typedef enum {
DNS_ADDITIONAL, DNS_ADDITIONAL,
} DNS_AnswerType; } 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 { struct DNS_RawMsgHdr {
unsigned short id; unsigned short id;
@ -105,6 +137,42 @@ struct TSIG_DATA {
unsigned short rr_error; 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 { class DNS_MsgInfo {
public: public:
DNS_MsgInfo(DNS_RawMsgHdr* hdr, int is_query); DNS_MsgInfo(DNS_RawMsgHdr* hdr, int is_query);
@ -114,6 +182,10 @@ public:
Val* BuildAnswerVal(); Val* BuildAnswerVal();
Val* BuildEDNS_Val(); Val* BuildEDNS_Val();
Val* BuildTSIG_Val(); Val* BuildTSIG_Val();
Val* BuildRRSIG_Val();
Val* BuildDNSKEY_Val();
Val* BuildNSEC3_Val();
Val* BuildDS_Val();
int id; int id;
int opcode; ///< query type, see DNS_Opcode int opcode; ///< query type, see DNS_Opcode
@ -143,9 +215,14 @@ public:
///< for forward lookups ///< for forward lookups
// More values for spesific DNS types. // More values for spesific DNS types.
// struct EDNS_ADDITIONAL* edns; //struct EDNS_ADDITIONAL* edns;
//DNSSEC_Algo dnssec_algo;
struct TSIG_DATA* tsig; 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); uint32 ExtractLong(const u_char*& data, int& len);
void ExtractOctets(const u_char*& data, int& len, BroString** p); 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, int ParseRR_Name(DNS_MsgInfo* msg,
const u_char*& data, int& len, int rdlength, const u_char*& data, int& len, int rdlength,
const u_char* msg_start); const u_char* msg_start);
@ -218,7 +297,21 @@ protected:
int ParseRR_TSIG(DNS_MsgInfo* msg, int ParseRR_TSIG(DNS_MsgInfo* msg,
const u_char*& data, int& len, int rdlength, const u_char*& data, int& len, int rdlength,
const u_char* msg_start); 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, void SendReplyOrRejectEvent(DNS_MsgInfo* msg, EventHandlerPtr event,
const u_char*& data, int& len, const u_char*& data, int& len,
BroString* question_name); BroString* question_name);
@ -270,7 +363,6 @@ public:
void Done() override; void Done() override;
void ConnectionClosed(tcp::TCP_Endpoint* endpoint, void ConnectionClosed(tcp::TCP_Endpoint* endpoint,
tcp::TCP_Endpoint* peer, int gen_event) override; tcp::TCP_Endpoint* peer, int gen_event) override;
void ExpireTimer(double t); void ExpireTimer(double t);
static analyzer::Analyzer* Instantiate(Connection* conn) static analyzer::Analyzer* Instantiate(Connection* conn)

View file

@ -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 ## 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%); 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 ## 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 ## ``dns_*`` event that will be raised for a DNS query/reply and signals that
## all resource records have been passed on. ## all resource records have been passed on.

View file

@ -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

View file

@ -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

Binary file not shown.

Binary file not shown.

View file

@ -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

View file

@ -0,0 +1,4 @@
# @TEST-EXEC: bro -r $TRACES/nsec-test.trace %INPUT
# @TEST-EXEC: btest-diff dns.log
@load protocols/dns/auth-addl