mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 15:48:19 +00:00
Merge branch 'master' into topic/script-reference
Conflicts: aux/broccoli aux/broctl scripts/base/frameworks/notice/main.bro src/event.bif
This commit is contained in:
commit
a4117016e9
124 changed files with 1145 additions and 562 deletions
|
@ -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]);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,6 +13,44 @@ export {
|
|||
[TLSv11] = "TLSv11",
|
||||
} &default="UNKNOWN";
|
||||
|
||||
const alert_levels: table[count] of string = {
|
||||
[1] = "warning",
|
||||
[2] = "fatal",
|
||||
} &default=function(i: count):string { return fmt("unknown-%d", i); };
|
||||
|
||||
const alert_descriptions: table[count] of string = {
|
||||
[0] = "close_notify",
|
||||
[10] = "unexpected_message",
|
||||
[20] = "bad_record_mac",
|
||||
[21] = "decryption_failed",
|
||||
[22] = "record_overflow",
|
||||
[30] = "decompression_failure",
|
||||
[40] = "handshake_failure",
|
||||
[41] = "no_certificate",
|
||||
[42] = "bad_certificate",
|
||||
[43] = "unsupported_certificate",
|
||||
[44] = "certificate_revoked",
|
||||
[45] = "certificate_expired",
|
||||
[46] = "certificate_unknown",
|
||||
[47] = "illegal_parameter",
|
||||
[48] = "unknown_ca",
|
||||
[49] = "access_denied",
|
||||
[50] = "decode_error",
|
||||
[51] = "decrypt_error",
|
||||
[60] = "export_restriction",
|
||||
[70] = "protocol_version",
|
||||
[71] = "insufficient_security",
|
||||
[80] = "internal_error",
|
||||
[90] = "user_canceled",
|
||||
[100] = "no_renegotiation",
|
||||
[110] = "unsupported_extension",
|
||||
[111] = "certificate_unobtainable",
|
||||
[112] = "unrecognized_name",
|
||||
[113] = "bad_certificate_status_response",
|
||||
[114] = "bad_certificate_hash_value",
|
||||
[115] = "unknown_psk_identity",
|
||||
} &default=function(i: count):string { return fmt("unknown-%d", i); };
|
||||
|
||||
# http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xml
|
||||
const extensions: table[count] of string = {
|
||||
[0] = "server_name",
|
||||
|
@ -526,8 +564,7 @@ export {
|
|||
[30] = "akid issuer serial mismatch",
|
||||
[31] = "keyusage no certsign",
|
||||
[32] = "unable to get crl issuer",
|
||||
[33] = "unhandled critical extension"
|
||||
|
||||
[33] = "unhandled critical extension",
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -16,32 +16,33 @@ export {
|
|||
subject: string &log &optional;
|
||||
not_valid_before: time &log &optional;
|
||||
not_valid_after: time &log &optional;
|
||||
|
||||
last_alert: string &log &optional;
|
||||
|
||||
cert: string &optional;
|
||||
cert_chain: vector of string &optional;
|
||||
|
||||
|
||||
## This stores the analyzer id used for the analyzer instance attached
|
||||
## to each connection. It is not used for logging since it's a
|
||||
## to each connection. It is not used for logging since it's a
|
||||
## meaningless arbitrary number.
|
||||
analyzer_id: count &optional;
|
||||
};
|
||||
|
||||
|
||||
## This is where the default root CA bundle is defined. By loading the
|
||||
## mozilla-ca-list.bro script it will be set to Mozilla's root CA list.
|
||||
const root_certs: table[string] of string = {} &redef;
|
||||
|
||||
## If true, detach the SSL analyzer from the connection to prevent
|
||||
|
||||
## If true, detach the SSL analyzer from the connection to prevent
|
||||
## continuing to process encrypted traffic. Helps with performance
|
||||
## (especially with large file transfers).
|
||||
const disable_analyzer_after_detection = T &redef;
|
||||
|
||||
|
||||
## The openssl command line utility. If it's in the path the default
|
||||
## value will work, otherwise a full path string can be supplied for the
|
||||
## utility.
|
||||
const openssl_util = "openssl" &redef;
|
||||
|
||||
|
||||
global log_ssl: event(rec: Info);
|
||||
|
||||
|
||||
const ports = {
|
||||
443/tcp, 563/tcp, 585/tcp, 614/tcp, 636/tcp,
|
||||
989/tcp, 990/tcp, 992/tcp, 993/tcp, 995/tcp, 5223/tcp
|
||||
|
@ -86,7 +87,7 @@ function set_session(c: connection)
|
|||
if ( ! c?$ssl )
|
||||
c$ssl = [$ts=network_time(), $uid=c$uid, $id=c$id, $cert_chain=vector()];
|
||||
}
|
||||
|
||||
|
||||
function finish(c: connection)
|
||||
{
|
||||
Log::write(SSL::LOG, c$ssl);
|
||||
|
@ -98,29 +99,33 @@ function finish(c: connection)
|
|||
event ssl_client_hello(c: connection, version: count, possible_ts: time, session_id: string, ciphers: count_set) &priority=5
|
||||
{
|
||||
set_session(c);
|
||||
|
||||
|
||||
# Save the session_id if there is one set.
|
||||
if ( session_id != /^\x00{32}$/ )
|
||||
c$ssl$session_id = bytestring_to_hexstr(session_id);
|
||||
}
|
||||
|
||||
|
||||
event ssl_server_hello(c: connection, version: count, possible_ts: time, session_id: string, cipher: count, comp_method: count) &priority=5
|
||||
{
|
||||
set_session(c);
|
||||
|
||||
|
||||
c$ssl$version = version_strings[version];
|
||||
c$ssl$cipher = cipher_desc[cipher];
|
||||
}
|
||||
|
||||
event x509_certificate(c: connection, cert: X509, is_server: bool, chain_idx: count, chain_len: count, der_cert: string) &priority=5
|
||||
event x509_certificate(c: connection, is_orig: bool, cert: X509, chain_idx: count, chain_len: count, der_cert: string) &priority=5
|
||||
{
|
||||
set_session(c);
|
||||
|
||||
|
||||
# We aren't doing anything with client certificates yet.
|
||||
if ( is_orig )
|
||||
return;
|
||||
|
||||
if ( chain_idx == 0 )
|
||||
{
|
||||
# Save the primary cert.
|
||||
c$ssl$cert = der_cert;
|
||||
|
||||
|
||||
# Also save other certificate information about the primary cert.
|
||||
c$ssl$subject = cert$subject;
|
||||
c$ssl$not_valid_before = cert$not_valid_before;
|
||||
|
@ -132,20 +137,27 @@ event x509_certificate(c: connection, cert: X509, is_server: bool, chain_idx: co
|
|||
c$ssl$cert_chain[|c$ssl$cert_chain|] = der_cert;
|
||||
}
|
||||
}
|
||||
|
||||
event ssl_extension(c: connection, code: count, val: string) &priority=5
|
||||
|
||||
event ssl_extension(c: connection, is_orig: bool, code: count, val: string) &priority=5
|
||||
{
|
||||
set_session(c);
|
||||
|
||||
if ( extensions[code] == "server_name" )
|
||||
|
||||
if ( is_orig && extensions[code] == "server_name" )
|
||||
c$ssl$server_name = sub_bytes(val, 6, |val|);
|
||||
}
|
||||
|
||||
|
||||
event ssl_alert(c: connection, is_orig: bool, level: count, desc: count) &priority=5
|
||||
{
|
||||
set_session(c);
|
||||
|
||||
c$ssl$last_alert = alert_descriptions[desc];
|
||||
}
|
||||
|
||||
event ssl_established(c: connection) &priority=5
|
||||
{
|
||||
set_session(c);
|
||||
}
|
||||
|
||||
|
||||
event ssl_established(c: connection) &priority=-5
|
||||
{
|
||||
finish(c);
|
||||
|
@ -163,4 +175,4 @@ event protocol_violation(c: connection, atype: count, aid: count,
|
|||
{
|
||||
if ( c?$ssl )
|
||||
finish(c);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue