mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Merge branch 'master' of https://github.com/FlyingWithJerome/zeek
Merge includes small changes, e.g. fixing the comsumption of remaining raw data. * 'master' of https://github.com/FlyingWithJerome/zeek: remove excussive fields in dns_svcb_rr address code reviews (formatting and type and intrusiveptr) newlines at the end of test outputs lazy commit use tabs in init-bare.zeek add svcb test case add a dns https test case remove test logs fix a few syntax errors initial commit for SVCB/HTTPS records
This commit is contained in:
commit
303e84ad86
14 changed files with 180 additions and 1 deletions
4
CHANGES
4
CHANGES
|
@ -1,3 +1,7 @@
|
||||||
|
4.2.0-dev.271 | 2021-10-19 14:54:56 +0200
|
||||||
|
|
||||||
|
* Add parsing of DNS SVCB/HTTPS records (FlyingWithJerome)
|
||||||
|
|
||||||
4.2.0-dev.260 | 2021-10-15 09:45:45 +0100
|
4.2.0-dev.260 | 2021-10-15 09:45:45 +0100
|
||||||
|
|
||||||
* logging/writers/ascii: shadow files: Add fsync() before rename(). This
|
* logging/writers/ascii: shadow files: Add fsync() before rename(). This
|
||||||
|
|
3
NEWS
3
NEWS
|
@ -35,6 +35,9 @@ New Functionality
|
||||||
specifying ``-O ZAM`` on the command line. See
|
specifying ``-O ZAM`` on the command line. See
|
||||||
``src/script_opt/ZAM/README.md`` for more information.
|
``src/script_opt/ZAM/README.md`` for more information.
|
||||||
|
|
||||||
|
- The DNS analyzer has initial support for the SVCB and HTTPS types. The new events
|
||||||
|
are ``dns_SVCB`` and ``dns_HTTPS``.
|
||||||
|
|
||||||
Changed Functionality
|
Changed Functionality
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
4.2.0-dev.260
|
4.2.0-dev.271
|
||||||
|
|
|
@ -3884,6 +3884,14 @@ type dns_loc_rr: record {
|
||||||
is_query: count; ##< The RR is a query/Response.
|
is_query: count; ##< The RR is a query/Response.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
## DNS SVCB and HTTPS RRs
|
||||||
|
##
|
||||||
|
## .. zeek:see:: dns_SVCB dns_HTTPS
|
||||||
|
type dns_svcb_rr: record {
|
||||||
|
svc_priority: count; ##< Service priority for the current record, 0 indicates that this record is in AliasMode and cannot carry svc_params; otherwise this is in ServiceMode, and may include svc_params
|
||||||
|
target_name: string; ##< Target name, the hostname of the service endpoint.
|
||||||
|
};
|
||||||
|
|
||||||
# DNS answer types.
|
# DNS answer types.
|
||||||
#
|
#
|
||||||
# .. zeek:see:: dns_answerr
|
# .. zeek:see:: dns_answerr
|
||||||
|
|
|
@ -172,4 +172,15 @@ export {
|
||||||
[4] = "SHA384",
|
[4] = "SHA384",
|
||||||
} &default = function(n: count): string { return fmt("digest-%d", n); };
|
} &default = function(n: count): string { return fmt("digest-%d", n); };
|
||||||
|
|
||||||
|
## SVCB/HTTPS SvcParam keys, as defined in
|
||||||
|
## https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-07.txt, sec 14.3.2
|
||||||
|
const svcparam_keys = {
|
||||||
|
[0] = "mandatory",
|
||||||
|
[1] = "alpn",
|
||||||
|
[2] = "no-default-alpn",
|
||||||
|
[3] = "port",
|
||||||
|
[4] = "ipv4hint",
|
||||||
|
[5] = "ech",
|
||||||
|
[6] = "ipv6hint",
|
||||||
|
} &default = function(n: count): string { return fmt("key-%d", n); };
|
||||||
}
|
}
|
||||||
|
|
|
@ -345,6 +345,14 @@ bool DNS_Interpreter::ParseAnswer(detail::DNS_MsgInfo* msg, const u_char*& data,
|
||||||
status = ParseRR_LOC(msg, data, len, rdlength, msg_start);
|
status = ParseRR_LOC(msg, data, len, rdlength, msg_start);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case detail::TYPE_SVCB:
|
||||||
|
status = ParseRR_SVCB(msg, data, len, rdlength, msg_start, TYPE_SVCB);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case detail::TYPE_HTTPS:
|
||||||
|
status = ParseRR_SVCB(msg, data, len, rdlength, msg_start, TYPE_HTTPS);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
if ( dns_unknown_reply && ! msg->skip_event )
|
if ( dns_unknown_reply && ! msg->skip_event )
|
||||||
|
@ -1687,6 +1695,65 @@ bool DNS_Interpreter::ParseRR_CAA(detail::DNS_MsgInfo* msg, const u_char*& data,
|
||||||
return rdlength == 0;
|
return rdlength == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DNS_Interpreter::ParseRR_SVCB(detail::DNS_MsgInfo* msg, const u_char*& data, int& len,
|
||||||
|
int rdlength, const u_char* msg_start, const RR_Type& svcb_type)
|
||||||
|
{
|
||||||
|
const u_char* data_start = data;
|
||||||
|
// the smallest SVCB/HTTPS rr is 3 bytes:
|
||||||
|
// the first 2 bytes are for the svc priority, and the third byte is root (0x0)
|
||||||
|
if ( len < 3 )
|
||||||
|
{
|
||||||
|
analyzer->Weird("DNS_SVBC_wrong_length");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t svc_priority = ExtractShort(data, len);
|
||||||
|
|
||||||
|
u_char target_name[513];
|
||||||
|
int name_len = sizeof(target_name) - 1;
|
||||||
|
u_char* name_end = ExtractName(data, len, target_name, name_len, msg_start, false);
|
||||||
|
if ( ! name_end )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// target name can be root - in this case the alternative endpoint is
|
||||||
|
// qname itself. make sure that we print "." instead of an empty string
|
||||||
|
if ( name_end - target_name == 0 )
|
||||||
|
{
|
||||||
|
target_name[0] = '.';
|
||||||
|
target_name[1] = '\0';
|
||||||
|
name_end = target_name+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SVCB_DATA svcb_data = {
|
||||||
|
.svc_priority = svc_priority,
|
||||||
|
.target_name = make_intrusive<StringVal>(new String(target_name, name_end - target_name, true)),
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: parse svcparams
|
||||||
|
// we consume all the remaining raw data (svc params) but do nothing.
|
||||||
|
// this should be removed if the svc param parser is ready
|
||||||
|
std::ptrdiff_t parsed_bytes = data - data_start;
|
||||||
|
if ( parsed_bytes < rdlength )
|
||||||
|
{
|
||||||
|
len -= ( rdlength - parsed_bytes );
|
||||||
|
data += ( rdlength - parsed_bytes );
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( svcb_type )
|
||||||
|
{
|
||||||
|
case detail::TYPE_SVCB:
|
||||||
|
analyzer->EnqueueConnEvent(dns_SVCB, analyzer->ConnVal(), msg->BuildHdrVal(),
|
||||||
|
msg->BuildAnswerVal(), msg->BuildSVCB_Val(svcb_data));
|
||||||
|
break;
|
||||||
|
case detail::TYPE_HTTPS:
|
||||||
|
analyzer->EnqueueConnEvent(dns_HTTPS, analyzer->ConnVal(), msg->BuildHdrVal(),
|
||||||
|
msg->BuildAnswerVal(), msg->BuildSVCB_Val(svcb_data));
|
||||||
|
break;
|
||||||
|
default: break; // unreachable. for suppressing compiler warnings.
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void DNS_Interpreter::SendReplyOrRejectEvent(detail::DNS_MsgInfo* msg, EventHandlerPtr event,
|
void DNS_Interpreter::SendReplyOrRejectEvent(detail::DNS_MsgInfo* msg, EventHandlerPtr event,
|
||||||
const u_char*& data, int& len, String* question_name,
|
const u_char*& data, int& len, String* question_name,
|
||||||
String* original_name)
|
String* original_name)
|
||||||
|
@ -1987,6 +2054,18 @@ RecordValPtr DNS_MsgInfo::BuildLOC_Val(LOC_DATA* loc)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RecordValPtr DNS_MsgInfo::BuildSVCB_Val(const SVCB_DATA& svcb)
|
||||||
|
{
|
||||||
|
static auto dns_svcb_rr = id::find_type<RecordType>("dns_svcb_rr");
|
||||||
|
auto r = make_intrusive<RecordVal>(dns_svcb_rr);
|
||||||
|
|
||||||
|
r->Assign(0, svcb.svc_priority);
|
||||||
|
r->Assign(1, svcb.target_name);
|
||||||
|
|
||||||
|
// TODO: assign values to svcparams
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
Contents_DNS::Contents_DNS(Connection* conn, bool orig, detail::DNS_Interpreter* arg_interp)
|
Contents_DNS::Contents_DNS(Connection* conn, bool orig, detail::DNS_Interpreter* arg_interp)
|
||||||
|
|
|
@ -71,6 +71,8 @@ enum RR_Type
|
||||||
TYPE_DS = 43, ///< Delegation signer (RFC 4034)
|
TYPE_DS = 43, ///< Delegation signer (RFC 4034)
|
||||||
TYPE_NSEC3 = 50,
|
TYPE_NSEC3 = 50,
|
||||||
TYPE_NSEC3PARAM = 51, ///< Contains the NSEC3 parameters (RFC 5155)
|
TYPE_NSEC3PARAM = 51, ///< Contains the NSEC3 parameters (RFC 5155)
|
||||||
|
TYPE_SVCB = 64, ///< SerViCe Binding (RFC draft: https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-07#section-1.1)
|
||||||
|
TYPE_HTTPS = 65, ///< HTTPS record (HTTPS specific SVCB resource record)
|
||||||
// Obsoleted
|
// Obsoleted
|
||||||
TYPE_SPF = 99, ///< Alternative: storing SPF data in TXT records, using the same format (RFC
|
TYPE_SPF = 99, ///< Alternative: storing SPF data in TXT records, using the same format (RFC
|
||||||
///< 4408). Support for it was discontinued in RFC 7208
|
///< 4408). Support for it was discontinued in RFC 7208
|
||||||
|
@ -148,6 +150,18 @@ enum DNSSEC_Digest
|
||||||
SHA384 = 4,
|
SHA384 = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///< all keys are defined in RFC draft https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-07#section-14.3.2
|
||||||
|
enum SVCPARAM_Key
|
||||||
|
{
|
||||||
|
mandatory = 0,
|
||||||
|
alpn = 1,
|
||||||
|
no_default_alpn = 2,
|
||||||
|
port = 3,
|
||||||
|
ipv4hint = 4,
|
||||||
|
ech = 5,
|
||||||
|
ipv6hint = 6,
|
||||||
|
};
|
||||||
|
|
||||||
struct DNS_RawMsgHdr
|
struct DNS_RawMsgHdr
|
||||||
{
|
{
|
||||||
unsigned short id;
|
unsigned short id;
|
||||||
|
@ -269,6 +283,12 @@ struct LOC_DATA
|
||||||
unsigned long altitude; // 32
|
unsigned long altitude; // 32
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SVCB_DATA
|
||||||
|
{
|
||||||
|
uint16_t svc_priority; // 2
|
||||||
|
StringValPtr target_name;
|
||||||
|
};
|
||||||
|
|
||||||
class DNS_MsgInfo
|
class DNS_MsgInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -288,6 +308,7 @@ public:
|
||||||
RecordValPtr BuildDS_Val(struct DS_DATA*);
|
RecordValPtr BuildDS_Val(struct DS_DATA*);
|
||||||
RecordValPtr BuildBINDS_Val(struct BINDS_DATA*);
|
RecordValPtr BuildBINDS_Val(struct BINDS_DATA*);
|
||||||
RecordValPtr BuildLOC_Val(struct LOC_DATA*);
|
RecordValPtr BuildLOC_Val(struct LOC_DATA*);
|
||||||
|
RecordValPtr BuildSVCB_Val(const struct SVCB_DATA&);
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
int opcode; ///< query type, see DNS_Opcode
|
int opcode; ///< query type, see DNS_Opcode
|
||||||
|
@ -393,6 +414,8 @@ protected:
|
||||||
const u_char* msg_start);
|
const u_char* msg_start);
|
||||||
bool ParseRR_LOC(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength,
|
bool ParseRR_LOC(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength,
|
||||||
const u_char* msg_start);
|
const u_char* msg_start);
|
||||||
|
bool ParseRR_SVCB(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength,
|
||||||
|
const u_char* msg_start, const RR_Type& svcb_type);
|
||||||
void SendReplyOrRejectEvent(detail::DNS_MsgInfo* msg, EventHandlerPtr event,
|
void SendReplyOrRejectEvent(detail::DNS_MsgInfo* msg, EventHandlerPtr event,
|
||||||
const u_char*& data, int& len, String* question_name,
|
const u_char*& data, int& len, String* question_name,
|
||||||
String* original_name);
|
String* original_name);
|
||||||
|
|
|
@ -721,6 +721,37 @@ event dns_SSHFP%(c: connection, msg: dns_msg, ans: dns_answer, algo: count, fpty
|
||||||
## loc: The parsed RDATA of LOC type record.
|
## loc: The parsed RDATA of LOC type record.
|
||||||
event dns_LOC%(c: connection, msg: dns_msg, ans: dns_answer, loc: dns_loc_rr%);
|
event dns_LOC%(c: connection, msg: dns_msg, ans: dns_answer, loc: dns_loc_rr%);
|
||||||
|
|
||||||
|
## Generated for DNS replies of type *SVCB* (General Purpose Service Endpoints).
|
||||||
|
## See `RFC draft for DNS SVCB/HTTPS <https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-07>`__
|
||||||
|
## for more information about DNS SVCB/HTTPS resource records.
|
||||||
|
## 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.
|
||||||
|
##
|
||||||
|
## svcb: The parsed RDATA of SVCB type record.
|
||||||
|
event dns_SVCB%(c: connection, msg: dns_msg, ans: dns_answer, svcb: dns_svcb_rr%);
|
||||||
|
|
||||||
|
## Generated for DNS replies of type *HTTPS* (HTTPS Specific Service Endpoints).
|
||||||
|
## See `RFC draft for DNS SVCB/HTTPS <https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-07>`__
|
||||||
|
## for more information about DNS SVCB/HTTPS resource records.
|
||||||
|
## Since SVCB and HTTPS records share the same wire format layout, the argument https is dns_svcb_rr.
|
||||||
|
## 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.
|
||||||
|
##
|
||||||
|
## https: The parsed RDATA of HTTPS type record.
|
||||||
|
event dns_HTTPS%(c: connection, msg: dns_msg, ans: dns_answer, https: dns_svcb_rr%);
|
||||||
|
|
||||||
## 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.
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
[svc_priority=1, target_name=.]
|
|
@ -0,0 +1 @@
|
||||||
|
[svc_priority=0, target_name=foo.example.com]
|
BIN
testing/btest/Traces/dns-https.pcap
Normal file
BIN
testing/btest/Traces/dns-https.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/dns-svcb.pcap
Normal file
BIN
testing/btest/Traces/dns-svcb.pcap
Normal file
Binary file not shown.
9
testing/btest/scripts/base/protocols/dns/https.zeek
Normal file
9
testing/btest/scripts/base/protocols/dns/https.zeek
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# @TEST-EXEC: zeek -C -r $TRACES/dns-https.pcap %INPUT > output
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
|
@load policy/protocols/dns/auth-addl
|
||||||
|
|
||||||
|
event dns_HTTPS(c: connection, msg: dns_msg, ans: dns_answer, https: dns_svcb_rr)
|
||||||
|
{
|
||||||
|
print https;
|
||||||
|
}
|
9
testing/btest/scripts/base/protocols/dns/svcb.zeek
Normal file
9
testing/btest/scripts/base/protocols/dns/svcb.zeek
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# @TEST-EXEC: zeek -C -r $TRACES/dns-svcb.pcap %INPUT > output
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
|
@load policy/protocols/dns/auth-addl
|
||||||
|
|
||||||
|
event dns_SVCB(c: connection, msg: dns_msg, ans: dns_answer, svcb: dns_svcb_rr)
|
||||||
|
{
|
||||||
|
print svcb;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue