Bugtraq mailing list archives

A crash course with Linux Kernel 2.4.x, IP ID values & RFC 791


From: Ofir Arkin <ofir () atstake com>
Date: Sat, 13 Apr 2002 21:30:20 +0100

This is an update of my original postings about the IP ID handling in the ICMP and UDP protocols with Linux Kernel 2.4.x.


RFC 791 defines the IP Identification field as:
"An identifying value assigned by the sender to aid in assembling the fragments of a datagram."

RFC 791 identifies the role of the Identification field as:
"The internet fragmentation and reassembly procedure needs to be able to break a datagram into an almost arbitrary number of pieces that can be later reassembled. The receiver of the fragments uses the identification field to ensure that fragments of different datagrams are not mixed."

and

"The identification field is used to distinguish the fragments of one datagram from those of another."

While the IP identification value is only used for IP fragment reassembly and is not used in cases where the DF flag is set, the RFC states that

"... the identification field to a value that must be unique for that source-destination pair and protocol for the time the datagram will be active in the internet system."

Some may argue that when the packet is not to be fragmented there is no room for an IP identification value, since its usage is futile in this case. While this does not impact the normal operations of the IP protocol, it does violate the RFC and might prove harmful by allowing simplified OS fingerprinting.

If we have an exploit targeting only Linux 2.4.x kernel-based machines, for example, and our problem is to identify those machines, we will need only 1 extra packet to send to questionable IP addresses before deciding on a match.


The Linux Kernel 2.4.x way:
Linux Kernel 2.4.x is using IP ID values of zero in several circumstances, whenever the DF is set:

ICMP:
Kernel 2.4.0-2.4.4 will use the value of zero (0) for the IP ID field value whenever sending an ICMP query messages or producing ICMP replies.

This behavior was changed with Kernel 2.4.5 and above, and now only when generating ICMP query messages the IP ID field value will be set to zero.

If the Linux Kernel 2.4.x IP stack implementation is to comply with the same rule regarding the DF bit and the IP identification field value (0), why the IP ID field value was changed when the DF bit is set with ICMP replies with Kernel 2.4.5 and after?


UDP:
Whenever sending or answering for a UDP datagram the IP ID will be zero when the DF bit will be set.

Sending:
03/16-11:49:41.531642 192.168.1.200:1024 -> x.x.x.x:53 UDP TTL:64 TOS:0x0 ID:0 IpLen:20 DgmLen:63 DF
Len: 43
BC 0D 01 00 00 01 00 00 00 00 00 00 03 77 77 77  .............www
03 63 6E 6E 03 63 6F 6D 05 6C 6F 63 61 6C 00 00  .cnn.com.local..
01 00 01
Replying:
03/16-12:13:17.388211 192.168.1.200:1775 -> y.y.y.y:7
UDP TTL:64 TOS:0x0 ID:28256 IpLen:20 DgmLen:28
Len: 8

03/16-12:13:17.547636 y.y.y.y:7 -> 192.168.1.200:1775
UDP TTL:50 TOS:0x0 ID:0 IpLen:20 DgmLen:28 DF
Len: 8


TCP:
In several circumstances, like a SYN-ACK answer for a SYN, the IP ID will be zero when the DF bit will be set.

21:45:36.779241 192.168.1.5.31682 > 192.168.1.25.ssh: S [tcp sum ok]
2372425889:2372425889(0) win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 0,nop,nop,timestamp 329650873 0> (DF) (ttl 64, id 12445, len 64)
0x0000     4500 0040 309d 4000 4006 86ac c0a8 0105    E..@0.@.@.......
0x0010     c0a8 0119 7bc2 0016 8d68 58a1 0000 0000    ....{....hX.....
0x0020     b002 4000 ea50 0000 0204 05b4 0101 0402    ..@..P..........
0x0030     0103 0300 0101 080a 13a6 12b9 0000 0000    ................

21:45:36.779241 192.168.1.25.ssh > 192.168.1.5.31682: S [tcp sum ok]
3107930066:3107930066(0) ack 2372425890 win 5792 <mss 1460,sackOK,timestamp 101376 329650873,nop,wscale 0> (DF) (ttl 64, id 0, len 60)
0x0000     4500 003c 0000 4000 4006 b74d c0a8 0119    E..<..@.@..M....
0x0010     c0a8 0105 0016 7bc2 b93f 3fd2 8d68 58a2    ......{..??..hX.
0x0020     a012 16a0 a092 0000 0204 05b4 0402 080a    ................
0x0030     0001 8c00 13a6 12b9 0103 0300              ............



The bottom line is that this behavior will allow a _very_ easy identification of _any_ Kernel 2.4.x based Linux machine. I do not need to go over again why having predictable IP ID values is wrong in the first place.

Using a random value for the IP ID not only enhances security but also reduces the ability to accurately fingerprint the IP stack using this parameter.


Related Previous Bugtraq Posts:
Fingerprinting Linux Kernel 2.4.x based machines using ICMP
http://www.sys-security.com/archive/bugtraq/ofirarkin2001-03.txt

Fun with IP Identification Field Values (Identifying Older MS Based OSs)
http://www.sys-security.com/archive/bugtraq/ofirarkin2001-02.txt

Several Misbehaviors with the ICMP implementation (and the 'ping' utility) with MS based operating systems
http://www.sys-security.com/archive/bugtraq/ofirarkin2001-01.txt

--
Ofir Arkin
Managing Security Architect
@stake, Inc.
http://www.atstake.com
email: ofir () atstake com



Current thread: