google / google/gopacket

layers.DNS doesn't properly decode any DNS-over-TCP or DNS-over-TLS packet

Open
#901 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
6.8k
Forks
1.2k
PR merge metrics
No merged PRs in 30d

Description

By [RFC 7766, Section 8](https://datatracker.ietf.org/doc/html/rfc7766#section-8):

> DNS clients and servers SHOULD pass the two-octet length field, and
the message described by that length field, to the TCP layer at the
same time

As a result, for DNS packet over TCP and over TLS (after decryption), the first two bytes are an additional `length` field which dosn't exist in typical DNS over UDP.

The `layers.DNS` in current gopacket didn't consider this when decoding or encoding. For example, in [layers/dns.go#315](https://github.com/google/gopacket/blob/master/layers/dns.go#L315) , it directly suppose the first two bytes are the `ID` field.

This bug will cause all later decoding being not as expected and being invalid, since it will thereafter result in wrong values of `QDCount`, `ANCount`, `NSCount` and `ARCount` and cause wrong times of iterations. Practically, in many real world cases, I found this bug will cause an error message like `"qname '0x40' - RFC 2673 unsupported yet (data=%x index=%d)"`; but the field ignoring is the actual root cause.

A pcap for testing could be obtained via:

1) download from https://github.com/arkime/arkime/blob/main/tests/pcap/dns-tcp.pcap , or

2) generate by `dig @8.8.8.8 +tcp example.org` and capture by `tcpdump port 53`

side note: DNS-over-HTTPS, although also "over TCP", is not affected by this bug. When DNS Wireformat is used for DoH's HTTP payload, that payload should be decoded as DNS over UDP.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.