Last Updated: 2011-05-03 16:02:06 UTC
by Johannes Ullrich (Version: 1)
The Teredo protocol , originally developed by Microsoft but since adopted by Linux and OS X under the name "miredo" has been difficult to control and monitor. The protocol tunnels IPv6 traffic from hosts behind NAT gateways via UDP packets, exposing them via IPv6 and possibly evading commonly used controls like Intrusion Detection Systems (IDS), Proxies or other network defenses.
As of Windows 7, Teredo is enabled by default, but inactive . It will only be used if an application requires it. If Teredo is active, "ipconfig" will return a "Tunnel Adapter" with an IP address starting with "2001:0:"
A teredo connection in default configuration starts with the client (your desktop), connecting to a Teredo server on UDP port 3544. Initially, the client and the server will perform a handshake to determine the connection parameters and the IPv6 address. After the handshake is complete, the connection may be handed off to a relay.
Wireshark and tshark are perfectly fine in detecting and analyzing the initial handshake. However, the actual "data connection" after the handshake is complete is usually missed as it may use arbitrary UDP ports. You have to manually determine the UDP ports involved and configure wireshark (or tshark) to analyze the respective traffic as Teredo.
Lets look at the respective traffic from a Windows 7 system using tshark (to make this more readable, I replace my local network with "x")
First, we do have the name lookup for the teredo server (teredo.ipv6.microsoft.com)
x.135 -> x.2 DNS Standard query A teredo.ipv6.microsoft.com x.2 -> x.135 DNS Standard query response CNAME teredo.ipv6.microsoft.com.nsatc.net A 188.8.131.52
Next, Teredo is going through it's setup procedure. tshark will show this as IPv6 traffic by default, but it is really IPv6 encapsulated in IPv4/UDP. The traffic will be directed at the Teredo server at 184.108.40.206, so we can use "ip.host==220.127.116.11" as filter
tshark -r teredo.pcap 'ip.host==18.104.22.168' fe80::ffff:ffff:fffe -> ff02::2 ICMPv6 Router solicitation fe80::8000:f227:bec8:6189 -> fe80::ffff:ffff:fffe ICMPv6 Router advertisement 2001::4137:9e76:1488:16cf:aabb:ccdd -> 2001:4860:8003::93 Teredo Direct IPv6 Connectivity Test 2001::4137:9e76:1488:16cf:aabb:ccdd -> 2001:4860:8003::93 Teredo Direct IPv6 Connectivity Test 2001::4137:9e76:1488:16cf:aabb:ccdd -> 2001:4860:8003::93 Teredo Direct IPv6 Connectivity Test 2001::4137:9e76:1488:16cf:aabb:ccdd -> 2001:4860:8003::93 Teredo Direct IPv6 Connectivity Test fe80::98f4:bbf1:cf8c:1c -> 2001::4137:9e76:1488:16cf:aabb:ccdd IPv6 IPv6 no next header
The router advertisement packet is actually a bit more complex. It does include a Teredo header indicating the source from which the teredo server received the packet. The complete packet consists of
- IPv4 Header
- UDP Header
- Teredo Authentication Header
- Teredo Origin Header
- IPv6 Header
- ICMPv6 Header
- Router Advertisement
Using tshark in verbose mode yields all the details (only the Teredo headers are shown. My public IPv4 address is obfuscated):
Teredo Authentication header Client identifier length: 0 Authentication value length: 0 Nonce value: 027ed9846d66944e Confirmation byte: 00 Teredo Origin Indication header Origin UDP port: 59696 Origin IPv4 address: a.b.c.d (a.b.c.d)
The initial router advertisement advertises the network address to use, which is derived from the teredo servers IPv4 address. In this case, the subnet is 2001:0:4136:9e76::/64. 0x41 0x36 0x9e 0x76 is our teredo servers IPv4 address (22.214.171.124).The routers "lifetime" is set to infinite. Using the prefix and the Teredo Origin Indication Header, our host knows everything it needs to know to assemble its Teredo IPv6 address.
The "connectivity test" is just a simple ICMPv6 echo request.
finally, the packet labeled "IPv6 no next header" above is actually interesting for its Teredo header. It includes a "Teredo Origin Indication Header", which will direct us to a different server. Teredo servers typically only deal with the initial connection setup and then hand us over to a different server to actually send data. In our case, this header looks like:
Teredo Origin Indication header Origin UDP port: 3545 Origin IPv4 address: 126.96.36.199 (188.8.131.52)
Now our connection switches to this server (and port) to continue. One tshark filter that can be used to find this packet and extract the new destination address and port
One tshark command to extract the new destination port and address (again: a.b.c.d is our public IPv4 address. we have to exclude it to eliminate origin headers sent as part of the connection setup)
tshark -r teredo.pcap -T fields -e teredo.orig.port -e teredo.orig.addr 'teredo.orig.port && !(teredo.orig.addr == a.b.c.d)'
And we can use this information to now have tshark decode the remaining teredo traffic for us:
tshark -r teredo.pcap -d udp.port==3545,teredo 'ip.host==184.108.40.206'
or extract the IPv6 packet data in hexadecimal:
tshark -e data -T fields -r teredo.pcap 'ip.host==220.127.116.11 and udp.port==3545'
Also see http://isc.sans.edu/tools/ipv6.html