From: Simon Dugas Date: Wed, 22 Apr 2020 17:29:32 +0000 (+0000) Subject: dns: log rdata for NULL record type X-Git-Tag: suricata-7.0.0-beta1~1955 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4336a0e7394a31a3eaddb15cfe543c27955fa96c;p=thirdparty%2Fsuricata.git dns: log rdata for NULL record type Logs the rdata for a NULL record type as a printable string. --- diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index e876be23c8..4102968580 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -271,6 +271,7 @@ pub enum DNSRData { MX(Vec), // RData is text TXT(Vec), + NULL(Vec), // RData has several fields SOA(DNSRDataSOA), SSHFP(DNSRDataSSHFP), diff --git a/rust/src/dns/log.rs b/rust/src/dns/log.rs index c27076be45..02519b8135 100644 --- a/rust/src/dns/log.rs +++ b/rust/src/dns/log.rs @@ -444,6 +444,7 @@ fn dns_log_json_answer_detail(answer: &DNSAnswerEntry) -> Result { jsa.set_string_from_bytes("rdata", &bytes)?; } @@ -515,6 +516,7 @@ fn dns_log_json_answer(js: &mut JsonBuilder, response: &DNSResponse, flags: u64) DNSRData::CNAME(bytes) | DNSRData::MX(bytes) | DNSRData::TXT(bytes) | + DNSRData::NULL(bytes) | DNSRData::PTR(bytes) => { if !answer_types.contains_key(&type_string) { answer_types.insert(type_string.to_string(), @@ -687,6 +689,7 @@ fn dns_log_json_answer_v1(header: &DNSHeader, answer: &DNSAnswerEntry) DNSRData::CNAME(bytes) | DNSRData::MX(bytes) | DNSRData::TXT(bytes) | + DNSRData::NULL(bytes) | DNSRData::PTR(bytes) => { js.set_string_from_bytes("rdata", &bytes)?; } diff --git a/rust/src/dns/lua.rs b/rust/src/dns/lua.rs index 6a7ea26921..570c71e512 100644 --- a/rust/src/dns/lua.rs +++ b/rust/src/dns/lua.rs @@ -177,6 +177,7 @@ pub extern "C" fn rs_dns_lua_get_answer_table(clua: &mut CLuaState, DNSRData::CNAME(ref bytes) | DNSRData::MX(ref bytes) | DNSRData::TXT(ref bytes) | + DNSRData::NULL(ref bytes) | DNSRData::PTR(ref bytes) | DNSRData::Unknown(ref bytes) => { if bytes.len() > 0 { diff --git a/rust/src/dns/parser.rs b/rust/src/dns/parser.rs index 0f7038dda6..a59a09fbaa 100644 --- a/rust/src/dns/parser.rs +++ b/rust/src/dns/parser.rs @@ -323,6 +323,15 @@ fn dns_parse_rdata_txt<'a>(input: &'a [u8]) ) } +fn dns_parse_rdata_null<'a>(input: &'a [u8]) + -> IResult<&'a [u8], DNSRData> { + do_parse!( + input, + data: take!(input.len()) >> + (DNSRData::NULL(data.to_vec())) + ) +} + fn dns_parse_rdata_sshfp<'a>(input: &'a [u8]) -> IResult<&'a [u8], DNSRData> { do_parse!( @@ -354,6 +363,7 @@ pub fn dns_parse_rdata<'a>(input: &'a [u8], message: &'a [u8], rrtype: u16) DNS_RECORD_TYPE_SOA => dns_parse_rdata_soa(input, message), DNS_RECORD_TYPE_MX => dns_parse_rdata_mx(input, message), DNS_RECORD_TYPE_TXT => dns_parse_rdata_txt(input), + DNS_RECORD_TYPE_NULL => dns_parse_rdata_null(input), DNS_RECORD_TYPE_SSHFP => dns_parse_rdata_sshfp(input), _ => dns_parse_rdata_unknown(input), } @@ -669,6 +679,65 @@ mod tests { } } + + #[test] + fn test_dns_parse_response_null() { + // DNS response with a NULL record from + // https://redmine.openinfosecfoundation.org/attachments/2062 + + let pkt: &[u8] = &[ + 0x12, 0xb0, 0x84, 0x00, 0x00, 0x01, 0x00, 0x01, /* ........ */ + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x76, 0x61, 0x61, /* .....vaa */ + 0x61, 0x61, 0x6b, 0x61, 0x72, 0x64, 0x6c, 0x69, /* aakardli */ + 0x06, 0x70, 0x69, 0x72, 0x61, 0x74, 0x65, 0x03, /* .pirate. */ + 0x73, 0x65, 0x61, 0x00, 0x00, 0x0a, 0x00, 0x01, /* sea..... */ + 0xc0, 0x0c, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x00, /* ........ */ + 0x00, 0x00, 0x00, 0x09, 0x56, 0x41, 0x43, 0x4b, /* ....VACK */ + 0x44, 0x03, 0xc5, 0xe9, 0x01, /* D.... */ + ]; + + let res = dns_parse_response(pkt); + match res { + Ok((rem, response)) => { + // The response should be fully parsed. + assert_eq!(rem.len(), 0); + + assert_eq!(response.header, DNSHeader { + tx_id: 0x12b0, + flags: 0x8400, + questions: 1, + answer_rr: 1, + authority_rr: 0, + additional_rr: 0, + }); + + assert_eq!(response.queries.len(), 1); + let query = &response.queries[0]; + assert_eq!(query.name, + "vaaaakardli.pirate.sea".as_bytes().to_vec()); + assert_eq!(query.rrtype, DNS_RECORD_TYPE_NULL); + assert_eq!(query.rrclass, 1); + + assert_eq!(response.answers.len(), 1); + + let answer = &response.answers[0]; + assert_eq!(answer.name, + "vaaaakardli.pirate.sea".as_bytes().to_vec()); + assert_eq!(answer.rrtype, DNS_RECORD_TYPE_NULL); + assert_eq!(answer.rrclass, 1); + assert_eq!(answer.ttl, 0); + assert_eq!(answer.data, DNSRData::NULL(vec![ + 0x56, 0x41, 0x43, 0x4b, /* VACK */ + 0x44, 0x03, 0xc5, 0xe9, 0x01, /* D.... */ + ])); + }, + _ => { + assert!(false); + } + } + } + + #[test] fn test_dns_parse_rdata_sshfp() { // Dummy data since we don't have a pcap sample.