Re: Linux blind TCP spoofing, act II + others

From: Salvatore Sanfilippo -antirez- (antirezat_private)
Date: Fri Aug 06 1999 - 03:39:14 PDT

  • Next message: Gene Spafford: "Please pass the word: RAID registration deadlines!"

    --J/dobhs11T7y2rNN
    Content-Type: text/plain; charset=us-ascii
    
    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.
    
    bye,
    antirez
    
    --
    Salvatore Sanfilippo      antirezat_private     antirezat_private
    ALICOM snc  Tel: +39-0871-403522  Fax: +39-0871-41960 Web: www.alicom.com
                     try hping: http://www.kyuzz.org/antirez
    FreeSilviaBaraldiniFreeSilviaBaraldiniFreeSilviaBaraldiniFreeSilviaBarald
    
    --J/dobhs11T7y2rNN
    Content-Type: text/plain; charset=us-ascii
    Content-Disposition: attachment; filename="idrand.diff"
    
    diff -cr linux-2.0.36/Documentation/Configure.help linux-2.0.36-hack/Documentation/Configure.help
    *** linux-2.0.36/Documentation/Configure.help	Sun Nov 15 19:32:42 1998
    --- linux-2.0.36-hack/Documentation/Configure.help	Sun Dec 27 15:48:18 1998
    ***************
    *** 1336,1341 ****
    --- 1336,1349 ----
        hence it is recommended that you say Y here unless you really know
        what you're doing.
    
    + IP: True random id
    + CONFIG_ID_RAND
    +   This supplies true random ip id field in order to prevent id abuse
    +   in port scanning and in outgoing packets traffic guessing.
    +   See http://www.geek-girl.com/bugtraq/1998_4/0609.html for more
    +   informations on this topic.
    +   Warning: 256 Kbytes needed.
    +
      IP: Allow large windows (not recommend if <16MB of memory)
      CONFIG_SKB_LARGE
        On high speed, long distance networks the performance limit on
    diff -cr linux-2.0.36/net/ipv4/Config.in linux-2.0.36-hack/net/ipv4/Config.in
    *** linux-2.0.36/net/ipv4/Config.in	Thu Jun  4 00:17:50 1998
    --- linux-2.0.36-hack/net/ipv4/Config.in	Sun Dec 27 15:01:53 1998
    ***************
    *** 47,50 ****
    --- 47,51 ----
      bool 'IP: Disable Path MTU Discovery (normally enabled)' CONFIG_NO_PATH_MTU_DISCOVERY
      #bool 'IP: Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF
      bool 'IP: Drop source routed frames' CONFIG_IP_NOSR
    + bool 'IP: True random id' CONFIG_ID_RAND
      bool 'IP: Allow large windows (not recommended if <16Mb of memory)' CONFIG_SKB_LARGE
    diff -cr linux-2.0.36/net/ipv4/ip_forward.c linux-2.0.36-hack/net/ipv4/ip_forward.c
    *** linux-2.0.36/net/ipv4/ip_forward.c	Thu Jun  4 00:17:50 1998
    --- linux-2.0.36-hack/net/ipv4/ip_forward.c	Sat Dec 26 21:47:15 1998
    ***************
    *** 77,83 ****
    --- 77,87 ----
      	iph->protocol	=	IPPROTO_IPIP;
      	iph->ihl	=	5;
      	iph->tot_len	=	htons(skb->len + len);  /* Anand, ernet */
    + #ifdef CONFIG_ID_RAND
    + 	iph->id		=	htons(getrandid());
    + #else
      	iph->id		=	htons(ip_id_count++);
    + #endif
      	ip_send_check(iph);
    
      	skb->dev = out;
    diff -cr linux-2.0.36/net/ipv4/ip_output.c linux-2.0.36-hack/net/ipv4/ip_output.c
    *** linux-2.0.36/net/ipv4/ip_output.c	Thu Jun  4 00:17:50 1998
    --- linux-2.0.36-hack/net/ipv4/ip_output.c	Sun Dec 27 15:44:05 1998
    ***************
    *** 30,35 ****
    --- 30,36 ----
       *		Juan Jose Ciarlante:	sk/skb source address rewriting
       * 	Elena Apolinario Fdez de Sousa,:ipmr_forward never received multicast
       *	Juan-Mariano de Goyeneche	traffic generated locally.
    +  *	Salvatore Sanfilippo    :	IP id random. <antirezat_private>
       */
    
      #include <asm/segment.h>
    ***************
    *** 265,271 ****
    --- 266,276 ----
      	return mac;
      }
    
    + #ifdef CONFIG_ID_RAND
    + unsigned short getrandid(void);
    + #else
      int ip_id_count = 0;
    + #endif
    
      /*
       * This routine builds the appropriate hardware/IP headers for
    ***************
    *** 483,489 ****
    --- 488,498 ----
      			add_to_send_queue(sk, skb);
      			/* fall through */
      		case 1:
    + #ifdef CONFIG_ID_RAND
    + 			iph->id = htons(getrandid());
    + #else
      			iph->id = htons(ip_id_count++);
    + #endif
      	}
    
      	skb->free = free;
    ***************
    *** 751,757 ****
    --- 760,770 ----
      			iph->ihl=5;
      			iph->tos=sk->ip_tos;
      			iph->tot_len = htons(length);
    + #ifdef CONFIG_ID_RAND
    + 			iph->id=htons(getrandid());
    + #else
      			iph->id=htons(ip_id_count++);
    + #endif
      			iph->frag_off = 0;
      			iph->ttl=sk->ip_ttl;
      			iph->protocol=type;
    ***************
    *** 853,860 ****
      	/*
      	 *	Get an identifier
      	 */
    ! 	
      	id = htons(ip_id_count++);
    
      	/*
      	 *	Being outputting the bytes.
    --- 866,877 ----
      	/*
      	 *	Get an identifier
      	 */
    !
    ! #ifdef CONFIG_ID_RAND
    ! 	id = htons(getrandid());
    ! #else	
      	id = htons(ip_id_count++);
    + #endif
    
      	/*
      	 *	Being outputting the bytes.
    ***************
    *** 1209,1211 ****
    --- 1226,1304 ----
      #endif
      }
    
    + #ifdef CONFIG_ID_RAND
    + unsigned int random(void)
    + {
    +         static unsigned long seed=152L;
    +         seed=seed*69069L+1;
    +         return seed^jiffies;
    + }
    +
    + #define BIT 16
    + #define M (1 << BIT)
    + #define N ((1 << BIT) - 1)
    + #define RANDOM (random() & N)
    +
    + void swap(unsigned short *a, unsigned short *b)
    + {
    + 	unsigned short t;
    + 	t = *a;
    + 	*a = *b;
    + 	*b = t;
    + }
    +
    + unsigned short getrandid(void)
    + {
    + 	static unsigned short vect1[M];
    + 	static unsigned short vect2[M];
    + 	static int status = 0;
    + 	static int c = 0;
    +
    + 	if (status == 1)
    + 	{
    + 		if (c == N)
    + 			status = 2;
    +
    + 		swap(&vect2[c], &vect2[RANDOM]);
    + 		c++; c&=N;
    + 		return vect1[c];
    + 	}
    +
    + 	if (status == 2)
    + 	{
    + 		if (c == N)
    + 			status = 1;
    +
    + 		swap(&vect1[c], &vect1[RANDOM]);
    + 		c++; c&=N;
    + 		return vect2[c];
    + 	}
    +
    + 	if (status == 0)	/* initial shuffling */
    + 	{
    + 		register int j;
    +
    + 		for (j = 0; j < M; j++)
    + 			vect2[j] = vect1[j] = j;
    +
    + 		for (j = 0; j < M; j++)
    + 			swap(&vect1[j], &vect1[RANDOM]);
    +
    + 		status = 1;
    + 		printk(KERN_INFO "IP id true rand: initial shuffling completed\n");
    + 	}
    +
    + 	if (status == 1)
    + 	{
    + 		if (c == N)
    + 			status = 2;
    +
    + 		swap(&vect2[c], &vect2[RANDOM]);
    + 		c++; c&=N;
    + 		return vect1[c];
    + 	}
    +
    + 	printk(KERN_WARNING "Warning, getrandid() status = %d\n", status);
    + 	return RANDOM;
    + }
    + #endif /* CONFIG_ID_RAND */
    diff -cr linux-2.0.36/net/ipv4/raw.c linux-2.0.36-hack/net/ipv4/raw.c
    *** linux-2.0.36/net/ipv4/raw.c	Thu Jun  4 00:17:50 1998
    --- linux-2.0.36-hack/net/ipv4/raw.c	Sat Dec 26 21:56:37 1998
    ***************
    *** 308,314 ****
    --- 308,318 ----
      	 	 *	ip_build_xmit clean (well less messy).
      		 */
      		if (!iph->id)
    + #ifdef CONFIG_ID_RAND
    + 			iph->id = htons(getrandid());
    + #else
      			iph->id = htons(ip_id_count++);
    + #endif
      		iph->check=ip_fast_csum((unsigned char *)iph, iph->ihl);
      	}
      }
    diff -cr linux-2.0.36/net/ipv4/tcp_output.c linux-2.0.36-hack/net/ipv4/tcp_output.c
    *** linux-2.0.36/net/ipv4/tcp_output.c	Sun Nov 15 19:33:22 1998
    --- linux-2.0.36-hack/net/ipv4/tcp_output.c	Sat Dec 26 21:46:20 1998
    ***************
    *** 523,529 ****
    --- 523,534 ----
      					    skb->localroute, sk->bound_device);
      	        }
    
    + #ifdef CONFIG_ID_RAND
    + 		iph->id = htons(getrandid());
    + #else
      		iph->id = htons(ip_id_count++);
    + #endif
    +
      #ifndef CONFIG_NO_PATH_MTU_DISCOVERY
      		if (rt && ntohs(iph->tot_len) > rt->rt_mtu)
      			iph->frag_off &= ~htons(IP_DF);
    diff -cr linux-2.0.36/net/netsyms.c linux-2.0.36-hack/net/netsyms.c
    *** linux-2.0.36/net/netsyms.c	Mon Jul 13 22:47:41 1998
    --- linux-2.0.36-hack/net/netsyms.c	Sat Dec 26 21:53:33 1998
    ***************
    *** 107,113 ****
    --- 107,115 ----
      	X(ip_rt_put),
      	X(arp_send),
      	X(arp_bind_cache),
    + #ifndef CONFIG_ID_RAND
      	X(ip_id_count),
    + #endif
      	X(ip_send_check),
      	X(ip_forward),
      	X(sysctl_ip_forward),
    
    --J/dobhs11T7y2rNN--
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:55:15 PDT