Traceroute Bug

 

This document investigates the peculiar packet structure of the Linux traceroute utility.

 

Background

For these tests, I was using Redhat Linux version 7.2*. The network was two machines, one on either side of a Cisco 2621. The inside machine used static NATing, and the IP arrangement was as illustrated in the diagram below.

 

 

 

The router had no rules to restrict traffic in either direction.

 

The Windows2k machine had UDP port 135 open and listening.

There were no previous connections established.

 

The NAT translation table on the router showed only the static NAT:

Outside Global: 216.249.144.222 to Inside Local: 192.168.1.1

 

Test 1

 

#traceroute 216.249.144.222 –p 134 -n

 

The –p 134 was to force the traceroute routine to use port 135 in its probe.

 

A portion of the traffic generated is shown below:

 

Listing 1:

1  IP-216.249.144.221   IP-216.249.144.222   IP-135   64    IP UDP

2  IP-216.249.144.225   IP-216.249.144.221            74    ICMP DUnr

3  IP-216.249.144.221   IP-216.249.144.222   IP-136   64    IP UDP

4  IP-216.249.144.225   IP-216.249.144.221            74    ICMP DUnr

 

From this we can see that traceroute has send packets to two ports – 135 and 136. In both cases the router responded with a Port Unreachable. At first it might appear that the router is responding on behalf of the inside machine. However, traffic collected on the inside network shows no traffic between router and the target system.

 


Test 2

 

#nmapsU 216.249.144.222 –p 135 –n –P0

 

In this test, I used nmap to generate a similar UDP packet, also to port 135. Below is the listing showing the packets captured:

 

Listing 2:

12  IP-216.249.144.221   IP-216.249.144.222   IP-135    64      IP UDP

13  IP-216.249.144.222   IP-216.249.144.221   IP-54146  130     IP UDP

 

In this capture we can see that the end machine (.222) has responded with a UDP packet containing data. Obviously the packet has gone through the router this time.

 

This leads one to question why the UDP packet from the nmap test went through the router, while the packet from the traceroute did not. So, let’s open each of these and investigate:

 

Packet 1 from Listing 1: UDP Packet from traceroute:

Ethernet Header

  Destination:  00:06:28:7A:54:21

  Source:       00:03:47:8A:AF:AF

  Protocol Type:0x0800  IP

IP Header - Internet Protocol Datagram

  Version:              4

  Header Length:        5  (20  bytes)

  Type of Service:      %00000000

  Precedence: Routine,   Normal Delay,   Normal Throughput,   Normal Reliability

  Total Length:         38

  Identifier:           19302

  Fragmentation Flags:  %000  May Fragment   Last Fragment

  Fragment Offset:      0  (0  bytes)

  Time To Live:         1

  Protocol:             17  UDP

  Header Checksum:      0x9AB2

  Source IP Address:    216.249.144.221

  Dest. IP Address:     216.249.144.222

  No IP Options

UDP - User Datagram Protocol

  Source Port:          32772

  Destination Port:     135  DCE Endpoint Resolution

  Length:               18

  Checksum:             0xBC8F

  UDP Data Area:

  ..                01 01

Extra bytes (Padding):

 

From this we see an immediate problem. The UDP header length is 18 bytes – which is illegal since all headers must have a long-word boundary (i.e. a length that is evenly divisible by 4). Let’s look at the nmap packet now, just for verification:

 

Listing 2, Packet 12: UDP Packet from nmap

Ethernet Header

  Destination:  00:06:28:7A:54:21

  Source:       00:03:47:8A:AF:AF

  Protocol Type:0x0800  IP

IP Header - Internet Protocol Datagram

  Version:              4

  Header Length:        5  (20  bytes)

  Type of Service:      %00000000

  Precedence: Routine,   Normal Delay,   Normal Throughput,   Normal Reliability

  Total Length:         28

  Identifier:           39350

  Fragmentation Flags:  %000  May Fragment   Last Fragment

  Fragment Offset:      0  (0  bytes)

  Time To Live:         58

  Protocol:             17  UDP

  Header Checksum:      0x136C

  Source IP Address:    216.249.144.221

  Dest. IP Address:     216.249.144.222

  No IP Options

UDP - User Datagram Protocol

  Source Port:          54146

  Destination Port:     135  DCE Endpoint Resolution

  Length:               8

  Checksum:             0x5825

  UDP Data Area:        No more data.

 

Here we see a ‘normal’ UDP header with a length of 8 bytes.

 

More Router Investigation

After noting that the packets from traceroute appeared to be mal-formed, I looked into the router packet statistics:

 

#show ip traffic

 

. .

 

UDP 655 no port

 

. .

 

Every time I ran traceroute this "UDP no port" count would increment by the number of UDP packets sent from traceroute. This indicates that the router does not recognize the UDP header as is, and never "finds" a port. This might explain the router`s response: ICMP Port Unreachable. Ironically, this response is exactly what traceroute is looking for and translates it as a valid response from an "endpoint" machine.

 

Notes:

* I later ran the test with Redhat version 8.0. The packets generated were exactly the same.

 

For those of you that prefer to examine the raw tcpdump data:

 

 

Traceroute dump:

09:03:46.298411 216.249.144.221.32772 > 216.249.144.222.135: udp 10 [ttl 1]
    4500 0026 4b66 0000 0111 9ab2 d8f9 90dd
    d8f9 90de 8004 0087 0012 bc8f 0101 d211
    663e b1ae 0400
09:03:46.298411 216.249.144.225 > 216.249.144.221: icmp: 216.249.144.222 udp port 135 unreachable [tos 0xc0]
    45c0 0038 00c9 0000 ff01 e689 d8f9 90e1
    d8f9 90dd 0303 bfcf 0000 0000 4500 0026
    4b66 0000 0111 9ab2 d8f9 90dd d8f9 90de
    8004 0087 0012 bc8f
09:03:56.328411 216.249.144.221.32772 > 216.249.144.222.136: udp 10 [ttl 1]
    4500 0026 4b67 0000 0111 9ab1 d8f9 90dd
    d8f9 90de 8004 0088 0012 bc38 0201 dc11
    663e a604 0500
    09:03:56.328411 216.249.144.225 > 216.249.144.221: icmp: 216.249.144.222 udp port 136 unreachable [tos 0xc0]
    45c0 0038 00ca 0000 ff01 e688 d8f9 90e1
    d8f9 90dd 0303 c025 0000 0000 4500 0026
    4b67 0000 0111 9ab1 d8f9 90dd d8f9 90de
    8004 0088 0012 bc38
09:03:56.328411 216.249.144.221.32772 > 216.249.144.222.netbios-ns: NBT UDP PACKET(137): OPUNKNOWN; NEGATIVE;
RESPONSE; BROADCAST [ttl 1]
    4500 0026 4b68 0000 0111 9ab0 d8f9 90dd
    d8f9 90de 8004 0089 0012 8831 0301 dc11
    663e d90a 0500

nmap Dump:

09:01:42.778411 216.249.144.221.54145 > 216.249.144.222.135: udp 0
    4500 001c afd7 0000 3a11 fd4a d8f9 90dd
    d8f9 90de d381 0087 0008 5826
09:01:42.778411 216.249.144.222.135 > 216.249.144.221.54145: udp 84
    4500 0070 0075 0000 7f11 6759 d8f9 90de
    d8f9 90dd 0087 d381 005c f3ee 0406 0000
    1000 0000 0000 0000 0000 0000 0000 0000
    0000 0000 0000 0000 0000 0000 0000 0000
    0000 0000 0000 0000 0000 0000 0000 0000
    0000 0000 c130 823c 0000 0000 0000 0000
    0000 0000 0000 0400 0000 0000 0800 001c