Analyzing Teredo with tshark and Wireshark

Published: 2011-05-03
Last Updated: 2011-05-03 16:02:06 UTC
by Johannes Ullrich (Version: 1)
0 comment(s)

The Teredo protocol [1], 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 [2]. 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.

[ tshark too complex? Don't like reading? ;-) ... watch this video to learn how to use Wireshark to do all this ]

 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 (

x.135 -> x.2 DNS Standard query A
x.2 -> x.135 DNS Standard query response CNAME A

 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, so we can use "" as filter

tshark -r teredo.pcap ''  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

  1. IPv4 Header
  2. UDP Header
  3. Teredo Authentication Header
  4. Teredo Origin Header
  5. IPv6 Header
  6. ICMPv6 Header
  7. 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 ( 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: (

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 ''

or extract the IPv6 packet data in hexadecimal:

tshark -e data -T fields -r teredo.pcap 
    ' and udp.port==3545'


Also see

Johannes B. Ullrich, Ph.D.
SANS Technology Institute
Twitter    39E7KUWGJQRV

0 comment(s)


Diary Archives