Merge branch 'dns-original-query-case' of https://github.com/rvictory/zeek

Changes during merge
- Changed the policy script to use an event handler that behaves
  for like the base script: &priority=5, msg$opcode != early-out,
  no record field existence checks
- Also extended dns_query_reply event with original_query param
- Removed ExtractName overload, and just use default param

* 'dns-original-query-case' of https://github.com/rvictory/zeek:
  Fixed some places where tabs became spaces
  Stricter checking if we have a dns field on the connection being processed
  Modified the DNS protocol analyzer to add a new parameter to the dns_request event which includes the DNS query in its original case. Added a policy script that will add the original_case to the dns.log file as well. Created new btests to test both.
This commit is contained in:
Jon Siwek 2020-06-25 23:33:14 -07:00
commit 00a4865885
14 changed files with 87 additions and 18 deletions

View file

@ -171,7 +171,7 @@ bool DNS_Interpreter::ParseQuestion(DNS_MsgInfo* msg,
u_char name[513];
int name_len = sizeof(name) - 1;
u_char* name_end = ExtractName(data, len, name, name_len, msg_start);
u_char* name_end = ExtractName(data, len, name, name_len, msg_start, false);
if ( ! name_end )
return false;
@ -196,9 +196,16 @@ bool DNS_Interpreter::ParseQuestion(DNS_MsgInfo* msg,
if ( dns_event && ! msg->skip_event )
{
BroString* question_name =
new BroString(name, name_end - name, true);
SendReplyOrRejectEvent(msg, dns_event, data, len, question_name);
BroString* original_name = new BroString(name, name_end - name, true);
// Downcase the Name to normalize it
for ( u_char* np = name; np < name_end; ++np )
if ( isupper(*np) )
*np = tolower(*np);
BroString* question_name = new BroString(name, name_end - name, true);
SendReplyOrRejectEvent(msg, dns_event, data, len, question_name, original_name);
}
else
{
@ -355,7 +362,7 @@ bool DNS_Interpreter::ParseAnswer(DNS_MsgInfo* msg,
u_char* DNS_Interpreter::ExtractName(const u_char*& data, int& len,
u_char* name, int name_len,
const u_char* msg_start)
const u_char* msg_start, bool downcase)
{
u_char* name_start = name;
@ -375,9 +382,10 @@ u_char* DNS_Interpreter::ExtractName(const u_char*& data, int& len,
}
// Convert labels to lower case for consistency.
for ( u_char* np = name_start; np < name; ++np )
if ( isupper(*np) )
*np = tolower(*np);
if ( downcase )
for ( u_char* np = name_start; np < name; ++np )
if ( isupper(*np) )
*np = tolower(*np);
return name;
}
@ -1388,7 +1396,8 @@ bool DNS_Interpreter::ParseRR_CAA(DNS_MsgInfo* msg,
void DNS_Interpreter::SendReplyOrRejectEvent(DNS_MsgInfo* msg,
EventHandlerPtr event,
const u_char*& data, int& len,
BroString* question_name)
BroString* question_name,
BroString* original_name)
{
RR_Type qtype = RR_Type(ExtractShort(data, len));
int qclass = ExtractShort(data, len);
@ -1400,7 +1409,8 @@ void DNS_Interpreter::SendReplyOrRejectEvent(DNS_MsgInfo* msg,
msg->BuildHdrVal(),
make_intrusive<StringVal>(question_name),
val_mgr->Count(qtype),
val_mgr->Count(qclass)
val_mgr->Count(qclass),
make_intrusive<StringVal>(original_name)
);
}

View file

@ -242,7 +242,7 @@ protected:
u_char* ExtractName(const u_char*& data, int& len,
u_char* label, int label_len,
const u_char* msg_start);
const u_char* msg_start, bool downcase = true);
bool ExtractLabel(const u_char*& data, int& len,
u_char*& label, int& label_len,
const u_char* msg_start);
@ -308,7 +308,7 @@ protected:
const u_char* msg_start);
void SendReplyOrRejectEvent(DNS_MsgInfo* msg, EventHandlerPtr event,
const u_char*& data, int& len,
BroString* question_name);
BroString* question_name, BroString* original_name);
analyzer::Analyzer* analyzer;
bool first_message;

View file

@ -34,12 +34,14 @@ event dns_message%(c: connection, is_orig: bool, msg: dns_msg, len: count%);
##
## msg: The parsed DNS message header.
##
## query: The queried name.
## query: The queried name (normalized to all lowercase).
##
## qtype: The queried resource record type.
##
## qclass: The queried resource record class.
##
## original_query: The queried name, with the original case kept intact
##
## .. zeek:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl
## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply
## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_SPF_reply dns_WKS_reply dns_end
@ -47,6 +49,7 @@ event dns_message%(c: connection, is_orig: bool, msg: dns_msg, len: count%);
## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply
## dns_rejected dns_max_queries dns_session_timeout dns_skip_addl
## dns_skip_all_addl dns_skip_all_auth dns_skip_auth
event dns_request%(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count, original_query: string%);
event dns_request%(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count%);
## Generated for DNS replies that reject a query. This event is raised if a DNS
@ -63,12 +66,14 @@ event dns_request%(c: connection, msg: dns_msg, query: string, qtype: count, qcl
##
## msg: The parsed DNS message header.
##
## query: The queried name.
## query: The queried name (normalized to all lowercase).
##
## qtype: The queried resource record type.
##
## qclass: The queried resource record class.
##
## original_query: The queried name, with the original case kept intact
##
## .. zeek:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl
## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply
## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_SPF_reply dns_WKS_reply dns_end
@ -76,6 +81,7 @@ event dns_request%(c: connection, msg: dns_msg, query: string, qtype: count, qcl
## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply
## dns_request dns_max_queries dns_session_timeout dns_skip_addl
## dns_skip_all_addl dns_skip_all_auth dns_skip_auth
event dns_rejected%(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count, original_query: string%);
event dns_rejected%(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count%);
## Generated for each entry in the Question section of a DNS reply.
@ -95,6 +101,8 @@ event dns_rejected%(c: connection, msg: dns_msg, query: string, qtype: count, qc
##
## qclass: The queried resource record class.
##
## original_query: The queried name, with the original case kept intact
##
## .. zeek:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl
## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply
## dns_SRV_reply dns_TSIG_addl dns_TXT_reply dns_SPF_reply dns_WKS_reply dns_end
@ -102,6 +110,8 @@ event dns_rejected%(c: connection, msg: dns_msg, query: string, qtype: count, qc
## dns_mapping_unverified dns_mapping_valid dns_message dns_rejected
## dns_request dns_max_queries dns_session_timeout dns_skip_addl
## dns_skip_all_addl dns_skip_all_auth dns_skip_auth
event dns_query_reply%(c: connection, msg: dns_msg, query: string,
qtype: count, qclass: count, original_query: string%);
event dns_query_reply%(c: connection, msg: dns_msg, query: string,
qtype: count, qclass: count%);