Subject: Re: IP source address security issue
To: None <netbsd-bugs@NetBSD.ORG>
From: Lawrence E. Freil <lef@woods.com>
List: netbsd-bugs
Date: 01/30/1995 11:29:51
I've incorporated the majority of the suggestions to TCP/IP stack and
done some testing.  It seems to fit within the framework of RFC-1323
and while not a complete solution to the problem with source IP address
spoofing, it should make the task of breaking into a system great deal
more difficult.  In any case, let me know what you think.   If there
are no objections/problems perhaps it could be released as a patch.

Also I'm working on some modifications for ppp-2.2 that will do IP source
filtering on the ppp link.  This in combination with the below patches
should improve things quite a lot.

BTW - The origonal behavior can be obtained by #defining ORIGONAL_TCP_ISS.

-----------------------IP source address patch---------------------------
*** netinet/Otcp_input.c        Mon Jan 30 10:24:10 1995
--- netinet/tcp_input.c Mon Jan 30 10:28:56 1995
***************
*** 589,595 ****
--- 589,604 ----
                        tp->iss = iss;
                else
                        tp->iss = tcp_iss;
+ #ifdef ORIGONAL_TCP_ISS
                tcp_iss += TCP_ISSINCR/2;
+ #else
+               if (1) {
+                 struct timeval avt;
+
+                 microtime(&avt);
+                 tcp_iss += (avt.tv_usec + random()) & 0xffff;
+               }
+ #endif
                tp->irs = ti->ti_seq;
                tcp_sendseqinit(tp);
                tcp_rcvseqinit(tp);
*** netinet/Otcp_subr.c Mon Jan 30 10:15:07 1995
--- netinet/tcp_subr.c  Mon Jan 30 10:08:16 1995
***************
*** 74,81 ****
  void
  tcp_init()
  {

!       tcp_iss = 1;            /* wrong */
        tcb.inp_next = tcb.inp_prev = &tcb;
        if (max_protohdr < sizeof(struct tcpiphdr))
                max_protohdr = sizeof(struct tcpiphdr);
--- 74,88 ----
  void
  tcp_init()
  {
+ #ifdef ORIGONAL_TCP_ISS
+         tcp_iss = 1;      /* Wrong */
+ #else
+         struct timeval avt;

!
!       microtime(&avt);
!       tcp_iss = (random() & 0x3fffffff) + (avt.tv_usec & 0x3fffffff);
! #endif /* ORIGONAL_TCP_ISS */
        tcb.inp_next = tcb.inp_prev = &tcb;
        if (max_protohdr < sizeof(struct tcpiphdr))
                max_protohdr = sizeof(struct tcpiphdr);
*** netinet/Otcp_timer.c        Mon Jan 30 10:14:47 1995
--- netinet/tcp_timer.c Mon Jan 30 10:35:02 1995
***************
*** 129,138 ****
  tpgone:
                ;
        }
        tcp_iss += TCP_ISSINCR/PR_SLOWHZ;               /* increment iss */
  #ifdef TCP_COMPAT_42
        if ((int)tcp_iss < 0)
!               tcp_iss = 0;                            /* XXX */
  #endif
        tcp_now++;                                      /* for timestamps */
        splx(s);
--- 129,147 ----
  tpgone:
                ;
        }
+ #ifdef ORIGONAL_TCP_ISS
        tcp_iss += TCP_ISSINCR/PR_SLOWHZ;               /* increment iss */
+ #else
+       tcp_iss += (random() & 0x7fffffff) % ((TCP_ISSINCR/PR_SLOWHZ));
+ #endif /* ORIGONAL_TCP_ISS */
+
  #ifdef TCP_COMPAT_42
        if ((int)tcp_iss < 0)
! #ifdef ORIGONAL_TCP_ISS
!               tcp_iss = 0;                            /* XXX */
! #else
!               tcp_iss &= 0x7fffffff;                  /* XXX */
! #endif /* ORIGONAL_TCP_ISS */
  #endif
        tcp_now++;                                      /* for timestamps */
        splx(s);
*** netinet/Otcp_usrreq.c       Thu Jan 26 13:25:18 1995
--- netinet/tcp_usrreq.c        Mon Jan 30 10:32:31 1995
***************
*** 196,202 ****
                tcpstat.tcps_connattempt++;
                tp->t_state = TCPS_SYN_SENT;
                tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
!               tp->iss = tcp_iss; tcp_iss += TCP_ISSINCR/2;
                tcp_sendseqinit(tp);
                error = tcp_output(tp);
                break;
--- 196,227 ----
                tcpstat.tcps_connattempt++;
                tp->t_state = TCPS_SYN_SENT;
                tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
!               tp->iss = tcp_iss;
! #ifdef ORIGONAL_TCP_ISS
!               tcp_iss += TCP_ISSINCR/2;
! #else
!               /*
!                * This and almost identical code in tcp_input.c is where
!                  * the initial connection sequence number is set incremented.
!                  * I've modified this to increment it by a pseudo-random
!                  * sequence in the bounds of 0 to 65535.  I don't just use
!                  * the random number generator here because the sequence
!                * of the generator could also be predicted.  however adding
!                * the low order bits of the microsecond clock should make
!                * the sequence very difficult to predict in a networked
!                * environment.
!                * This will slow down the code a little for a TCP connection
!                * setup, but it is a small price to pay and since frequently
!                * a session setup is slow anyway, it isn't likely that
!                * the difference will be noticable.
!                */
!               if (1) {
!                 struct timeval avt;
!
!                 microtime(&avt);
!                 tcp_iss += (avt.tv_usec + random()) & 0xffff;
!               }
! #endif
                tcp_sendseqinit(tp);
                error = tcp_output(tp);
                break;


        Lawrence Freil                      Usenet/DDN:lef@woods.com
        Essential Technical Services Inc.   or lef@dogwood.atl.ga.us
        1768 Old Country Place              Phone:(404) 667-9274
        Woodstock, GA 30188