Add DNS TKEY event

This commit is contained in:
Evan Typanski 2024-08-13 15:27:25 -04:00
parent ec1088c3ef
commit 170276807b
9 changed files with 161 additions and 0 deletions

View file

@ -256,6 +256,8 @@ bool DNS_Interpreter::ParseAnswer(detail::DNS_MsgInfo* msg, const u_char*& data,
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;
case detail::TYPE_TSIG: status = ParseRR_TSIG(msg, data, len, rdlength, msg_start); break;
case detail::TYPE_RRSIG: status = ParseRR_RRSIG(msg, data, len, rdlength, msg_start); break;
@ -824,6 +826,48 @@ bool DNS_Interpreter::ParseRR_TSIG(detail::DNS_MsgInfo* msg, const u_char*& data
return true;
}
bool DNS_Interpreter::ParseRR_TKEY(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength,
const u_char* msg_start) {
if ( ! dns_TKEY || msg->skip_event ) {
data += rdlength;
len -= rdlength;
return true;
}
if ( len < 16 )
return false;
const u_char* data_start = data;
u_char alg_name[513];
int alg_name_len = sizeof(alg_name) - 1;
u_char* alg_name_end = ExtractName(data, len, alg_name, alg_name_len, msg_start);
if ( ! alg_name_end )
return false;
uint32_t inception = ExtractLong(data, len);
uint32_t expiration = ExtractLong(data, len);
uint16_t mode = ExtractShort(data, len);
uint16_t error = ExtractShort(data, len);
String* key_data;
ExtractOctets(data, len, dns_TKEY ? &key_data : nullptr);
ExtractOctets(data, len, nullptr); // Other data
if ( dns_TKEY ) {
detail::TKEY_DATA tkey;
tkey.alg_name = new String(alg_name, int(alg_name_end - alg_name), true);
tkey.inception = inception;
tkey.expiration = expiration;
tkey.mode = mode;
tkey.error = error;
tkey.key = key_data;
analyzer->EnqueueConnEvent(dns_TKEY, analyzer->ConnVal(), msg->BuildHdrVal(), msg->BuildTKEY_Val(&tkey));
}
return true;
}
bool DNS_Interpreter::ParseRR_RRSIG(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength,
const u_char* msg_start) {
if ( ! dns_RRSIG || msg->skip_event ) {
@ -1660,6 +1704,23 @@ RecordValPtr DNS_MsgInfo::BuildEDNS_COOKIE_Val(struct EDNS_COOKIE* opt) {
return r;
}
RecordValPtr DNS_MsgInfo::BuildTKEY_Val(struct TKEY_DATA* tkey) {
static auto dns_tkey = id::find_type<RecordType>("dns_tkey");
auto r = make_intrusive<RecordVal>(dns_tkey);
r->Assign(0, query_name);
r->Assign(1, answer_type);
r->Assign(2, tkey->alg_name);
r->AssignTime(3, static_cast<double>(tkey->inception));
r->AssignTime(4, static_cast<double>(tkey->expiration));
r->Assign(5, static_cast<uint16_t>(tkey->mode));
r->Assign(6, static_cast<uint16_t>(tkey->error));
r->Assign(7, tkey->key);
r->Assign(8, is_query);
return r;
}
RecordValPtr DNS_MsgInfo::BuildTSIG_Val(struct TSIG_DATA* tsig) {
static auto dns_tsig_additional = id::find_type<RecordType>("dns_tsig_additional");
auto r = make_intrusive<RecordVal>(dns_tsig_additional);

View file

@ -191,6 +191,15 @@ struct EDNS_COOKIE {
zeek::String* server_cookie; ///< cookie value sent by the server (0 or 8-32 bytes)
};
struct TKEY_DATA {
String* alg_name;
unsigned long inception;
unsigned long expiration;
unsigned short mode;
unsigned short error;
String* key;
};
struct TSIG_DATA {
String* alg_name;
unsigned long time_s;
@ -278,6 +287,7 @@ public:
RecordValPtr BuildEDNS_ECS_Val(struct EDNS_ECS*);
RecordValPtr BuildEDNS_TCP_KA_Val(struct EDNS_TCP_KEEPALIVE*);
RecordValPtr BuildEDNS_COOKIE_Val(struct EDNS_COOKIE*);
RecordValPtr BuildTKEY_Val(struct TKEY_DATA*);
RecordValPtr BuildTSIG_Val(struct TSIG_DATA*);
RecordValPtr BuildRRSIG_Val(struct RRSIG_DATA*);
RecordValPtr BuildDNSKEY_Val(struct DNSKEY_DATA*);
@ -361,6 +371,7 @@ protected:
bool ParseRR_TXT(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start);
bool ParseRR_SPF(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start);
bool ParseRR_CAA(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start);
bool ParseRR_TKEY(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start);
bool ParseRR_TSIG(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start);
bool ParseRR_RRSIG(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start);
bool ParseRR_DNSKEY(detail::DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start);

View file

@ -578,6 +578,23 @@ event dns_EDNS_tcp_keepalive%(c: connection, msg: dns_msg, opt: dns_edns_tcp_kee
## dns_skip_all_addl dns_skip_all_auth dns_skip_auth
event dns_EDNS_cookie%(c: connection, msg: dns_msg, opt: dns_edns_cookie%);
## Generated for DNS replies of type *TKEY*. For replies with multiple answers,
## an individual event of the corresponding type is raised for each.
##
## See `Wikipedia <http://en.wikipedia.org/wiki/Domain_Name_System>`__ for more
## information about the DNS protocol. See `RFC2930 <https://tools.ietf.org/html/rfc2930>`__
## for more information about TKEY. Zeek analyzes both UDP and TCP DNS sessions.
##
## 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 parsed TKEY reply.
##
## .. zeek:see:: dns_TSIG_addl
event dns_TKEY%(c: connection, msg: dns_msg, ans: dns_tkey%);
## Generated for DNS replies of type *TSIG*. For replies with multiple answers,
## an individual event of the corresponding type is raised for each.
##