Bugtraq mailing list archives

TOS Field value in ICMP Error Messages with LINUX Kernels 2.2.x & 2.4


From: Ofir Arkin <ofir () ITCON-LTD COM>
Date: Sat, 14 Oct 2000 00:37:08 +0200

RFC 1349 states that ICMP Error messages should be
sent with TOS field value of 0x00. Nearly all stack implementations
send back 0x00 as the TOS field value when generating an ICMP error
message. All but LINUX.

Fyodor had outlined in his paper “Remote OS Identification by TCP/IP
Fingerprinting”   the fact that LINUX is using the value of 0xc0 (an
unused precedence value) as its TOS field value with ICMP Port
Unreachable error messages.

This abnormality with LINUX is not only limited to ICMP Destination
Unreachable Port Unreachable error messages.

Lets examine the next trace:

00:30:08.339498 < x.x.x.x > y.y.y.y: ip-proto-72 0 (ttl 49, id 38624)
                         4500 0014 96e0 0000 3148 f4bf xxxx xxxx
                         yyyy yyyy
00:30:08.339559 > y.y.y.y > x.x.x.x: icmp: y.y.y.y protocol 72
unreachable Offending pkt: x.x.x.x > y.y.y.y: ip-proto-72 0 (ttl 49,
id 38624) [tos 0xc0]  (ttl 255, id 37)
                         45c0 0044 0025 0000 ff01 bcd1 yyyy yyyy
                         xxxx xxxx 0302 fb1a 0000 0000 4500 0014
                         96e0 0000 3148 f4bf xxxx xxxx yyyy yyyy
                         0050 d909 621b 96f7 0000 0000 5004 0000
                         df71 0000

The ICMP error message produced by a LINUX machine based on Kernel
2.2.14, is Destination Unreachable Protocol Unreachable (Type 3 Code 2).
As it can be seen the TOS field value that was used is again 0xc0.

Is 0xc0 the default value for the TOS field with LINUX host destination
unreachable error messages?

It is the default value used for the TOS field with ALL host generated
ICMP error messages with LINUX.


Sending offending packets with different TOS field values
What will happen if we will send a UDP datagram with a TOS field value
that is not equal to the default? Will LINUX use 0xc0 or another value?

In the next example I have sent a UDP datagram with TOS field value of 0x08
hex to a closed UDP port:

00:46:10.573825 > x.x.x.x.2790 > y.y.y.y.0: udp 0 [tos 0x8]  (ttl 64, id
28850)
                         4508 001c 70b2 0000 4011 0c15 xxxx xxxx
                         yyyy yyyy 0ae6 0000 0008 f6f5

00:46:10.573866 > y.y.y.y > x.x.x.x: icmp: y.y.y.y udp port 0 unreachable
Offending pkt: x.x.x.x.2790 > y.y.y.y.0: udp 0 [tos 0x8]  (ttl 64, id 28850)
[tos 0xc8]  (ttl 255, id 24808)
                         45c8 0038 60e8 0000 ff01 5c12 yyyy yyyy
                         xxxx xxxx 0303 fb18 0000 0000 4508 001c
                         70b2 0000 4011 0c15 xxxx xxxx yyyy yyyy
                         0ae6 0000 0008 f6f5

The TOS field value used with the reply was 0xc8.

In the next example I have sent a UDP datagram with the TOS field value set
to 0x10 hex to a closed UDP port:

00:50:43.759906 ppp0 > x.x.x.x.1952 > y.y.y.y.0: udp 0 [tos 0x10]  (ttl 64,
id 15952)
                         4510 001c 3e50 0000 4011 e6b2 xxxx xxxx
                         yyyy yyyy 07a0 0000 0008 a27f
00:50:44.154556 ppp0 < y.y.y.y > x.x.x.x: icmp: y.y.y.y.211 udp port 0
unreachable Offending pkt: x.x.x.x.1952 > y.y.y.y.0: udp 0 [tos 0x10]  (
ttl 47, id 15952) [tos 0xd0]  (ttl 238, id 54662)
                         45d0 0038 d586 0000 ee01 a0af yyyy yyyy
                         xxxx xxxx 0303 52d5 0000 0000 4510 001c
                         3e50 0000 2f11 f7b2 xxxx xxxx yyyy yyyy
                         07a0 0000 0008 a27f

The TOS field value used with the reply was 0xd0.

How is the TOS field value used in the LINUX ICMP Error message is
calculated?
0x00 in hex equal to 00000000 in binary. Use the binary value of 0xc0
(11000000), and do a logical OR between those values. The result will be
11000000 in binary, which equal to 0xc0 in hex.

0x10 in hex equal to 00010000 in binary. When doing a logical OR with
11000000 we will have 11010000 as the result. It is equale to 0xd0 in
hex.

0x09 in hex equal to 00001001. Do a Logical OR with 11000000 and you will
receive
11001001 as the result. Because the unused bit should be zero, the actual
value sent would be 11001000 that equal to 0xc8.

I hope this will clarify the subject.


Ofir Arkin  [ofir () itcon-ltd com]
Senior Security Analyst
Chief of Grey Hats
ITcon, Israel.
http://www.itcon-ltd.com

Personal Web page: http://www.sys-security.com

"Opinions expressed do not necessarily
represent the views of my employer."


Current thread: