Apply conversion script to all *.md files. authored by Alexander Hansen Færøy's avatar Alexander Hansen Færøy
...@@ -30,11 +30,12 @@ Summary ...@@ -30,11 +30,12 @@ Summary
* Supports EDNS for long replies. * Supports EDNS for long replies.
* Complicated. * Complicated.
The terms "quarter duplex", "half duplex", and "full duplex" describe how the upstream and downstream data channels may be used simultaneously, or not. Quarter duplex is not a standard term, but [https://en.wikipedia.org/wiki/Duplex_(telecommunications)#Half_duplex half duplex] and [https://en.wikipedia.org/wiki/Duplex_(telecommunications)#Full_duplex full duplex] are. The table below shows what I mean by them. Suppose the client has 3 pieces of data to send (UP1, UP2, UP3) and the server also has 3 pieces of data to send (DOWN1, DOWN2, DOWN3). The terms "quarter duplex", "half duplex", and "full duplex" describe how the upstream and downstream data channels may be used simultaneously, or not. Quarter duplex is not a standard term, but [half duplex](https://en.wikipedia.org/wiki/Duplex_(telecommunications)#Half_duplex) and [full duplex](https://en.wikipedia.org/wiki/Duplex_(telecommunications)#Full_duplex) are. The table below shows what I mean by them. Suppose the client has 3 pieces of data to send (UP1, UP2, UP3) and the server also has 3 pieces of data to send (DOWN1, DOWN2, DOWN3).
||= Quarter duplex =||= Half duplex =||= Full duplex =|| |= Quarter duplex =|= Half duplex =|= Full duplex =|
|------------------|---------------|---------------|
|----------------- |-----------------
{{{#!td valign=top ```
{{{ {{{
[UP1] --> [UP1] -->
<-- [ok] <-- [ok]
...@@ -48,9 +49,9 @@ The terms "quarter duplex", "half duplex", and "full duplex" describe how the up ...@@ -48,9 +49,9 @@ The terms "quarter duplex", "half duplex", and "full duplex" describe how the up
<-- [ok] <-- [ok]
[poll] --> [poll] -->
<-- [DOWN3] <-- [DOWN3]
```
}}} }}}
}}} ```
{{{#!td valign=top
{{{ {{{
[UP1] --> [UP1] -->
<-- [DOWN1] <-- [DOWN1]
...@@ -58,9 +59,9 @@ The terms "quarter duplex", "half duplex", and "full duplex" describe how the up ...@@ -58,9 +59,9 @@ The terms "quarter duplex", "half duplex", and "full duplex" describe how the up
<-- [DOWN2] <-- [DOWN2]
[UP3] --> [UP3] -->
<-- [DOWN3] <-- [DOWN3]
```
}}} }}}
}}} ```
{{{#!td valign=top
{{{ {{{
[UP1] --> [UP1] -->
[UP2] --> [UP2] -->
...@@ -68,35 +69,36 @@ The terms "quarter duplex", "half duplex", and "full duplex" describe how the up ...@@ -68,35 +69,36 @@ The terms "quarter duplex", "half duplex", and "full duplex" describe how the up
[UP3] --> [UP3] -->
<-- [DOWN2] <-- [DOWN2]
<-- [DOWN3] <-- [DOWN3]
}}} ```
}}} }}}
|----------------- |-----------------
||In a single query–response exchange, either the query carries data, or the response carries data, but not both. Sending and receiving 3 pieces of data requires 6 sequential roundtrips.||In a single query–response exchange, both the query and response may carry data, but queries and responses must serialized in a ping-pong fashion. Sending and receiving 3 pieces of data requires 3 sequential roundtrips.||Both queries and responses may carry data, and there is no requirement for one exchange to be finished before starting another one. Sending and receiving 3 pieces of data requires 3 roundtrips, but they may be interleaved.|| |In a single query–response exchange, either the query carries data, or the response carries data, but not both. Sending and receiving 3 pieces of data requires 6 sequential roundtrips.|In a single query–response exchange, both the query and response may carry data, but queries and responses must serialized in a ping-pong fashion. Sending and receiving 3 pieces of data requires 3 sequential roundtrips.|Both queries and responses may carry data, and there is no requirement for one exchange to be finished before starting another one. Sending and receiving 3 pieces of data requires 3 roundtrips, but they may be interleaved.|
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
= General observations = # 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. 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 [https://tools.ietf.org/html/rfc1035#section-4.1.1 syntactically permits] sending any number of entries in the Question section, in practice the only supported value is QDCOUNT=1. Upstream queries are more squeezed for bandwidth than downstream responses. Although the protocol [syntactically permits](https://tools.ietf.org/html/rfc1035#section-4.1.1) sending any number of entries in the Question section, in practice the only supported value is QDCOUNT=1.
* https://stackoverflow.com/questions/4082081/requesting-a-and-aaaa-records-in-single-dns-query#4083071 * https://stackoverflow.com/questions/4082081/requesting-a-and-aaaa-records-in-single-dns-query#4083071
* https://groups.google.com/forum/?hl=en#!topic/comp.protocols.dns.bind/uOWxNkm7AVg * https://groups.google.com/forum/?hl=en#!topic/comp.protocols.dns.bind/uOWxNkm7AVg
* http://maradns.samiam.org/multiple.qdcount.html * http://maradns.samiam.org/multiple.qdcount.html
A single DNS name has a maximum length of 255 bytes ([https://tools.ietf.org/html/rfc1035#section-2.3.4 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. A single DNS name has a maximum length of 255 bytes ([RFC 1035 §2.3.4](https://tools.ietf.org/html/rfc1035#section-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, [https://tools.ietf.org/html/rfc2181#section-11 any 8-bit value] can be part of a name label. However RFC 1035 [https://tools.ietf.org/html/rfc1035#section-2.3.1 recommends] `[A-Za-z][A-Za-z0-9-]*` for compatibility. Additionally, you can't rely on uppercase/lowercase being preserved ([https://developers.google.com/speed/public-dns/docs/security?hl=en#randomize_case 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. Technically, [any 8-bit value](https://tools.ietf.org/html/rfc2181#section-11) can be part of a name label. However RFC 1035 [recommends](https://tools.ietf.org/html/rfc1035#section-2.3.1) `[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](https://developers.google.com/speed/public-dns/docs/security?hl=en#randomize_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 [https://tools.ietf.org/html/rfc6891#section-6 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.)'' 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](https://tools.ietf.org/html/rfc6891#section-6) 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 ([https://tools.ietf.org/html/rfc1035#section-3.4.1 A], [https://tools.ietf.org/html/rfc3596#section-2 AAAA], [https://tools.ietf.org/html/rfc1035#section-3.3.9 MX], [https://tools.ietf.org/html/rfc1035#section-3.3.1 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 [https://tools.ietf.org/html/rfc1035#section-3.3.14 TXT] type seems practical: it's a byte sequence of any length up to the 64K limit. (The [https://github.com/iagox86/dnscat2/blob/master/doc/protocol.md#dns-record-type 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 [https://tools.ietf.org/html/rfc1035#section-3.3.10 NULL] type is marginally more efficient than TXT, but is marked "experimental". 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](https://tools.ietf.org/html/rfc1035#section-3.4.1), [AAAA](https://tools.ietf.org/html/rfc3596#section-2), [MX](https://tools.ietf.org/html/rfc1035#section-3.3.9), [CNAME](https://tools.ietf.org/html/rfc1035#section-3.3.1), 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](https://tools.ietf.org/html/rfc1035#section-3.3.14) type seems practical: it's a byte sequence of any length up to the 64K limit. (The [dnscat2 docs](https://github.com/iagox86/dnscat2/blob/master/doc/protocol.md#dns-record-type) 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](https://tools.ietf.org/html/rfc1035#section-3.3.10) 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 [https://tools.ietf.org/html/rfc6891#section-6.1.2 UDP payload size] field is 16 bits, and anyway that's the largest IP datagram size); or TCP (messages are preceded by a [https://tools.ietf.org/html/rfc1035#section-4.2.2 16-bit length field]). In the absence of EDNS, UDP responses are supposed to be [https://tools.ietf.org/html/rfc1035#section-4.2.1 limited to 512 bytes]. But as EDNS has good support, the [https://en.wikipedia.org/wiki/Maximum_transmission_unit MTU] is likely a bigger consideration than any DNS-imposed length limitations. A common value for the EDNS length field is 4096. 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](https://tools.ietf.org/html/rfc6891#section-6.1.2) field is 16 bits, and anyway that's the largest IP datagram size); or TCP (messages are preceded by a [16-bit length field](https://tools.ietf.org/html/rfc1035#section-4.2.2)). In the absence of EDNS, UDP responses are supposed to be [limited to 512 bytes](https://tools.ietf.org/html/rfc1035#section-4.2.1). But as EDNS has good support, the [MTU](https://en.wikipedia.org/wiki/Maximum_transmission_unit) is likely a bigger consideration than any DNS-imposed length limitations. A common value for the EDNS length field is 4096.
= dnscat2 = # dnscat2
[https://github.com/iagox86/dnscat2/blob/master/doc/protocol.md 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. [dnscat2](https://github.com/iagox86/dnscat2/blob/master/doc/protocol.md) 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 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). * Uses CNAME, MX, TXT (randomly selected) by default. Also supports A and AAAA (use `type=A,AAAA` with the `--dns` option).
...@@ -109,7 +111,7 @@ The overall length of a DNS response message cannot be more than 65535 bytes. Th ...@@ -109,7 +111,7 @@ The overall length of a DNS response message cannot be more than 65535 bytes. Th
* Doesn't use EDNS. * Doesn't use EDNS.
MESSAGE_TYPE_SYN:: MESSAGE_TYPE_SYN::
{{{ ```
#!html #!html
<pre> <pre>
<span style="background:skyblue">packet_id u16</span> <span style="background:skyblue">packet_id u16</span>
...@@ -145,9 +147,9 @@ The overall length of a DNS response message cannot be more than 65535 bytes. Th ...@@ -145,9 +147,9 @@ The overall length of a DNS response message cannot be more than 65535 bytes. Th
</pre> </pre>
}}} }}}
== dnscat2 sample conversation == ## dnscat2 sample conversation
[[attachment:dnscat2.pcapng]] [dnscat2.pcapng](None/dnscat2.pcapng)
{{{ {{{
#!comment #!comment
...@@ -155,12 +157,11 @@ dnscat2/server$ bundle install --path vendor/bundle ...@@ -155,12 +157,11 @@ dnscat2/server$ bundle install --path vendor/bundle
dnscat2/server$ GEM_PATH=$PWD/vendor/bundle/ruby/2.5.0 ruby ./dnscat2.rb --dns 'host=127.0.0.1,port=5353,domain=example.com' --security open dnscat2/server$ GEM_PATH=$PWD/vendor/bundle/ruby/2.5.0 ruby ./dnscat2.rb --dns 'host=127.0.0.1,port=5353,domain=example.com' --security open
./dnscat --no-encryption --dns=server=127.0.0.1,port=5353,domain=example.com ./dnscat --no-encryption --dns=server=127.0.0.1,port=5353,domain=example.com
tshark -d udp.port==5353,dns -V -n -r dnscat2.pcapng tshark -d udp.port==5353,dns -V -n -r dnscat2.pcapng
}}} ```
Starts with a [[span(MESSAGE_TYPE_SYN,style=background:coral)]] exchange. The session ID is [[span(48ac,style=background:skyblue)]]. The client and server choose initial sequence numbers of [[span(9037,style=background:orange)]] and [[span(7643,style=background:orange)]] respectively. The client additionally sends a session name of [[span(!command (happy),style=background:lightgray)]]. Starts with a [[span(MESSAGE_TYPE_SYN,style=background:coral)]] exchange. The session ID is [[span(48ac,style=background:skyblue)]]. The client and server choose initial sequence numbers of [[span(9037,style=background:orange)]] and [[span(7643,style=background:orange)]] respectively. The client additionally sends a session name of [[span(!command (happy),style=background:lightgray)]].
{{{ ```
#!html
<pre style="background:cornsilk"> <pre style="background:cornsilk">
Transaction ID: 0xfe47 Transaction ID: 0xfe47
Flags: 0x0100 Standard query Flags: 0x0100 Standard query
...@@ -178,12 +179,11 @@ Answers ...@@ -178,12 +179,11 @@ Answers
TXT: <span style="background:skyblue">3da5</span><span style="background:coral">00</span><span style="background:springgreen">48ac</span><span style="background:orange">7643</span>0000 TXT: <span style="background:skyblue">3da5</span><span style="background:coral">00</span><span style="background:springgreen">48ac</span><span style="background:orange">7643</span>0000
</pre> </pre>
</blockquote> </blockquote>
}}} ```
Client and server exchange empty [[span(MESSAGE_TYPE_MSG,style=background:coral)]] packets while the connection is idle. (Notice [[span(SEQ,style=background:orange)]] and [[span(ACK,style=background:olive)]] don't change.) Client and server exchange empty [[span(MESSAGE_TYPE_MSG,style=background:coral)]] packets while the connection is idle. (Notice [[span(SEQ,style=background:orange)]] and [[span(ACK,style=background:olive)]] don't change.)
{{{ ```
#!html
<pre style="background:cornsilk"> <pre style="background:cornsilk">
Transaction ID: 0xc641 Transaction ID: 0xc641
Flags: 0x0100 Standard query Flags: 0x0100 Standard query
...@@ -201,12 +201,11 @@ Answers ...@@ -201,12 +201,11 @@ Answers
TXT: <span style="background:skyblue">41e8</span><span style="background:coral">01</span><span style="background:springgreen">48ac</span><span style="background:orange">7643</span><span style="background:olive">9037</span> TXT: <span style="background:skyblue">41e8</span><span style="background:coral">01</span><span style="background:springgreen">48ac</span><span style="background:orange">7643</span><span style="background:olive">9037</span>
</pre> </pre>
</blockquote> </blockquote>
}}} ```
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. 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.
{{{ ```
#!html
<pre style="background:cornsilk"> <pre style="background:cornsilk">
Transaction ID: 0xf33d Transaction ID: 0xf33d
Flags: 0x0100 Standard query Flags: 0x0100 Standard query
...@@ -224,12 +223,11 @@ Answers ...@@ -224,12 +223,11 @@ Answers
CNAME: <span style="background:skyblue">8400</span><span style="background:coral">01</span><span style="background:springgreen">48ac</span><span style="background:orange">7643</span><span style="background:olive">9037</span><span style="background:lightgray">0000000d00010003646e736361742e6300</span>.example.com CNAME: <span style="background:skyblue">8400</span><span style="background:coral">01</span><span style="background:springgreen">48ac</span><span style="background:orange">7643</span><span style="background:olive">9037</span><span style="background:lightgray">0000000d00010003646e736361742e6300</span>.example.com
</pre> </pre>
</blockquote> </blockquote>
}}} ```
The client sends 101 bytes. Notice the client's ACK has advanced 17 bytes from 7643 to [[span(7654,style=background:olive)]]. 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 [[span(909c,style=background:olive)]]. The client sends 101 bytes. Notice the client's ACK has advanced 17 bytes from 7643 to [[span(7654,style=background:olive)]]. 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 [[span(909c,style=background:olive)]].
{{{ ```
#!html
<pre style="background:cornsilk"> <pre style="background:cornsilk">
Transaction ID: 0x6272 Transaction ID: 0x6272
Flags: 0x0100 Standard query Flags: 0x0100 Standard query
...@@ -256,12 +254,12 @@ Answers ...@@ -256,12 +254,12 @@ Answers
TXT: <span style="background:skyblue">018b</span><span style="background:coral">01</span><span style="background:springgreen">48ac</span><span style="background:orange">7654</span><span style="background:olive">909c</span> TXT: <span style="background:skyblue">018b</span><span style="background:coral">01</span><span style="background:springgreen">48ac</span><span style="background:orange">7654</span><span style="background:olive">909c</span>
</pre> </pre>
</blockquote> </blockquote>
}}} ```
= TUNS = # TUNS
[https://members.loria.fr/LNussbaum/tuns.html TUNS] is an IP-layer (VPN-like) tunnel described in the paper [https://members.loria.fr/LNussbaum/files/tuns-sec09-article.pdf "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.) [TUNS](https://members.loria.fr/LNussbaum/tuns.html) is an IP-layer (VPN-like) tunnel described in the paper ["On Robust Covert Channels Inside DNS"](https://members.loria.fr/LNussbaum/files/tuns-sec09-article.pdf) 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. * Uses CNAME exclusively.
* Encodes with base32, using `'0'` as a padding character instead of `'='`. * Encodes with base32, using `'0'` as a padding character instead of `'='`.
...@@ -271,9 +269,9 @@ Answers ...@@ -271,9 +269,9 @@ Answers
* Eschews EDNS. * Eschews EDNS.
* Caches responses so that duplicated queries get identical responses. * Caches responses so that duplicated queries get identical responses.
== TUNS sample conversation == ## TUNS sample conversation
Taken from [https://members.loria.fr/LNussbaum/files/tuns-sec09-article.pdf#page=6 Fig. 2] of the paper. Taken from [Fig. 2](https://members.loria.fr/LNussbaum/files/tuns-sec09-article.pdf#page=6) of the paper.
* [[span(message type,style=background:coral)]]: `d` for data, `l` for server queue length; `r` for data request * [[span(message type,style=background:coral)]]: `d` for data, `l` for server queue length; `r` for data request
* [[span(request counter,style=background:skyblue)]], prevents caching * [[span(request counter,style=background:skyblue)]], prevents caching
...@@ -282,8 +280,7 @@ Taken from [https://members.loria.fr/LNussbaum/files/tuns-sec09-article.pdf#page ...@@ -282,8 +280,7 @@ Taken from [https://members.loria.fr/LNussbaum/files/tuns-sec09-article.pdf#page
The client sends [[span(d,style=background:coral)]] data. The server responds with an [[span(l,style=background:coral)]] indicating that it has [[span(4,style=background:gold)]] responses in its queue. The client sends [[span(d,style=background:coral)]] data. The server responds with an [[span(l,style=background:coral)]] indicating that it has [[span(4,style=background:gold)]] responses in its queue.
{{{ ```
#!html
<pre style="background:cornsilk"> <pre style="background:cornsilk">
Flags: 0x0100 Standard query Flags: 0x0100 Standard query
Queries Queries
...@@ -299,12 +296,11 @@ Answers ...@@ -299,12 +296,11 @@ Answers
CNAME: <span style="background:coral">l</span><span style="background:gold">4</span>.example.com CNAME: <span style="background:coral">l</span><span style="background:gold">4</span>.example.com
</pre> </pre>
</blockquote> </blockquote>
}}} ```
The client sends [[span(r,style=background:coral)]] data requests to drain the server's queue. The server sends back [[span(d,style=background:coral)]] data responses. The client sends [[span(r,style=background:coral)]] data requests to drain the server's queue. The server sends back [[span(d,style=background:coral)]] data responses.
{{{ ```
#!html
<pre style="background:cornsilk"> <pre style="background:cornsilk">
Flags: 0x0100 Standard query Flags: 0x0100 Standard query
Queries Queries
...@@ -320,12 +316,11 @@ Answers ...@@ -320,12 +316,11 @@ Answers
CNAME: <span style="background:coral">d</span><span style="background:lightgray">IUAAAVCWIUAAAQABHVCY2DMO2HQ7EAQSEIZEEUTCOKBJFIVSYLJOF4YDC</span>.<span style="background:lightgray">MRTGQ2TMNY0</span>.example.com CNAME: <span style="background:coral">d</span><span style="background:lightgray">IUAAAVCWIUAAAQABHVCY2DMO2HQ7EAQSEIZEEUTCOKBJFIVSYLJOF4YDC</span>.<span style="background:lightgray">MRTGQ2TMNY0</span>.example.com
</pre> </pre>
</blockquote> </blockquote>
}}} ```
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?) 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?)
{{{ ```
#!html
<pre style="background:cornsilk"> <pre style="background:cornsilk">
Flags: 0x0100 Standard query Flags: 0x0100 Standard query
Queries Queries
...@@ -341,31 +336,30 @@ Answers ...@@ -341,31 +336,30 @@ Answers
CNAME: <span style="background:coral">d</span>zero.example.com CNAME: <span style="background:coral">d</span>zero.example.com
</pre> </pre>
</blockquote> </blockquote>
}}} ```
= OzymanDNS = # OzymanDNS
[https://dankaminsky.com/2004/07/29/51/ 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 [https://events.ccc.de/congress/2004/fahrplan/files/297-black-ops-of-dns-slides.pdf "Black Ops of DNS"] from 2004 (pages 12–17). [OzymanDNS](https://dankaminsky.com/2004/07/29/51/) 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"](https://events.ccc.de/congress/2004/fahrplan/files/297-black-ops-of-dns-slides.pdf) from 2004 (pages 12–17).
* Uses TXT exclusively. * Uses TXT exclusively.
* Uses base32 (without padding) in queries; base64 (padded, with newline breaks) in responses. * 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. * 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 ([https://www.bamsoftware.com/papers/fronting/#sec:deploy-tor like meek]). * For serializing messages, allows only one query or response in flight ([like meek](https://www.bamsoftware.com/papers/fronting/#sec:deploy-tor)).
* Sort-of has SEQ and ACK fields, but they seem advisory and not really used. * Sort-of has SEQ and ACK fields, but they seem advisory and not really used.
* Quarter duplex: each query–response pair either sends a piece of data (`up`) or receives a piece of data (`down`), not both. * Quarter 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. * 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 [https://events.ccc.de/congress/2004/fahrplan/files/297-black-ops-of-dns-slides.pdf#page=7 the slides] say Hi Bandwidth Payloads using EDNS are "Under Development". The [[#TUNS]] paper claims OzymanDNS uses EDNS. * Doesn't use EDNS in my tests, though [the slides](https://events.ccc.de/congress/2004/fahrplan/files/297-black-ops-of-dns-slides.pdf#page=7) say Hi Bandwidth Payloads using EDNS are "Under Development". The [[#TUNS]] paper claims OzymanDNS uses EDNS.
== OzymanDNS sample conversation == ## OzymanDNS sample conversation
[[attachment:ozymandns.pcap]] [ozymandns.pcap](None/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`). The nomde.pl server supports more than just DNS tunneling, so you have to scope your tunnel requests under a distinguished subdomain (here `myservice`).
{{{ ```
#!comment [ozymandns.patch](None/ozymandns.patch)
[[attachment:ozymandns.patch]]
ncat -lkv 8000 ncat -lkv 8000
./nomde.pl -i 127.0.0.1 -L myservice:127.0.0.1:8000 example.com ./nomde.pl -i 127.0.0.1 -L myservice:127.0.0.1:8000 example.com
./droute.pl -r 127.0.0.1 myservice.example.com ./droute.pl -r 127.0.0.1 myservice.example.com
...@@ -374,7 +368,7 @@ howto: ...@@ -374,7 +368,7 @@ howto:
* https://www.splitbrain.org/blog/2008-11/02-dns_tunneling_made_simple * https://www.splitbrain.org/blog/2008-11/02-dns_tunneling_made_simple
* https://room362.com/post/2009/2009310ozymandns-tunneling-ssh-over-dns-html/ * https://room362.com/post/2009/2009310ozymandns-tunneling-ssh-over-dns-html/
* http://dnstunnel.de/ - mentioned the "sshdns" subdomain step * http://dnstunnel.de/ - mentioned the "sshdns" subdomain step
}}} ```
* [[span(function,style=background:coral)]] (`up` or `down`) * [[span(function,style=background:coral)]] (`up` or `down`)
* [[span(nonce,style=background:skyblue)]], prevents caching * [[span(nonce,style=background:skyblue)]], prevents caching
...@@ -386,8 +380,7 @@ howto: ...@@ -386,8 +380,7 @@ howto:
The session is using session ID [[span(35765,style=background:springgreen)]]. Here the client has sent no data and the server has sent back 12 bytes in response. The first byte [[span(0,style=background:gold)]] of the `pending` A record indicates that the server has no further data queued at the moment. The session is using session ID [[span(35765,style=background:springgreen)]]. Here the client has sent no data and the server has sent back 12 bytes in response. The first byte [[span(0,style=background:gold)]] of the `pending` A record indicates that the server has no further data queued at the moment.
{{{ ```
#!html
<pre style="background:cornsilk"> <pre style="background:cornsilk">
Transaction ID: 0x5aa8 Transaction ID: 0x5aa8
Flags: 0x0100 Standard query Flags: 0x0100 Standard query
...@@ -409,12 +402,11 @@ Additional records ...@@ -409,12 +402,11 @@ Additional records
Address: <span style="background:gold">0</span>.0.0.0 Address: <span style="background:gold">0</span>.0.0.0
</pre> </pre>
</blockquote> </blockquote>
}}} ```
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. 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.
{{{ ```
#!html
<pre style="background:cornsilk"> <pre style="background:cornsilk">
Transaction ID: 0x9d9a Transaction ID: 0x9d9a
Flags: 0x0100 Standard query Flags: 0x0100 Standard query
...@@ -432,12 +424,11 @@ Answers ...@@ -432,12 +424,11 @@ Answers
Address: 18.0.0.0 Address: 18.0.0.0
</pre> </pre>
</blockquote> </blockquote>
}}} ```
Now the client wants to send 273 bytes, which it splits up into 110+110+53. Now the client wants to send 273 bytes, which it splits up into 110+110+53.
{{{ ```
#!html
<pre style="background:cornsilk"> <pre style="background:cornsilk">
Transaction ID: 0xa5d2 Transaction ID: 0xa5d2
Flags: 0x0100 Standard query Flags: 0x0100 Standard query
...@@ -510,12 +501,11 @@ Answers ...@@ -510,12 +501,11 @@ Answers
Address: 53.0.0.0 Address: 53.0.0.0
</pre> </pre>
</blockquote> </blockquote>
}}} ```
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 [[span(232,style=background:olive)]] and the server indicates that it has [[span(1,style=background:gold)]] further response queued. 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 [[span(232,style=background:olive)]] and the server indicates that it has [[span(1,style=background:gold)]] further response queued.
{{{ ```
#!html
<pre style="background:cornsilk"> <pre style="background:cornsilk">
Transaction ID: 0x6afa Transaction ID: 0x6afa
Flags: 0x0100 Standard query Flags: 0x0100 Standard query
...@@ -561,18 +551,18 @@ Additional records ...@@ -561,18 +551,18 @@ Additional records
Address: <span style="background:gold">0</span>.0.0.0 Address: <span style="background:gold">0</span>.0.0.0
</pre> </pre>
</blockquote> </blockquote>
}}} ```
= iodine = # iodine
[https://code.kryo.se/iodine/ iodine] is a network-layer DNS tunnel. [iodine](https://code.kryo.se/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. It has a lot of features, like password authentication, compression, and auto-probing of features like server case sensitivity and the MTU.
[https://code.kryo.se/iodine/README.html README] [README](https://code.kryo.se/iodine/README.html)
[https://github.com/yarrick/iodine/blob/master/doc/proto_00000502.txt Protocol documentation] [Protocol documentation](https://github.com/yarrick/iodine/blob/master/doc/proto_00000502.txt)
* 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 [https://tools.ietf.org/html/rfc6895#section-3.1 private-use range], relying on other servers [https://tools.ietf.org/html/rfc3597#section-3 not to understand it and to leave it alone]. * 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](https://tools.ietf.org/html/rfc6895#section-3.1), relying on other servers [not to understand it and to leave it alone](https://tools.ietf.org/html/rfc3597#section-3).
* Queries can be encoded with any of (autodetected): * Queries can be encoded with any of (autodetected):
* base32 (but a mutant base32 with a different alphabet: `abcdefghijklmnopqrstuvwxyz012345`) * 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 * base64 (again mutant with a different order and `'-'` and `'+'` in place of `'+'` and `'/'`) if the server is case-preserving
...@@ -583,16 +573,15 @@ It has a lot of features, like password authentication, compression, and auto-pr ...@@ -583,16 +573,15 @@ It has a lot of features, like password authentication, compression, and auto-pr
* Caches responses so that duplicated queries get identical responses. * Caches responses so that duplicated queries get identical responses.
* Complicated. * Complicated.
== iodine sample conversation == ## iodine sample conversation
{{{ ```
#!comment
iodined -f -l 192.168.0.64 -P password 10.0.0.1 example.com iodined -f -l 192.168.0.64 -P password 10.0.0.1 example.com
iodine -f -r -P password -I 50 192.168.0.64 example.com iodine -f -r -P password -I 50 192.168.0.64 example.com
ping 10.0.0.1 ping 10.0.0.1
}}} ```
[[attachment:iodine.pcap]] [iodine.pcap](None/iodine.pcap)
The iodine trace is more complicated than I want to walk through fully. The iodine trace is more complicated than I want to walk through fully.
...@@ -600,8 +589,7 @@ The first byte of queries indicates the type: `v` means version, `l` is login, ` ...@@ -600,8 +589,7 @@ The first byte of queries indicates the type: `v` means version, `l` is login, `
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. 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.
{{{ ```
#!html
<pre style="background:cornsilk"> <pre style="background:cornsilk">
Transaction ID: 0x5607 Transaction ID: 0x5607
Flags: 0x0100 Standard query Flags: 0x0100 Standard query
...@@ -634,12 +622,11 @@ Answers ...@@ -634,12 +622,11 @@ Answers
Null (data): \xa0\x20 Null (data): \xa0\x20
</pre> </pre>
</blockquote> </blockquote>
}}} ```
Here the client sends a `p` ping message. The server responds with a blob of unencoded data. Here the client sends a `p` ping message. The server responds with a blob of unencoded data.
{{{ ```
#!html
<pre style="background:cornsilk"> <pre style="background:cornsilk">
Transaction ID: 0x7436 Transaction ID: 0x7436
Flags: 0x0100 Standard query Flags: 0x0100 Standard query
...@@ -667,15 +654,15 @@ Answers ...@@ -667,15 +654,15 @@ Answers
<span style="background:lightgray">\x84\xa9\r\xfb</span> <span style="background:lightgray">\x84\xa9\r\xfb</span>
</pre> </pre>
</blockquote> </blockquote>
}}} ```
= Others = # Others
* [http://thomer.com/howtos/nstx.html NSTX] (predecessor of [[#iodine]]?) * [NSTX](http://thomer.com/howtos/nstx.html) (predecessor of [[#iodine]]?)
* According to the [[#TUNS]] paper, uses TXT and base64 (`[A-Za-z0-9_-]`). * According to the [[#TUNS]] paper, uses TXT and base64 (`[A-Za-z0-9_-]`).
* [https://tools.kali.org/maintaining-access/dns2tcp dns2tcp] * [dns2tcp](https://tools.kali.org/maintaining-access/dns2tcp)
* According to the [[#TUNS]] paper, uses TXT and base64 (`[A-Za-z0-9/-]`). * According to the [[#TUNS]] paper, uses TXT and base64 (`[A-Za-z0-9/-]`).
* [http://tadek.pietraszek.org/projects/DNScat/index.html DNScat] by Tadek Pietraszek – ''different'' than the similarly named [https://wiki.skullsecurity.org/Dnscat dnscat] by Ron Bowes that was the predecessor of [[#dnscat2]] * [DNScat](http://tadek.pietraszek.org/projects/DNScat/index.html) by Tadek Pietraszek – _different_ than the similarly named [dnscat](https://wiki.skullsecurity.org/Dnscat) by Ron Bowes that was the predecessor of [[#dnscat2]]
* [https://github.com/fbkcs/ThunderDNS ThunderDNS] * [ThunderDNS](https://github.com/fbkcs/ThunderDNS)
* [http://heyoka.sourceforge.net/ Heyoka] * [Heyoka](http://heyoka.sourceforge.net/)
\ No newline at end of file \ No newline at end of file