wiki:doc/DnsPluggableTransport/Survey

Survey of techniques to encode data in DNS messages.

Summary

  • #dnscat2
    • Uses CNAME, MX, TXT (randomly selected) by default. Also supports A and AAAA.
    • Uses hexadecimal encoding everywhere.
    • Full duplex: responses to data can themselves have data.
    • Doesn't use the Additional section in responses.
    • Doesn't use multiple strings in TXT responses (maximum length < 255 bytes).
    • Doesn't use EDNS.
  • #TUNS
    • Uses CNAME exclusively.
    • Encodes with base32, using '0' as a padding character instead of '='.
    • Half duplex: client either sends a d data-carrying query and gets back an empty l length response; or sends an empty r request and gets back a d data-carrying response.
    • l responses encode the number of server-queued messages.
    • Doesn't use EDNS.
  • #OzymanDNS
    • Uses TXT exclusively.
    • Encodes with base32 in queries and base64 in responses.
    • Half duplex: each query–response pair either sends a piece of data (up) or receives a piece of data (down), not both.
    • Supports long TXT records (multiple 255-byte-long strings concatenated in one resource record). Seems hardcoded to use exactly two TXT strings in a record.
    • Responses encode the number of server-queued messages as the first byte of a pending A record in the Additional section.
    • Doesn't use EDNS in my tests, though maybe a different version does.
  • #iodine
    • Supports A, CNAME, MX, SRV, TXT, NULL, and PRIVATE resource records. Does autodetection of which are supported on the DNS path.
    • Supports a number of encodings (also autodetected): base32, base64, base64u, base128.
    • Full duplex: server can send data in response to data; client can also solicit data without sending anything, using a p ping packet.
    • Supports EDNS for long replies.
    • Complicated.

General observations

DNS tunnels work either at the transport layer (netcat-like) or at the network layer (VPN-like). The network-layer ones have the implementation advantage that they don't have to worry about reliability, because retransmissions etc. are handled by lower-level kernel procedures.

Upstream queries are more squeezed for bandwidth than downstream responses. Although the protocol syntactically permits sending any number of entries in the Question section, in practice the only supported value is QDCOUNT=1.

A single DNS name has a maximum length of 255 bytes (RFC 1035 §2.3.4). However, a name is composed of labels, each of which is a maximum of 63 bytes (or 64 bytes if including the length prefix). And the name's null terminator byte is counted in the limit as well. So it's really only 250 usable bytes. And from that you have to subtract the length of the name suffix that the DNS server is actually authoritative for.

Technically, any 8-bit value can be part of a name label. However RFC 1035 recommends [A-Za-z][A-Za-z0-9-]* for compatibility. Additionally, you can't rely on uppercase/lowercase being preserved (Google Public DNS, among others, may randomize letter case). So you have to encode somehow; base32 or hexadecimal suffices but better efficiency may be possible.

Supposing base32 encoding and 20 bytes for the length of the server's domain name suffix, the most raw data you can send in a single query is about 140 bytes. (Even if upstream queries may contain only one entry in the Question section, it may be possible to stuff extra data into the other sections. EDNS queries have an OPT resource record in the Additional section—but that one only has hop-by-hop meaning, and isn't forwarded by a recursive server to an authoritative server. But perhaps some possibilities exist.)

It's easier to pack data into responses than into queries. Responses have to echo the original question, but they can contain multiple resources records for that query in the Answer section, not to mention the Additional section. You can have multiple resource records of the same or differing types, but the order of resource records within a section is not guaranteed. Resource records can be of any type (A, AAAA, MX, CNAME, etc.). A resource record has a maximum data length of 65535 bytes, but most of them have a fixed format that's shorter than that; e.g. A is 4 bytes and CNAME is up to 255 bytes. The TXT type seems practical: it's a byte sequence of any length up to the 64K limit. (The dnscat2 docs say that the Windows DNS client can't handle '\0' bytes in TXT records, but that shouldn't be a problem if you use a custom client.) The NULL type is marginally more efficient than TXT, but is marked "experimental".

The overall length of a DNS response message cannot be more than 65535 bytes. This holds whether using UDP with EDNS (the UDP payload size field is 16 bits, and anyway that's the largest IP datagram size); or TCP (messages are preceded by a 16-bit length field). In the absence of EDNS, UDP responses are supposed to be limited to 512 bytes. But as EDNS has good support, the MTU is likely a bigger consideration than any DNS-imposed length limitations. A common value for the EDNS length field is 4096.

dnscat2

dnscat2 is a DNS tunnel. It works at the socket layer. Despite its name, it doesn't provide a simple netcat-like interface; it overlays a lot of pentesting-oriented functionality like session management and high-level commands like "send a file". But the underlying transport protocol is separable from all that.

  • Uses hexadecimal encoding everywhere (even in TXT records).
  • Uses CNAME, MX, TXT (randomly selected) by default. Also supports A and AAAA (use type=A,AAAA with the --dns option).
  • Full duplex: responses to data can themselves have data.
  • Prepends a 2-byte packet_id to each query to prevent caching.
  • Doesn't use the Additional section in responses.
  • Only sends back one RR in the Answer section, except for A (max 64) or AAAA (max 16). Prepends a sequence byte to each A and AAAA record.
  • Doesn't use multiple strings in TXT responses (maximum length < 255 bytes).
  • Implements TCP-like reliability and virtual connections with 16-bit session IDs, SYN/FIN messages, and SEQ/ACK numbers.
  • Doesn't use EDNS.
MESSAGE_TYPE_SYN
packet_id     u16
message_type  u8  (= 0x00)
session_id    u16
initial sequence number  u16
options       u16
session name  null-terminated string
MESSAGE_TYPE_MSG
packet_id     u16
message_type  u8  (= 0x01)
session_id    u16
seq           u16
ack           u16
data          []u8
MESSAGE_TYPE_FIN
packet_id     u16
message_type  u8 (= 0x02)
session_id    u16
reason        null-terminated string

dnscat2 sample conversation

dnscat2.pcapng

Starts with a MESSAGE_TYPE_SYN exchange. The session ID is 48ac. The client and server choose initial sequence numbers of 9037 and 7643 respectively. The client additionally sends a session name of !command (happy).

Transaction ID: 0xfe47
Flags: 0x0100 Standard query
Queries
    26b80048ac90370021636f6d6d616e64202868617070792900.example.com: type TXT, class IN
Transaction ID: 0xfe47
Flags: 0x8180 Standard query response, No error
Queries
    26b80048ac90370021636f6d6d616e64202868617070792900.example.com: type TXT, class IN
Answers
    26b80048ac90370021636f6d6d616e64202868617070792900.example.com: type TXT, class IN
        TXT: 3da50048ac76430000

Client and server exchange empty MESSAGE_TYPE_MSG packets while the connection is idle. (Notice SEQ and ACK don't change.)

Transaction ID: 0xc641
Flags: 0x0100 Standard query
Queries
    f4580148ac90377643.example.com: type TXT, class IN
Transaction ID: 0xc641
Flags: 0x8180 Standard query response, No error
Queries
    f4580148ac90377643.example.com: type TXT, class IN
Answers
    f4580148ac90377643.example.com: type TXT, class IN
        TXT: 41e80148ac76439037

Now the server has 17 bytes to send. (It happens to be a command to send the contents of the file "dnscat.c", but the details aren't important.) The client has randomly chosen the CNAME response record type, so the server has to format its data as a domain name.

Transaction ID: 0xf33d
Flags: 0x0100 Standard query
Queries
    ea430148ac90377643.example.com: type CNAME, class IN
Transaction ID: 0xf33d
Flags: 0x8180 Standard query response, No error
Queries
    ea430148ac90377643.example.com: type CNAME, class IN
Answers
    ea430148ac90377643.example.com: type CNAME, class IN
        CNAME: 84000148ac764390370000000d00010003646e736361742e6300.example.com

The client sends 101 bytes. Notice the client's ACK has advanced 17 bytes from 7643 to 7654. The data is long enough that the client has to use multiple labels in the DNS name. The server's response advances the ACK from 9037 to 909c.

Transaction ID: 0x6272
Flags: 0x0100 Standard query
Queries
     11d50148ac903776540000461c800100032f2a20646e736361742e630a20.2a204372656\
     1746564204d617263682f323031330a202a20427920526f6e.20426f7765730a202a0a20\
     2a20536565204c4943454e53452e6d640a202a.2f0a23696e636c756465203c617373657\
     2742e68.example.com: type TXT, class IN
Transaction ID: 0x6272
Flags: 0x8180 Standard query response, No error
Queries
     11d50148ac903776540000461c800100032f2a20646e736361742e630a20.2a2043\
     726561746564204d617263682f323031330a202a20427920526f6e.20426f776573\
     0a202a0a202a20536565204c4943454e53452e6d640a202a.2f0a23696e636c7564\
     65203c6173736572742e68.example.com: type TXT, class IN
Answers
     11d50148ac903776540000461c800100032f2a20646e736361742e630a20.2a2043\
     726561746564204d617263682f323031330a202a20427920526f6e.20426f776573\
     0a202a0a202a20536565204c4943454e53452e6d640a202a.2f0a23696e636c7564\
     65203c6173736572742e68.example.com: type TXT, class IN
        TXT: 018b0148ac7654909c

TUNS

TUNS is an IP-layer (VPN-like) tunnel described in the paper On Robust Covert Channels Inside DNS by Lucas Nussbaum, Pierre Neyron and Olivier Richard. It works at the IP layer (VPN-like). Compared to other tunnels, TUNS aims for better compatibility with existing servers, at the expense of efficiency. (The paper claims that characters such as '_' and '/', as used by #iodine and dns2tcp, are not standards-compliant, but that's not quite true: they are just outside of the maximum-compatibility set recommended by RFC 1035. The authors acknowledge this in the "Future Work" section.)

  • Uses CNAME exclusively.
  • Encodes with base32, using '0' as a padding character instead of '='.
  • Half duplex: client either sends a d data-carrying query and gets back an empty l length response; or sends an empty r request and gets back a d data-carrying response.
  • l responses encode the number of server-queued messages.
  • Fakes a low MTU (140 bytes) in order to avoid having to split IP datagrams across multiple DNS messages.
  • Eschews EDNS.
  • Caches responses so that duplicated queries get identical responses.

TUNS sample conversation

Taken from Fig. 2 of the paper.

  • message type: d for data, l for server queue length; r for data request
  • request counter, prevents caching
  • size of server queue
  • data

The client sends d data. The server responds with an l indicating that it has 4 responses in its queue.

Flags: 0x0100 Standard query
Queries
    dIUAAAVAAABAAAQABJ5K4BKBVAHAKQNICBAAAOS5TD4ASKPSQIJEM7VABAAEASC.MRTGQ2TMNY0.example.com: type CNAME, class IN
Flags: 0x8180 Standard query response, No error
Queries
    dIUAAAVAAABAAAQABJ5K4BKBVAHAKQNICBAAAOS5TD4ASKPSQIJEM7VABAAEASC.MRTGQ2TMNY0.example.com: type CNAME, class IN
Answers
    dIUAAAVAAABAAAQABJ5K4BKBVAHAKQNICBAAAOS5TD4ASKPSQIJEM7VABAAEASC.MRTGQ2TMNY0.example.com: type CNAME, class IN
        CNAME: l4.example.com

The client sends r data requests to drain the server's queue. The server sends back d data responses.

Flags: 0x0100 Standard query
Queries
    r882.example.com: type CNAME, class IN
Flags: 0x8180 Standard query response, No error
Queries
    r882.example.com: type CNAME, class IN
Answers
    r882.example.com: type CNAME, class IN
        CNAME: dIUAAAVCWIUAAAQABHVCY2DMO2HQ7EAQSEIZEEUTCOKBJFIVSYLJOF4YDC.MRTGQ2TMNY0.example.com

When the server's queue is empty, it sends back the pseudo-data zero. (Distinguishable from actual base32 data by its lack of padding, I suppose?)

Flags: 0x0100 Standard query
Queries
    r993.example.com: type CNAME, class IN
Flags: 0x8180 Standard query response, No error
Queries
    r993.example.com: type CNAME, class IN
Answers
    r993.example.com: type CNAME, class IN
        CNAME: dzero.example.com

OzymanDNS

OzymanDNS is a suite of DNS tools. droute.pl (client) and nomde.pl (server) implement a tunnel. It implements more of a netcat-like interface, but the code is old and crufty and doesn't work out of the box. Described in the talk Black Ops of DNS from 2004 (pages 12–17).

  • Uses TXT exclusively.
  • Uses base32 (without padding) in queries; base64 (padded, with newline breaks) in responses.
  • Supports long TXT records (multiple 255-byte-long strings concatenated in one resource record). Seems hardcoded to use exactly two TXT strings in a record.
  • For serializing messages, allows only one query or response in flight (like meek).
  • Sort-of has SEQ and ACK fields, but they seem advisory and not really used.
  • Half duplex: each query–response pair either sends a piece of data (up) or receives a piece of data (down), not both.
  • Responses encode the number of server-queued messages as the first byte of a pending A record in the Additional section.
  • Doesn't use EDNS in my tests, though the slides say Hi Bandwidth Payloads using EDNS are "Under Development". The #TUNS paper claims OzymanDNS uses EDNS.

OzymanDNS sample conversation

ozymandns.pcap

The nomde.pl server supports more than just DNS tunneling, so you have to scope your tunnel requests under a distinguished subdomain (here myservice).

  • function (up or down)
  • nonce, prevents caching
  • session ID
  • number of bytes sent (like a SEQ field, only in the client—though it is bugged and always remains 0)
  • number of bytes received (like an ACK field, only in the client)
  • size of server queue
  • data

The session is using session ID 35765. Here the client has sent no data and the server has sent back 12 bytes in response. The first byte 0 of the pending A record indicates that the server has no further data queued at the moment.

Transaction ID: 0x5aa8
Flags: 0x0100 Standard query
Queries
    0-27778.id-35765.down.myservice.example.com: type TXT, class IN
Transaction ID: 0x5aa8
Flags: 0x8500 Standard query response, No error
Queries
    0-27778.id-35765.down.myservice.example.com: type TXT, class IN
Answers
    0-27778.id-35765.down.myservice.example.com: type TXT, class IN
        TXT: aGVsbG8gd29ybGQK\n
        TXT: 
Additional records
    pending.0-27778.id-35765.down.myservice.example.com: type A, class IN
        Address: 0.0.0.0

Now the client has 18 bytes to send. It encodes them into an A query. The first byte 18 of the server's answer just echoes the number of bytes received.

Transaction ID: 0x9d9a
Flags: 0x0100 Standard query
Queries
    nbswy3dpebthe33nebrwy2lfnz2au.12010-0.id-35765.up.myservice.example.com: type A, class IN
Transaction ID: 0x9d9a
Flags: 0x8500 Standard query response, No error
Queries
    nbswy3dpebthe33nebrwy2lfnz2au.12010-0.id-35765.up.myservice.example.com: type A, class IN
Answers
    nbswy3dpebthe33nebrwy2lfnz2au.12010-0.id-35765.up.myservice.example.com: type A, class IN
        Address: 18.0.0.0

Now the client wants to send 273 bytes, which it splits up into 110+110+53.

Transaction ID: 0xa5d2
Flags: 0x0100 Standard query
Queries
    pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5h.u6t2pj\
    5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2.pj5hu6t2pj5h\
    u6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2.19517-0.id-35765.up.my\
    service.example.com: type A, class IN
Transaction ID: 0xa5d2
Flags: 0x8500 Standard query response, No error
Queries
    pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5h.u6t2pj\
    5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2.pj5hu6t2pj5h\
    u6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2.19517-0.id-35765.up.my\
    service.example.com: type A, class IN
Answers
    pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5h.u6t2pj\
    5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2.pj5hu6t2pj5h\
    u6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2.19517-0.id-35765.up.my\
    service.example.com: type A, class IN
        Address: 110.0.0.0
Transaction ID: 0x067f
Flags: 0x0100 Standard query
Queries
    pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5h.u6t2pj\
    5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2.pj5hu6t2pj5h\
    u6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2.15796-0.id-35765.up.my\
    service.example.com: type A, class IN
Transaction ID: 0x067f
Flags: 0x8500 Standard query response, No error
Queries
    pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5h.u6t2pj\
    5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2.pj5hu6t2pj5h\
    u6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2.15796-0.id-35765.up.my\
    service.example.com: type A, class IN
Answers
    pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5h.u6t2pj\
    5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2.pj5hu6t2pj5h\
    u6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2.15796-0.id-35765.up.my\
    service.example.com: type A, class IN
        Address: 110.0.0.0
Transaction ID: 0x663f
Flags: 0x0100 Standard query
Queries
    pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5h.u6t2pj5h\
    u6t2pj5hu6t2pj5au.34064-0.id-35765.up.myservice.example.com: type A, class IN
Transaction ID: 0x663f
Flags: 0x8500 Standard query response, No error
Queries
    pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5h.u6t2pj\
    5hu6t2pj5hu6t2pj5au.34064-0.id-35765.up.myservice.example.com: type A, class IN
Answers
    pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5hu6t2pj5h.u6t2pj\
    5hu6t2pj5hu6t2pj5au.34064-0.id-35765.up.myservice.example.com: type A, class IN
        Address: 53.0.0.0

Now the server has 298 bytes to send, which it splits up as 220+78. After the first send, the client increments its count of received bytes from 12 to 232 and the server indicates that it has 1 further response queued.

Transaction ID: 0x6afa
Flags: 0x0100 Standard query
Queries
    12-63032.id-35765.down.myservice.example.com: type TXT, class IN
Transaction ID: 0x6afa
Flags: 0x8500 Standard query response, No error
Queries
    12-63032.id-35765.down.myservice.example.com: type TXT, class IN
Answers
    12-63032.id-35765.down.myservice.example.com: type TXT, class IN
        TXT: eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4\n\
             eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHg=\n
        TXT: eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4\n\
             eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHg=\n
Additional records
    pending.12-63032.id-35765.down.myservice.example.com: type A, class IN
        Address: 1.0.0.0
Transaction ID: 0xa06c
Flags: 0x0100 Standard query
Queries
    232-7106.id-35765.down.myservice.example.com: type TXT, class IN
Transaction ID: 0xa06c
Flags: 0x8500 Standard query response, No error
Queries
    232-7106.id-35765.down.myservice.example.com: type TXT, class IN
Answers
    232-7106.id-35765.down.myservice.example.com: type TXT, class IN
        TXT: eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4\n\
             eHh4eHh4eHh4eHh4eHh4eHh4eHgK\n
        TXT: 
Additional records
    pending.232-7106.id-35765.down.myservice.example.com: type A, class IN
        Address: 0.0.0.0

iodine

iodine is a network-layer DNS tunnel. It has a lot of features, like password authentication, compression, and auto-probing of features like server case sensitivity and the MTU.

README Protocol documentation

  • Supports all of A, CNAME, MX, SRV, TXT, NULL, and PRIVATE resource records. NULL is like TXT but with slightly less overhead. PRIVATE uses a code in the private-use range, relying on other servers not to understand it and to leave it alone.
  • Queries can be encoded with any of (autodetected):
    • base32 (but a mutant base32 with a different alphabet: abcdefghijklmnopqrstuvwxyz012345)
    • base64 (again mutant with a different order and '-' and '+' in place of '+' and '/') if the server is case-preserving
    • base64u (same as base64 but with '_' in place of '+')
    • base128 (uses alphabet a-zA-Z0-9\xbc-\xfd) if the DNS path preserves case and the high bit
  • Full duplex: server can send data in response to data; client can also solicit data without sending anything, using a p ping packet.
  • Supports EDNS for long replies.
  • Caches responses so that duplicated queries get identical responses.
  • Complicated.

iodine sample conversation

iodine.pcap

The iodine trace is more complicated than I want to walk through fully.

The first byte of queries indicates the type: v means version, l is login, s is switch codec, etc. Hex digits 0-9a-f represent a user ID and indicate an actual data packet (which means there can only be 16 simultaneous users of the tunnel).

Here is a sample data transaction. The client and server have negotiated the base128 codec and the NULL record type. The client with user ID 0 sends a data packet and the server responds with no data (just a two-byte data header \xa0\x20). Note the client signals support for EDNS in the Additional section.

Transaction ID: 0x5607
Flags: 0x0100 Standard query
Queries
     0iabb82\xca2hb\xbe\xeeY\xd6bp\xc9\xcdNb\xde\xdeQFzWUdb\xc2\xe0dB\
     \xc6\xdeS\xdbO\xe3\xdagdqP\xf9\xcc\xefGiHLoy\xdeLaWfcHW.\xc2Qtl\
     \xc2s\xc7u\xd8Jv\xc7\xe3\xf0fI\xc7S\xcfQ\xd2\xe8\xf3g\xd1L\xd4\
     \xe6\xf369\xbc\xbe\xe6YBmM\xd1z\xda\xdei\xc98B\xf9.example.com: type NULL, class IN
Additional records
    <Root>: type OPT
        UDP payload size: 4096
        Higher bits in extended RCODE: 0x00
        EDNS0 version: 0
        Z: 0x8000
Transaction ID: 0x5607
Flags: 0x8400 Standard query response, No error
Queries
     0iabb82\xca2hb\xbe\xeeY\xd6bp\xc9\xcdNb\xde\xdeQFzWUdb\xc2\xe0dB\
     \xc6\xdeS\xdbO\xe3\xdagdqP\xf9\xcc\xefGiHLoy\xdeLaWfcHW.\xc2Qtl\
     \xc2s\xc7u\xd8Jv\xc7\xe3\xf0fI\xc7S\xcfQ\xd2\xe8\xf3g\xd1L\xd4\
     \xe6\xf369\xbc\xbe\xe6YBmM\xd1z\xda\xdei\xc98B\xf9.example.com: type NULL, class IN
Answers
     0iabb82\xca2hb\xbe\xeeY\xd6bp\xc9\xcdNb\xde\xdeQFzWUdb\xc2\xe0dB\
     \xc6\xdeS\xdbO\xe3\xdagdqP\xf9\xcc\xefGiHLoy\xdeLaWfcHW.\xc2Qtl\
     \xc2s\xc7u\xd8Jv\xc7\xe3\xf0fI\xc7S\xcfQ\xd2\xe8\xf3g\xd1L\xd4\
     \xe6\xf369\xbc\xbe\xe6YBmM\xd1z\xda\xdei\xc98B\xf9.example.com: type NULL, class IN
        Null (data): \xa0\x20

Here the client sends a p ping message. The server responds with a blob of unencoded data.

Transaction ID: 0x7436
Flags: 0x0100 Standard query
Queries
    paaifhjy.example.com: type NULL, class IN
Additional records
    <Root>: type OPT
        UDP payload size: 4096
        Higher bits in extended RCODE: 0x00
        EDNS0 version: 0
        Z: 0x8000
Transaction ID: 0x7436
Flags: 0x8400 Standard query response, No error
Queries
    paaifhjy.example.com: type NULL, class IN
Answers
    paaifhjy.example.com: type NULL, class IN
        Null (data): \xb0Ax\xdac`\xe0`pe`\x089\xbf\x8f\x81\xc1\x81q\xda\
                     \x0b.\x06\x06F fb`\xe8\xba\xa6-\xc0\xc0\xc4%\xf7;\
                     \x8a\x01\x08\x9aO3\x81(\x06\x01A!a\x11Q1q\tI)i\x19\
                     Y9y\x05E%e\x15U5u\rM-m\x1d]=}\x03C#c\x13S3s\x00\
                     \x84\xa9\r\xfb

Others

  • NSTX (predecessor of #iodine?)
    • According to the #TUNS paper, uses TXT and base64 ([A-Za-z0-9_-]).
  • dns2tcp
    • According to the #TUNS paper, uses TXT and base64 ([A-Za-z0-9/-]).
  • DNScat by Tadek Pietraszek – different than the similarly named dnscat by Ron Bowes that was the predecessor of #dnscat2
Last modified 4 months ago Last modified on May 15, 2018, 10:19:24 PM

Attachments (4)

  • dnscat2.pcapng (125.8 KB) - added by dcf 4 months ago. server: ruby ./dnscat2.rb --dns 'host=127.0.0.1,port=5353,domain=example.com' --security open client: ./dnscat --no-encryption --dns=server=127.0.0.1,port=5353,domain=example.com
  • ozymandns.pcap (8.9 KB) - added by dcf 4 months ago. server: ./nomde.pl -i 127.0.0.1 -L myservice:127.0.0.1:8000 example.com client: ./droute.pl -r 127.0.0.1 myservice.example.com also needs netcat listener on port 8000 and ozymandns.patch.
  • ozymandns.patch (1.6 KB) - added by dcf 4 months ago. Patch I needed to get OzymanDNS 0.1 to work.
  • iodine.pcap (17.1 KB) - added by dcf 4 months ago. server: iodined -f -l 192.168.0.64 -P password 10.0.0.1 example.com client: iodine -f -r -P password -I 50 192.168.0.64 example.com

Download all attachments as: .zip