Bugtraq mailing list archives

Re: Linux blind TCP spoofing, act II + others


From: deraadt () CVS OPENBSD ORG (Theo de Raadt)
Date: Sat, 7 Aug 1999 03:38:28 -0600


On Sun, Aug 01, 1999 at 01:10:06AM +0200, Nergal wrote:
    Now let's recall another Linux feature. Many OSes (including Linux)
assign to ID field of an outgoing IP datagram consecutive, increasing
numbers (we forget about fragmentation here; irrelevant in this case). That
enables anyone to determine the number of packets sent by host A: it's enough
to ping it, note the value of ID field of received ICMP_REPLY packet, wait x
seconds (or perform some other actions), then again ping host A. The
difference between ID fields of received ICMP_REPLY packets is equal to (the
number of packets sent by A in x second) +1. "Idle portscan" by antirez uses
this technique.

Re,

      i think that a consecutive IP id now can be considered
      a weakness in IP stacks. Using it you today are able
      at least to scan spoofed, to guess host traffic and
      you can use it when you need to know if the target host
      of your spoofed packet answered. Here is a patch for
      linux 2.0.36, maybe it isn't SMP safe so don't use it
      if your linux box have more than one CPU. Note: the name
      of this patch are 'True random id', however this isn't
      true, a better name is 'Truly random id'. There are
      a lot of 'better possible patchs' to fix this problem, but
      this patch is old and writed in 30 min. so i'm interested
      in your comment about how to implement a better patch.

Without having done an analysis of the pseudo-random number generator
in the Linux patch provided, I have a few comments to make.

This situation is very similar to the resolver problem.  For a
reminder about the resolver issue we were solving, see

        http://www.openbsd.org/advisories/res_random

Wow.  April 22, 1997.  That's before OpenBSD 2.1 was released, you
know, the release that was almost impossible to install from CD...

OpenBSD 2.5 solves this by using the same non-repeating random number
generator that we used to solve the resolver problem.  The same code
simply gets moved into the kernel.

Basically, you do not want to make that field random using a stock
random number generator, as close repeats (same number repeated in
close proximity to a previous occurance) can cause grotesque errors in
fragment reassembly at the destination.  The existing method of using
ip_id++, avoids such problems .... as well as they can be avoided in a
16-bit identifier space.  If you don't believe me, heck, just set the
ip_id to 31337 each time and see how well IP de-fragmentation suddenly
works..

Hence, what you really want is a pseudo random number generator which
is fairly strong (in a 16 bit space, hah), but cleverly avoids
re-using the same number in close proximity... I believe that this
would solve your problem best.

For more details, see:

        http://www.openbsd.org/cgi-bin/cvsweb/src/sys/netinet/ip_id.c?rev=1.1

In our case, this is called in the following places...

netinet/ip_ip4.c:    ipo->ip_id = ip_randomid();
netinet/ip_mroute.c:    ip_copy->ip_id = ip_randomid();
netinet/ip_output.c:            ip->ip_id = ip_randomid();
netinet/raw_ip.c:                       ip->ip_id = ip_randomid();
netinet6/ipv6_trans.c:  ip->ip_id = ip_randomid();

Enjoy.


Current thread: