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