[757] in bugtraq
Re: preventing sequence number guessing
daemon@ATHENA.MIT.EDU (Darren Reed)
Wed Jan 25 02:23:12 1995
From: Darren Reed <avalon@coombs.anu.edu.au>
To: dawagner@phoenix.Princeton.EDU (David A. Wagner)
Date: Wed, 25 Jan 1995 17:04:14 +1100 (EDT)
Cc: bugtraq@fc.net
In-Reply-To: <9501250440.AA02761@tucson.Princeton.EDU> from "David A. Wagner" at Jan 24, 95 11:40:37 pm
>
> I'm certainly no security expert, but I had a fairly simple idea
> for fixing the sequence number guessing vulnerability. Hopefully
> someone can tell me whether it's worthless or not. Hunting season's
> open -- shoot it down at will. :-)
>
> When OS boots up, grab lots of entropy and use MD5 to hash it
> into a 32 bit seed; initialize tcp_iss with it. Now let the
> kernel do its normal "increment tcp_iss a little for every new
> connection and every couple of clock ticks" schtick as always.
This is a good start...
> I've only got one novel idea: instead of using tcp_iss directly
> for the SYN everytime a new TCP/IP connection is opened, send
> MD5(tcp_iss) [or maybe MD5(tcp_iss, time(NULL), ...)].
not bad either...but rather than just when it is opened, perhaps
something a bit different but very similar...
> This implements a cryptographically strong random number generator
> for the sequence numbers; then attackers would have to invert
> MD5 to predict sequence numbers. MD5 is quite fast (is it fast
> enough?) and is completely exportable. Code for MD5 is available
> for anonymous ftp on ripem.msu.edu /pub/crypt/other/md5.zip.
>
> To nitpick, tcp_iss should be a full 64 bit (or even larger :-)
> data type; this is easy enough to change in the kernel: (right?)
No. For the patch to be most useful, it should work with minimal
alteration to .o's (I've learnt this) unless you're Sun/DEC, etc.
Even then, most people will be reluctant to make these sort of
changes unless they're confident about what they're doing.
[...]
> So, am I missing some important kernel feature which shoots this
> all down? Or is this actually a worthwhile technique? [If it
> is worthwhile, it seems like it'd be pretty easy to code -- but
> I have no experience at kernel programming, so I haven't done it
> myself. <sigh>]
If you don't interfere with the generation of tcp_iss at the *right*
time (and remember, for some stupid reason to do with 4.2BSD, you're
limited to 31 bits) the kernel will hapily make tcp_iss 0 for you,
regardless of what your increments were in and what it started out at.
It would seem that the easiest way to "hijack" the generation of the
tcp_iss variable in the kernel is to mess with the table in in_proto.c
(which is shipped with all SunOS 4.1.x and is compiled when you generate
your own kernel). Indeed, rather than use that program to mess with
ip_output.o and insert a wrapper, you can simply put your wrapper into
the table here and voila! If, for example, we used the above idea,
it should be trivial to write a wrapper for tcp_input which set tcp_iss
to whatever only when it was a pure "SYN" packet coming in. How hard
is that ?
MD5(foo)
tcp_seq foo;
{
...
return bar;
}
tcp_input_wrap(m)
struct mbuf *m;
{
struct ip *ip;
struct tcphdr *tcp;
ip = mtod(m, struct ip *);
tcp = (struct tcphdr *)((char *)ip + ip->ip_hl << 2);
if (tcp->th_flags == TH_SYN)
tcp_iss = MD5(tcp_iss);
return tcp_input(m);
}
and in in_proto.c, we replace tcp_input with tcp_input_wrap in the
table for SOCK_STREAM. The rest is academic...
darren