diff --git a/CHANGES b/CHANGES index e4d7b194cf..5be56b8f18 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,27 @@ +2.0-beta-126 | 2011-12-18 15:18:05 -0800 + + * DNS updates. (Seth Hall) + + - Fixed some bugs with capturing data in the base DNS script. + + - Answers and TTLs are now vectors. + + - A warning that was being generated (dns_reply_seen_after_done) + from transaction ID reuse is fixed. + + * SSL updates. (Seth Hall) + + - Added is_orig fields to the SSL events and adapted script. + + - Added a field named last_alert to the SSL log. + + - The x509_certificate function has an is_orig field now instead + of is_server and its position in the argument list has moved. + + - A bit of reorganization and cleanup in the core analyzer. (Seth + Hall) + 2.0-beta-121 | 2011-12-18 15:10:15 -0800 * Enable warnings for malformed Broxygen xref roles. (Jon Siwek) diff --git a/VERSION b/VERSION index d0da1331e8..f9bcabd87f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0-beta-121 +2.0-beta-126 diff --git a/scripts/base/protocols/dns/main.bro b/scripts/base/protocols/dns/main.bro index c8c56bdc00..b8cfc7b44e 100644 --- a/scripts/base/protocols/dns/main.bro +++ b/scripts/base/protocols/dns/main.bro @@ -4,50 +4,50 @@ module DNS; export { redef enum Log::ID += { LOG }; - + type Info: record { - ts: time &log; - uid: string &log; - id: conn_id &log; - proto: transport_proto &log; - trans_id: count &log &optional; - query: string &log &optional; - qclass: count &log &optional; - qclass_name: string &log &optional; - qtype: count &log &optional; - qtype_name: string &log &optional; - rcode: count &log &optional; - rcode_name: string &log &optional; - QR: bool &log &default=F; - AA: bool &log &default=F; - TC: bool &log &default=F; - RD: bool &log &default=F; - RA: bool &log &default=F; - Z: count &log &default=0; - TTL: interval &log &optional; - answers: set[string] &log &optional; - + ts: time &log; + uid: string &log; + id: conn_id &log; + proto: transport_proto &log; + trans_id: count &log &optional; + query: string &log &optional; + qclass: count &log &optional; + qclass_name: string &log &optional; + qtype: count &log &optional; + qtype_name: string &log &optional; + rcode: count &log &optional; + rcode_name: string &log &optional; + QR: bool &log &default=F; + AA: bool &log &default=F; + TC: bool &log &default=F; + RD: bool &log &default=F; + RA: bool &log &default=F; + Z: count &log &default=0; + answers: vector of string &log &optional; + TTLs: vector of interval &log &optional; + ## This value indicates if this request/response pair is ready to be logged. ready: bool &default=F; total_answers: count &optional; total_replies: count &optional; }; - + type State: record { ## Indexed by query id, returns Info record corresponding to ## query/response which haven't completed yet. pending: table[count] of Info &optional; - + ## This is the list of DNS responses that have completed based on the ## number of responses declared and the number received. The contents ## of the set are transaction IDs. finished_answers: set[count] &optional; }; - + global log_dns: event(rec: Info); - + ## This is called by the specific dns_*_reply events with a "reply" which - ## may not represent the full data available from the resource record, but + ## may not represent the full data available from the resource record, but ## it's generally considered a summarization of the response(s). global do_reply: event(c: connection, msg: dns_msg, ans: dns_answer, reply: string); } @@ -58,11 +58,11 @@ redef record connection += { }; # DPD configuration. -redef capture_filters += { +redef capture_filters += { ["dns"] = "port 53", ["mdns"] = "udp and port 5353", ["llmns"] = "udp and port 5355", - ["netbios-ns"] = "udp port 137", + ["netbios-ns"] = "udp port 137", }; const dns_ports = { 53/udp, 53/tcp, 137/udp, 5353/udp, 5355/udp }; @@ -89,7 +89,7 @@ function new_session(c: connection, trans_id: count): Info state$finished_answers=set(); c$dns_state = state; } - + local info: Info; info$ts = network_time(); info$id = c$id; @@ -102,23 +102,29 @@ function new_session(c: connection, trans_id: count): Info function set_session(c: connection, msg: dns_msg, is_query: bool) { if ( ! c?$dns_state || msg$id !in c$dns_state$pending ) + { c$dns_state$pending[msg$id] = new_session(c, msg$id); - + # Try deleting this transaction id from the set of finished answers. + # Sometimes hosts will reuse ports and transaction ids and this should + # be considered to be a legit scenario (although bad practice). + delete c$dns_state$finished_answers[msg$id]; + } + c$dns = c$dns_state$pending[msg$id]; c$dns$rcode = msg$rcode; c$dns$rcode_name = base_errors[msg$rcode]; - + if ( ! is_query ) { if ( ! c$dns?$total_answers ) c$dns$total_answers = msg$num_answers; - - if ( c$dns?$total_replies && + + if ( c$dns?$total_replies && c$dns$total_replies != msg$num_answers + msg$num_addl + msg$num_auth ) { - event conn_weird("dns_changed_number_of_responses", c, - fmt("The declared number of responses changed from %d to %d", + event conn_weird("dns_changed_number_of_responses", c, + fmt("The declared number of responses changed from %d to %d", c$dns$total_replies, msg$num_answers + msg$num_addl + msg$num_auth)); } @@ -129,27 +135,30 @@ function set_session(c: connection, msg: dns_msg, is_query: bool) } } } - + event DNS::do_reply(c: connection, msg: dns_msg, ans: dns_answer, reply: string) &priority=5 { set_session(c, msg, F); - c$dns$AA = msg$AA; - c$dns$RA = msg$RA; - c$dns$TTL = ans$TTL; - if ( ans$answer_type == DNS_ANS ) { + c$dns$AA = msg$AA; + c$dns$RA = msg$RA; + if ( msg$id in c$dns_state$finished_answers ) event conn_weird("dns_reply_seen_after_done", c, ""); - + if ( reply != "" ) { if ( ! c$dns?$answers ) - c$dns$answers = set(); - add c$dns$answers[reply]; + c$dns$answers = vector(); + c$dns$answers[|c$dns$answers|] = reply; + + if ( ! c$dns?$TTLs ) + c$dns$TTLs = vector(); + c$dns$TTLs[|c$dns$TTLs|] = ans$TTL; } - + if ( c$dns?$answers && |c$dns$answers| == c$dns$total_answers ) { add c$dns_state$finished_answers[c$dns$trans_id]; @@ -158,13 +167,12 @@ event DNS::do_reply(c: connection, msg: dns_msg, ans: dns_answer, reply: string) } } } - + event DNS::do_reply(c: connection, msg: dns_msg, ans: dns_answer, reply: string) &priority=-5 { if ( c$dns$ready ) { Log::write(DNS::LOG, c$dns); - add c$dns_state$finished_answers[c$dns$trans_id]; # This record is logged and no longer pending. delete c$dns_state$pending[c$dns$trans_id]; } @@ -173,41 +181,41 @@ event DNS::do_reply(c: connection, msg: dns_msg, ans: dns_answer, reply: string) event dns_request(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count) &priority=5 { set_session(c, msg, T); - + c$dns$RD = msg$RD; c$dns$TC = msg$TC; c$dns$qclass = qclass; c$dns$qclass_name = classes[qclass]; c$dns$qtype = qtype; c$dns$qtype_name = query_types[qtype]; - + # Decode netbios name queries - # Note: I'm ignoring the name type for now. Not sure if this should be + # Note: I'm ignoring the name type for now. Not sure if this should be # worked into the query/response in some fashion. if ( c$id$resp_p == 137/udp ) query = decode_netbios_name(query); c$dns$query = query; - + c$dns$Z = msg$Z; } - + event dns_A_reply(c: connection, msg: dns_msg, ans: dns_answer, a: addr) &priority=5 { event DNS::do_reply(c, msg, ans, fmt("%s", a)); } - + event dns_TXT_reply(c: connection, msg: dns_msg, ans: dns_answer, str: string) &priority=5 { event DNS::do_reply(c, msg, ans, str); } - -event dns_AAAA_reply(c: connection, msg: dns_msg, ans: dns_answer, a: addr, + +event dns_AAAA_reply(c: connection, msg: dns_msg, ans: dns_answer, a: addr, astr: string) &priority=5 { # TODO: What should we do with astr? event DNS::do_reply(c, msg, ans, fmt("%s", a)); } - + event dns_NS_reply(c: connection, msg: dns_msg, ans: dns_answer, name: string) &priority=5 { event DNS::do_reply(c, msg, ans, name); @@ -223,12 +231,12 @@ event dns_MX_reply(c: connection, msg: dns_msg, ans: dns_answer, name: string, { event DNS::do_reply(c, msg, ans, name); } - + event dns_PTR_reply(c: connection, msg: dns_msg, ans: dns_answer, name: string) &priority=5 { event DNS::do_reply(c, msg, ans, name); } - + event dns_SOA_reply(c: connection, msg: dns_msg, ans: dns_answer, soa: dns_soa) &priority=5 { event DNS::do_reply(c, msg, ans, soa$mname); @@ -238,7 +246,7 @@ event dns_WKS_reply(c: connection, msg: dns_msg, ans: dns_answer) &priority=5 { event DNS::do_reply(c, msg, ans, ""); } - + event dns_SRV_reply(c: connection, msg: dns_msg, ans: dns_answer) &priority=5 { event DNS::do_reply(c, msg, ans, ""); @@ -247,17 +255,17 @@ event dns_SRV_reply(c: connection, msg: dns_msg, ans: dns_answer) &priority=5 # TODO: figure out how to handle these #event dns_EDNS(c: connection, msg: dns_msg, ans: dns_answer) # { -# +# # } # #event dns_EDNS_addl(c: connection, msg: dns_msg, ans: dns_edns_additional) # { -# +# # } # #event dns_TSIG_addl(c: connection, msg: dns_msg, ans: dns_tsig_additional) # { -# +# # } @@ -271,10 +279,10 @@ event connection_state_remove(c: connection) &priority=-5 { if ( ! c?$dns_state ) return; - - # If Bro is expiring state, we should go ahead and log all unlogged + + # If Bro is expiring state, we should go ahead and log all unlogged # request/response pairs now. for ( trans_id in c$dns_state$pending ) Log::write(DNS::LOG, c$dns_state$pending[trans_id]); } - + diff --git a/testing/btest/Baseline/scripts.policy.protocols.dns.event-priority/dns.log b/testing/btest/Baseline/scripts.policy.protocols.dns.event-priority/dns.log index 945960e03e..78e61070d7 100644 --- a/testing/btest/Baseline/scripts.policy.protocols.dns.event-priority/dns.log +++ b/testing/btest/Baseline/scripts.policy.protocols.dns.event-priority/dns.log @@ -1,5 +1,5 @@ #separator \x09 #path dns -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id query qclass qclass_name qtype qtype_name rcode rcode_name QR AA TC RD RA Z TTL answers auth addl -#types time string addr port addr port enum count string count string count string count string bool bool bool bool bool count interval table table table -930613226.529070 UWkUyAuUGXf 212.180.42.100 25000 131.243.64.3 53 tcp 34798 - - - - - 0 NOERROR F F F F T 0 31337.000000 4.3.2.1 - - +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id query qclass qclass_name qtype qtype_name rcode rcode_name QR AA TC RD RA Z answers TTLs auth addl +#types time string addr port addr port enum count string count string count string count string bool bool bool bool bool count vector vector table table +930613226.529070 UWkUyAuUGXf 212.180.42.100 25000 131.243.64.3 53 tcp 34798 - - - - - 0 NOERROR F F F F T 0 4.3.2.1 31337.000000 - -