Unix & Linux Asked by user424280 on January 3, 2022
I’m trying to send a valid DNS request with either nc
or bash
and /dev/udp/
.
I created a valid DNS packet to use as a template:
tcpdump -XX port 53
Then, in a new terminal made a request with curl:
curl https://duckduckgo.com/
This generates the following data in the tcpdump terminal.
0x0000: 4500 003c b0b4 4000 4011 73c3 0a00 020f E..<..@[email protected].....
0x0010: 0a2a 0001 bdd4 0035 0028 4f24 cfc9 0100 .*.....5.(O$....
0x0020: 0001 0000 0000 0000 0a64 7563 6b64 7563 .........duckduc
0x0030: 6b67 6f03 636f 6d00 0001 0001 kgo.com.....
From this, I modified the request slightly to match this reference and saved it to a file /tmp/ddg.txt
.
0000: 4500 003c b0b4 4000 4011 73c3 0a00 020f E..<..@[email protected].....
0010: 0a2a 0001 bdd4 0035 0028 4f24 cfc9 0100 .*.....5.(O$....
0020: 0001 0000 0000 0000 0a64 7563 6b64 7563 .........duckduc
0030: 6b67 6f03 636f 6d00 0001 0001 kgo.com.....
Then, tried generating a request, but I get the following error message:
xxd -r /tmp/ddg.txt | nc -q 1 -nu 10.42.0.1 53
xxd: sorry, cannot seek backwards.
In Wireshark, the request appears malformed. What am I getting wrong here? It is possible to send a proper DNS query with this method?
You have used tcpdump. But you should then have used wireshark the same way you did later: you would have seen that you made the same mistake as in the link you provided: you included the extra IPv4+UDP headers: you must only provide the UDP payload to the netcat command, since it sends an IPv4 UDP packet already.
Here's the data in hex without any superfluous addresses:
4500 003c b0b4 4000 4011 73c3 0a00 020f 0a2a 0001
UDP header (the 0028 is the length of the whole UDP part: 8+20 => payload of length 0x20 = 32 bytes):
bdd4 0035 0028 4f24
UDP payload:
cfc9 0100 0001 0000 0000 0000 0a64 7563 6b64 7563 6b67 6f03 636f 6d00 0001 0001
xxd
can use the -p
parameter and not write but more importantly not need any address with -r
(which avoids having to rewrite and now renumber those addresses):
-p | -ps | -postscript | -plain
Output in postscript continuous hexdump style. Also known as plain hexdump style.
When reversed (-r
) it will also ignore any white spaces wherever they are.
Here's a test done (I just put back your own DNS server IP instead of the test one which worked fine):
$ echo cfc9 0100 0001 0000 0000 0000 0a64 7563 6b64 7563 6b67 6f03 636f 6d00 0001 0001 |
xxd -p -r | nc -q1 -w2 -n -u 10.42.0.1 53 | xxd
00000000: cfc9 8180 0001 0001 0004 0000 0a64 7563 .............duc
00000010: 6b64 7563 6b67 6f03 636f 6d00 0001 0001 kduckgo.com.....
00000020: c00c 0001 0001 0000 005e 0004 2872 b19c .........^..(r..
00000030: c00c 0002 0001 0002 91bb 0014 0464 6e73 .............dns
00000040: 3303 7030 3505 6e73 6f6e 6503 6e65 7400 3.p05.nsone.net.
00000050: c00c 0002 0001 0002 91bb 0007 0464 6e73 .............dns
00000060: 31c0 41c0 0c00 0200 0100 0291 bb00 0704 1.A.............
00000070: 646e 7332 c041 c00c 0002 0001 0002 91bb dns2.A..........
00000080: 0007 0464 6e73 34c0 41 ...dns4.A
Replacing netcat with socat: replace nc -q1 -w2 -n -u 10.42.0.1 53
with socat udp4:10.42.0.1:53 -
. It deals better with EOF conditions (so no need to wait two seconds).
If you want to use bash's built-in /dev/udp
instead of netcat or socat then it becomes a bit more complicated to handle a full-duplex socket with two half-duplex commands (one only writes, the other only reads). For this non-interactive case, no need to fork the first output command (else, for more complex cases, the ;
before dd
can be replaced with &
to have output and input working in parallel). It still requires dd
in order to grab only one packet and finish, thus avoiding xxd
blocking:
( echo cfc9 0100 0001 0000 0000 0000 0a64 7563 6b64 7563 6b67 6f03 636f 6d00 0001 0001 | xxd -p -r >&3; dd bs=9000 count=1 <&3 2>/dev/null | xxd ) 3>/dev/udp/10.42.0.1/53
Answered by A.B on January 3, 2022
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP