[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

TCP/IP Implementation Issues



There is an ambiguity (well more then one but im focusing on this one)
in rfc793 that affects the OpenBSD network stack in
sys/netinet/tcp_input.c the stack generates a RST upon receiving a FIN
to a closed port when it perhaps should silently drop the packet, this
response is used by os-fingerprinting tools to detect a particular
stack. 

The following are two direct quotes from the rfc that identify the
ambiguity. 

>From rfc793 page 64 section SEGMENT ARRIVES :

"If the state is CLOSED (i.e., TCB does not exist) then
all data in the incoming segment is discarded.  An incoming
segment containing a RST is discarded.  An incoming segment not
containing a RST causes a RST to be sent in response.  The
acknowledgment and sequence field values are selected to make the
reset sequence acceptable to the TCP that sent the offending
segment."

>From rfc793 page 74 section Established State:

"eighth, check the FIN bit,

Do not process the FIN if the state is CLOSED, LISTEN or SENSING
since the SEG.SEQ cannot be validated; drop the segment and
return.
"
The former is ambiguous because it says "An incoming segment not
containing a RST causes an RST to be sent in response." but does not
mention any specific criteria for making this situation other then
"not containing a RST". It would seem this paragraph was written more
with a segment containing an SYN-AWK or AWK in mind as the next line
reads "The acknowledgment and sequence field values are selected to
make the reset sequence acceptable to the TCP that sent the offending 
segment." It does not make sense to send a RST with AWK and SEQ
acceptable to the other end upon receiving a FIN with no AWK or SYN
to a closed port. 

The ambiguity in the latter is that would never be reached as the
former would have discarded the data gram before any further processing
and generated a RST. 

I believe it is better to not respond with a reset in these situations,
as
this type of packet should never occur "naturally" and is more likely
a pathological attempt at "something" mainly a stack fingerprinting
attempt or an attempt to confuse an "packet observation system" (a
human, or and ids :) upstream.

The included fix is simple when the TCB is checked before any
further processing the packet we simply goto drop instead of
dropwithreset. 
There are other flags that perhaps should be checked for as well such as
a
URG or PSH if the packet bares only these options. 

Jonathan Smith
--- tcp_input.c	Fri Apr 14 19:05:17 2000
+++ tcp_input-fix.c	Fri Apr 14 19:12:32 2000
@@ -610,7 +610,10 @@
 		 */
 		if (inp == 0) {
 			++tcpstat.tcps_noport;
-			goto dropwithreset;
+			if(tiflags & TH_FIN) 
+			  goto drop;
+			else 
+			  goto dropwithreset;
 		}
 	}
 

Visit your host, monkey.org