Skip to content
DNS Exfiltration

DNS Exfiltration

DNS can be used to exfiltrate data, for example to bypass firewalls.

  • iodine - GitHub

    Can be identified by the presence of the “Aaahhh-Drink-mal-ein-Jägermeister” or “La flûte naïve française est retirée à Crête”.
    Can be deciphered with this script
    Hack.lu CTF WU

  • DNScat2 - GitHub

    Can be identified when file signatures are present in the DNS queries. Data can be extracted with this script and files can be extracted with binwalk.

  • Custom exfiltration in DNS query names

    Custom tools (and many CTF challenges) spread the exfiltrated data across the subdomain labels of DNS queries (<chunk>.<chunk>.attacker.com), usually hex, base32 or base64 encoded. Rebuild the payload by collecting every query name in order, stripping the base domain, concatenating the labels and decoding.

    Extract the query names from a pcap with tshark:

    tshark -r capture.pcap -Y dns -T fields -e dns.qry.name | awk '!seen[$0]++'

    or with Python (scapy):

    from scapy.all import rdpcap, DNSQR
    import binascii
    
    names, seen = [], set()
    for pkt in rdpcap("capture.pcap"):
        if pkt.haslayer(DNSQR):                       # the packet carries a DNS question
            qname = pkt[DNSQR].qname.decode(errors="replace").rstrip(".")
            if qname not in seen:                     # the same query is often sent twice
                seen.add(qname)
                names.append(qname)
    
    # Example: each label is a hex chunk and the base domain is exfil.example.com
    blob = "".join(n.split(".exfil.example.com")[0].replace(".", "") for n in names)
    open("recovered.bin", "wb").write(binascii.unhexlify(blob))

    Then identify the recovered bytes with file signatures (for example a .webp starts with RIFF....WEBP).