From d3be0f2e38cda41a35fb78e6ad4efb71f6a4e39c Mon Sep 17 00:00:00 2001 From: Dan Kortschak <90160302+efd6@users.noreply.github.com> Date: Mon, 11 Oct 2021 08:58:22 +1030 Subject: [PATCH] packetbeat/protos/dns: don't render missing A and AAAA addresses from truncated records (#28297) (cherry picked from commit 4c1652c39473d35290aeeb420ed34db8b7bb3ed1) --- CHANGELOG.next.asciidoc | 1 + packetbeat/protos/dns/dns.go | 12 ++++++++++++ packetbeat/protos/dns/dns_test.go | 10 ++++++++-- packetbeat/protos/dns/dns_udp_test.go | 23 +++++++++++++++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index ea1ca4f7a75e..b195b8676684 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -47,6 +47,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d *Packetbeat* +- Handle truncated DNS records more gracefully. {issue}21495[21495] {pull}28297[28297] *Winlogbeat* diff --git a/packetbeat/protos/dns/dns.go b/packetbeat/protos/dns/dns.go index 15aa154276fc..125d6112bae6 100644 --- a/packetbeat/protos/dns/dns.go +++ b/packetbeat/protos/dns/dns.go @@ -615,6 +615,9 @@ func rrsToMapStrs(records []mkdns.RR, ipList bool) ([]common.MapStr, []string) { mapStr["ttl"] = strconv.FormatInt(int64(rrHeader.Ttl), 10) mapStrSlice = append(mapStrSlice, mapStr) } + if len(mapStrSlice) == 0 { + mapStrSlice = nil + } return mapStrSlice, allIPs } @@ -687,10 +690,19 @@ func rrToMapStr(rr mkdns.RR, ipList bool) (common.MapStr, []string) { } else { debugf("Rdata for the unhandled RR type %s could not be fetched", dnsTypeToString(rrType)) } + + // Don't attempt to render IPs for answers that are incomplete. case *mkdns.A: + if x.A == nil { + break + } mapStr["data"] = appendIP(x.A.String()) case *mkdns.AAAA: + if x.AAAA == nil { + break + } mapStr["data"] = appendIP(x.AAAA.String()) + case *mkdns.CNAME: mapStr["data"] = trimRightDot(x.Target) case *mkdns.DNSKEY: diff --git a/packetbeat/protos/dns/dns_test.go b/packetbeat/protos/dns/dns_test.go index 08afa1b58db1..9427ebeaecf5 100644 --- a/packetbeat/protos/dns/dns_test.go +++ b/packetbeat/protos/dns/dns_test.go @@ -212,8 +212,14 @@ func assertMapStrData(t testing.TB, m common.MapStr, q dnsTestMessage) { assertFlags(t, m, q.flags) assert.Equal(t, q.rcode, mapValue(t, m, "dns.response_code")) - assert.Equal(t, len(q.answers), mapValue(t, m, "dns.answers_count"), - "Expected dns.answers_count to be %d", len(q.answers)) + truncated, ok := mapValue(t, m, "dns.flags.truncated_response").(bool) + if !ok { + t.Fatal("dns.flags.truncated_response value is not a bool.") + } + if !truncated { + assert.Equal(t, len(q.answers), mapValue(t, m, "dns.answers_count"), + "Expected dns.answers_count to be %d", len(q.answers)) + } if len(q.answers) > 0 { assert.Len(t, mapValue(t, m, "dns.answers"), len(q.answers), "Expected dns.answers to be length %d", len(q.answers)) diff --git a/packetbeat/protos/dns/dns_udp_test.go b/packetbeat/protos/dns/dns_udp_test.go index c3ca35a0a163..3711fb50e007 100644 --- a/packetbeat/protos/dns/dns_udp_test.go +++ b/packetbeat/protos/dns/dns_udp_test.go @@ -54,6 +54,7 @@ var ( // An array of all test messages. messages = []dnsTestMessage{ elasticA, + elasticNoIP, zoneIxfr, githubPtr, sophosTxt, @@ -83,6 +84,28 @@ var ( }, } + elasticNoIP = dnsTestMessage{ + id: 8529, + opcode: "QUERY", + flags: []string{"rd", "ra", "tc"}, + rcode: "NOERROR", + qClass: "IN", + qType: "A", + qName: "elastic.co", + qEtld: "elastic.co", + qTLD: "co", + answers: nil, + request: []byte{ + 0x21, 0x51, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x65, 0x6c, 0x61, + 0x73, 0x74, 0x69, 0x63, 0x02, 0x63, 0x6f, 0x00, 0x00, 0x01, 0x00, 0x01, + }, + response: []byte{ + 0x21, 0x51, 0x83, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x65, 0x6c, 0x61, + 0x73, 0x74, 0x69, 0x63, 0x02, 0x63, 0x6f, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, + }, + } + zoneIxfr = dnsTestMessage{ id: 16384, opcode: "QUERY",