scapy
scapy copied to clipboard
scapy doesn't assemble DNS queries/responses sent over TCP in more than one packet
Brief description
When DNS messages are sent over TCP in more than one packet scapy
dissects each packet separately and since usually they don't pass the sanity checks their payloads get wrapped into Raw
. In theory it should be possible to add DNS.tcp_reassembly
that could assemble those messages but due to the sanity checks those packets can never reach it currently.
(It came up in https://github.com/secdev/scapy/pull/4012 but since it's kind of tangential I thought it would be better to move it here)
Scapy version
3da71cb275721292131a3ea5196bfa98883741f2
Python version
3.11.3
Operating system
Linux version 6.3.4-101.fc37.x86_64
Additional environment information
No response
How to reproduce
dns-openpgpkey.pcap
contains a response with an OPENPGPKEY RR that arrived in two separate packets.
>>> pkts = sniff(offline='dns-openpgpkey.pcap', session=TCPSession)
INFO: Malformed DNS message: invalid length!
INFO: Malformed DNS message: invalid length!
Actual result
scapy
wraps the DNS part of those packets into Raw
:
>>> pkts.nsummary()
0000 Ether / IP / UDP / DNS Qry "b'd08ee310438ca124a6149ea5cc21b6313b390dce485576eff96f8722._openpgpkey.fedoraproject.org.'"
0001 Ether / IP / UDP / DNS Ans
0002 Ether / IP / TCP 10.0.2.100:44681 > 1.1.1.1:domain S
0003 Ether / IP / TCP 1.1.1.1:domain > 10.0.2.100:44681 SA
0004 Ether / IP / TCP 10.0.2.100:44681 > 1.1.1.1:domain A
0005 Ether / IP / TCP / DNS Qry "b'd08ee310438ca124a6149ea5cc21b6313b390dce485576eff96f8722._openpgpkey.fedoraproject.org.'"
0006 Ether / IP / TCP 1.1.1.1:domain > 10.0.2.100:44681 A
0007 Ether / IP / TCP 1.1.1.1:domain > 10.0.2.100:44681 PA / Raw
0008 Ether / IP / TCP 10.0.2.100:44681 > 1.1.1.1:domain A
0009 Ether / IP / TCP 1.1.1.1:domain > 10.0.2.100:44681 PA / Raw
0010 Ether / IP / TCP 10.0.2.100:44681 > 1.1.1.1:domain A
0011 Ether / IP / TCP 10.0.2.100:44681 > 1.1.1.1:domain FA
0012 Ether / IP / TCP 1.1.1.1:domain > 10.0.2.100:44681 A
0013 Ether / IP / TCP 1.1.1.1:domain > 10.0.2.100:44681 FA
0014 Ether / IP / TCP 10.0.2.100:44681 > 1.1.1.1:domain A
Expected result
To get the response the Raw payloads should be combined manually using something like
DNS(pkts[7][Raw].load[2:] + pkts[9][Raw].load)
...
The idea is to get DNS.tcp_reassemble
to do that :-)
I'm not sure if it's helpful or not but here's what tshark
shows:
$ tshark -r dns-openpgpkey.pcap
...
3 0.404609 10.0.2.100 → 1.1.1.1 TCP 74 44681 → 53 [SYN] Seq=0 Win=64660 Len=0 MSS=1220 SACK_PERM TSval=2859481442 TSecr=0 WS=128
4 0.431399 1.1.1.1 → 10.0.2.100 TCP 58 53 → 44681 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=65480
5 0.431475 10.0.2.100 → 1.1.1.1 TCP 54 44681 → 53 [ACK] Seq=1 Ack=1 Win=64660 Len=0
6 0.431646 10.0.2.100 → 1.1.1.1 DNS 183 Standard query 0xb390 OPENPGPKEY d08ee310438ca124a6149ea5cc21b6313b390dce485576eff96f8722._openpgpkey.fedoraproject.org OPT
7 0.432353 1.1.1.1 → 10.0.2.100 TCP 54 53 → 44681 [ACK] Seq=1 Ack=130 Win=65535 Len=0
8 0.831929 1.1.1.1 → 10.0.2.100 TCP 1454 53 → 44681 [PSH, ACK] Seq=1 Ack=130 Win=65535 Len=1400 [TCP segment of a reassembled PDU]
9 0.831960 10.0.2.100 → 1.1.1.1 TCP 54 44681 → 53 [ACK] Seq=130 Ack=1401 Win=63440 Len=0
10 0.832338 1.1.1.1 → 10.0.2.100 DNS 1006 Standard query response 0xb390 OPENPGPKEY d08ee310438ca124a6149ea5cc21b6313b390dce485576eff96f8722._openpgpkey.fedoraproject.org OPENPGPKEY OPT