Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Dec 2000 18:26:00 +0100
From:      Jesper Skriver <jesper@skriver.dk>
To:        Kris Kennaway <kris@FreeBSD.ORG>, Poul-Henning Kamp <phk@critter.freebsd.dk>
Cc:        security-officer@FreeBSD.ORG, cvs-all@FreeBSD.ORG, freebsd-net@FreeBSD.org
Subject:   what to do now ?  Was: cvs commit: src/sys/netinet ip_icmp.c tcp_subr.c tcp_var.h
Message-ID:  <20001218182600.C1856@skriver.dk>

next in thread | raw e-mail | index | archive | help
Hi,

I'm trying to find out what to to now regarding this.

To summarize.

PHK committed my original patch, this patch have the following
functionality
- When a ICMP administrative prohibited is recieved, it zap's 
  all TCP sessions in SYN-SENT state matching the source and destination 
  IP addresses and TCP port numbers in the IP header + 8 bytes from the 
  ICMP packet.
- It does not match against TCP sequence number
- disabled by default

Yesterday I summitted a new diff, with the following changes to the
above.

- Matches against the TCP sequence number in the IP header + 8 bytes 
  from the ICMP packet, against the last unacknowledged packet in the 
  TCP session matching the source and destination IP addresses and 
  TCP port numbers, these must be equal, thus it only matches if the
  ICMP unreachable is for the last sent packet.
  This is very secure, but in reality only has effect when setting up
  the session, as it doesn't work with multiple outstanding packets,
  it does work when setting up sessions, as the window will be zero
  here.
  this could be fixed by something like (*)
- Check for SYN-SENT state removed
- enabled by default

What I will suggest at this point, is to do one of 2 things:

1) Extend the original diff PHK committed to check for sequence number,
   and enable it by default, trivial as it's part of the second diff.
2) Fix the second diff with the below code.

For both I'll also add a extra check if the IP header in the ICMP packet 
has options set, and if it has, don't act on it, this applies to both,
the reason for this is, if it has options set, we'll miss some (or all)
of the 8 bytes from the TCP header, and thus, we'll not know port and
sequence numbers.

What do you prefer ? When I know this, I'll post a new diff for review.

(*) replace

	if (tp->snd_una != tcp_sequence) {

	with

	/*
	 * First check: if sequence numbers have wrapped, don't act on this.
	 * Second -"- : if the sequence number from the ICMP packet is for a
	 *              "old" packet, it's probably spoofed, dont't act on this.
	 * Third -"-  : if the sequence number from the ICMP packet is for a
	 *              packet from the future, it's spoofed, don't act on this.
	 */
	if ((tp->snd_max < tp->snd_una) || (tcp_sequence < tp->snd_una) || \
		(tp->snd_max < tcp_sequence)) {


/Jesper

-- 
Jesper Skriver, jesper(at)skriver(dot)dk  -  CCIE #5456
Work:    Network manager @ AS3292 (Tele Danmark DataNetworks)
Private: Geek            @ AS2109 (A much smaller network ;-)

One Unix to rule them all, One Resolver to find them,
One IP to bring them all and in the zone to bind them.


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001218182600.C1856>