mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Merge remote-tracking branch 'origin/topic/awelzel/dns-naming-authority-pointer'
* origin/topic/awelzel/dns-naming-authority-pointer: DNS: Implement NAPTR RR support DNS: Move extract_char_string() helper around
This commit is contained in:
commit
fbeb3adfe6
13 changed files with 157 additions and 25 deletions
|
@ -11,10 +11,37 @@
|
|||
#include "zeek/Event.h"
|
||||
#include "zeek/NetVar.h"
|
||||
#include "zeek/RunState.h"
|
||||
#include "zeek/Val.h"
|
||||
#include "zeek/ZeekString.h"
|
||||
#include "zeek/analyzer/protocol/dns/events.bif.h"
|
||||
#include "zeek/session/Manager.h"
|
||||
|
||||
namespace {
|
||||
zeek::StringValPtr extract_char_string(zeek::analyzer::Analyzer* analyzer, const u_char*& data, int& len, int& rdlen) {
|
||||
if ( rdlen <= 0 )
|
||||
return nullptr;
|
||||
|
||||
uint8_t str_size = data[0];
|
||||
|
||||
--rdlen;
|
||||
--len;
|
||||
++data;
|
||||
|
||||
if ( str_size > rdlen ) {
|
||||
analyzer->Weird("DNS_TXT_char_str_past_rdlen");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto rval = zeek::make_intrusive<zeek::StringVal>(str_size, reinterpret_cast<const char*>(data));
|
||||
|
||||
rdlen -= str_size;
|
||||
len -= str_size;
|
||||
data += str_size;
|
||||
|
||||
return rval;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace zeek::analyzer::dns {
|
||||
|
||||
namespace detail {
|
||||
|
@ -273,6 +300,8 @@ bool DNS_Interpreter::ParseAnswer(detail::DNS_MsgInfo* msg, const u_char*& data,
|
|||
|
||||
break;
|
||||
|
||||
case detail::TYPE_NAPTR: status = ParseRR_NAPTR(msg, data, len, rdlength, msg_start); break;
|
||||
|
||||
case detail::TYPE_EDNS: status = ParseRR_EDNS(msg, data, len, rdlength, msg_start); break;
|
||||
|
||||
case detail::TYPE_TKEY: status = ParseRR_TKEY(msg, data, len, rdlength, msg_start); break;
|
||||
|
@ -602,6 +631,50 @@ bool DNS_Interpreter::ParseRR_SRV(detail::DNS_MsgInfo* msg, const u_char*& data,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DNS_Interpreter::ParseRR_NAPTR(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength,
|
||||
const u_char* msg_start) {
|
||||
zeek_uint_t order = ExtractShort(data, len);
|
||||
zeek_uint_t preference = ExtractShort(data, len);
|
||||
rdlength -= 4;
|
||||
|
||||
if ( len <= 0 || rdlength <= 0 ) {
|
||||
analyzer->AnalyzerViolation("DNS_NAPTR_too_short");
|
||||
return false;
|
||||
}
|
||||
|
||||
// These all check rdlength and return nullptr if there's not enough data available.
|
||||
auto flags = extract_char_string(analyzer, data, len, rdlength);
|
||||
auto service = extract_char_string(analyzer, data, len, rdlength);
|
||||
auto regexp = extract_char_string(analyzer, data, len, rdlength);
|
||||
|
||||
// The replacement string is a name. Compression shouldn't be used, but doesn't seem
|
||||
// we have a helper that would allow to control this.
|
||||
u_char replacement[513];
|
||||
int replacement_len = sizeof(replacement) - 1;
|
||||
u_char* replacement_end = ExtractName(data, len, replacement, replacement_len, msg_start, false);
|
||||
|
||||
if ( ! flags || ! service || ! regexp || ! replacement_end ) {
|
||||
analyzer->AnalyzerViolation("DNS_NAPTR_RR_too_short");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( dns_NAPTR_reply && ! msg->skip_event ) {
|
||||
static auto dns_naptr_rr = id::find_type<RecordType>("dns_naptr_rr");
|
||||
auto r = make_intrusive<RecordVal>(dns_naptr_rr);
|
||||
|
||||
r->Assign(0, order);
|
||||
r->Assign(1, preference);
|
||||
r->Assign(2, std::move(flags));
|
||||
r->Assign(3, std::move(service));
|
||||
r->Assign(4, std::move(regexp));
|
||||
r->Assign(5, zeek::make_intrusive<StringVal>(new String(replacement, replacement_end - replacement, true)));
|
||||
|
||||
analyzer->EnqueueConnEvent(dns_NAPTR_reply, analyzer->ConnVal(), msg->BuildHdrVal(), msg->BuildAnswerVal(), r);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DNS_Interpreter::ParseRR_EDNS(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength,
|
||||
const u_char* msg_start) {
|
||||
if ( dns_EDNS_addl && ! msg->skip_event )
|
||||
|
@ -1413,30 +1486,6 @@ bool DNS_Interpreter::ParseRR_WKS(detail::DNS_MsgInfo* msg, const u_char*& data,
|
|||
return true;
|
||||
}
|
||||
|
||||
static StringValPtr extract_char_string(analyzer::Analyzer* analyzer, const u_char*& data, int& len, int& rdlen) {
|
||||
if ( rdlen <= 0 )
|
||||
return nullptr;
|
||||
|
||||
uint8_t str_size = data[0];
|
||||
|
||||
--rdlen;
|
||||
--len;
|
||||
++data;
|
||||
|
||||
if ( str_size > rdlen ) {
|
||||
analyzer->Weird("DNS_TXT_char_str_past_rdlen");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto rval = make_intrusive<StringVal>(str_size, reinterpret_cast<const char*>(data));
|
||||
|
||||
rdlen -= str_size;
|
||||
len -= str_size;
|
||||
data += str_size;
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool DNS_Interpreter::ParseRR_HINFO(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength) {
|
||||
if ( ! dns_HINFO_reply || msg->skip_event ) {
|
||||
data += rdlength;
|
||||
|
|
|
@ -364,6 +364,7 @@ protected:
|
|||
bool ParseRR_MX(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start);
|
||||
bool ParseRR_NBS(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start);
|
||||
bool ParseRR_SRV(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start);
|
||||
bool ParseRR_NAPTR(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start);
|
||||
bool ParseRR_EDNS(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start);
|
||||
bool ParseRR_EDNS_ECS(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength,
|
||||
const u_char* msg_start);
|
||||
|
|
|
@ -467,6 +467,23 @@ event dns_CAA_reply%(c: connection, msg: dns_msg, ans: dns_answer, flags: count,
|
|||
## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth
|
||||
event dns_SRV_reply%(c: connection, msg: dns_msg, ans: dns_answer, target: string, priority: count, weight: count, p: count%);
|
||||
|
||||
## Generated for DNS replies of type *NAPTR*. 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.
|
||||
##
|
||||
## naptr: The parsed RDATA of NAPTR type record.
|
||||
##
|
||||
## .. 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_TSIG_addl dns_TXT_reply dns_SPF_reply dns_WKS_reply dns_SRV_reply dns_end
|
||||
event dns_NAPTR_reply%(c: connection, msg: dns_msg, ans: dns_answer, naptr: dns_naptr_rr%);
|
||||
|
||||
## Generated on DNS reply resource records when the type of record is not one
|
||||
## that Zeek knows how to parse and generate another more specific event.
|
||||
##
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue