Date: Sat, 03 Oct 1998 03:01:22 -0400 From: Adam McDougall <mcdougall@ameritech.net> To: security@FreeBSD.ORG Subject: Re: Changing 3-way handshakes to prevent port scans Message-ID: <3615CBC2.CE45793@ameritech.net> References: <199809261709.SAA07885@indigo.ie>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Niall Smart wrote:
>
> On Sep 26, 10:43am, Adam McDougall wrote:
> } Subject: Changing 3-way handshakes to prevent port scans
> > I know someone who has linux patches to alter 3-way handshakes so a
> > 'strobe' portscan returns no open ports, yet normal tcp communication
> > seems unhindered, does anyone have any patches for FreeBSD to do the
> > same? If the patches for linux might help I could attempt to dig them
> > up. Thanks
>
> This just isn't possible. A variety of portscanners exploit particular
> implementation bugs or features to determine if a port is being listened
> on, but strobe simply sends a plain old SYN segment and waits for a
> SYN|ACK, changing that would break TCP. Send me on the patches anyway
> and I'll see what I think they actually do.
>
> You can use ipfw to block port scans from particular hosts.
>
> Niall
>
found the patch..
[-- Attachment #2 --]
diff -cr linux-pure/Documentation/Configure.help linux-patched/Documentation/Configure.help
*** linux-pure/Documentation/Configure.help Wed Dec 10 20:21:47 1997
--- linux-patched/Documentation/Configure.help Mon Jan 12 23:32:32 1998
***************
*** 4111,4116 ****
--- 4111,4134 ----
This is the driver for the Sun ESP SCSI host adapter. The ESP
chipset is present in most SPARC-based computers.
+ TCP connection auditing (aka tcpd)
+ CONFIG_TCP_AUDIT
+ Logs all incoming connection attempts to syslog, whether or not
+ they are being listened to.
+
+ Strobe flood protection
+ CONFIG_STROBE_PROTECT
+ Strobing is what potential crackers will do to see, in a sense,
+ what 'doors' [ports] are open on your computer to the network. With this
+ option, we are able to judge if we are being strobed, and if so, we
+ make ourselves look like we have no ports open to the strober to
+ exploit. We do this by counting the amount of failed connection
+ requests we receive each second from a given IP. If a limit is reached
+ a message is logged and the IP gets nothing other than RST's on
+ each successive connection request. Once the requests stop coming,
+ the IP is ignored for another given amount of time, after which, things
+ will be set back to normal. Author: Jesse Off [joff@iastate.edu]
+
Sparc /dev/openprom compatibility driver
CONFIG_SUN_OPENPROMIO
This driver provides user programs with an interface to the Sparc
diff -cr linux-pure/arch/i386/defconfig linux-patched/arch/i386/defconfig
*** linux-pure/arch/i386/defconfig Mon Sep 22 15:44:01 1997
--- linux-patched/arch/i386/defconfig Mon Jan 12 23:34:13 1998
***************
*** 72,77 ****
--- 72,79 ----
# CONFIG_IP_ACCT is not set
# CONFIG_IP_ROUTER is not set
# CONFIG_NET_IPIP is not set
+ CONFIG_TCP_AUDIT=y
+ CONFIG_STROBE_PROTECT=y
#
# (it is safe to leave these untouched)
diff -cr linux-pure/net/Config.in linux-patched/net/Config.in
*** linux-pure/net/Config.in Tue Aug 12 13:30:22 1997
--- linux-patched/net/Config.in Mon Jan 12 23:33:44 1998
***************
*** 24,27 ****
--- 24,39 ----
if [ "$CONFIG_NETLINK" = "y" ]; then
bool 'Routing messages' CONFIG_RTNETLINK
fi
+ bool 'Strobe flood protection' CONFIG_STROBE_PROTECT
+
+ if [ "$CONFIG_STROBE_PROTECT" = "y" ]; then
+ int 'post-strobe ignore period (secs)' IGNORE_TIME 10
+ fi
+
+ if [ "$CONFIG_STROBE_PROTECT" = "y" ]; then
+ int 'refused connections/sec considered a strobe' MAX_SYN_SEC 3
+ fi
+
+
+ bool 'TCP connection auditing (aka tcpd)' CONFIG_TCP_AUDIT
endmenu
diff -cr linux-pure/net/ipv4/tcp_input.c linux-patched/net/ipv4/tcp_input.c
*** linux-pure/net/ipv4/tcp_input.c Fri Oct 31 13:34:12 1997
--- linux-patched/net/ipv4/tcp_input.c Mon Jan 12 23:33:10 1998
***************
*** 43,48 ****
--- 43,63 ----
#include <linux/random.h>
#include <net/tcp.h>
+
+ #ifdef CONFIG_STROBE_PROTECT
+
+ #define MAX_FLOOD 64 /* a good round number */
+
+
+ static struct flood {
+ u32 ip;
+ unsigned int count;
+ unsigned long timestamp;
+ } flood_hash[MAX_FLOOD];
+ unsigned int dummy_temp, dummy_temp2;
+ #endif
+
+
/*
* Policy code extracted so it's now separate
*/
***************
*** 2311,2316 ****
--- 2326,2386 ----
else
#endif
sk = __tcp_v4_lookup(th, saddr, th->source, daddr, th->dest, dev);
+ if ((th->syn && !th->ack && !th->rst && ip_chk_addr(daddr)==IS_MYADDR) &&
+ !(sk && sk->state == TCP_SYN_RECV)) {
+ #ifdef CONFIG_STROBE_PROTECT
+ dummy_temp2 = dummy_temp = saddr % MAX_FLOOD;
+ /* Ok, this is probably WAY overdue for something as trivial as strobing, and it is still not
+ * perfect, as forged SYN packets can be used deny service for the forged IP [although for not very long]
+ * and it is still possible to get a modified, spoofing, strober to fill up the flood hash. But even
+ * then, it will have to refill up the flood hash every second or so, which means the strobe could take a
+ * LONG time to complete, depending on what MAX_FLOOD is set as. Generally speaking MAX_FLOOD is link
+ * dependent and is the expected maximum connection requests per second _from different sources_ it should be
+ * prepared for. You raise this, you lower chances of anyone getting a meaningful strobe [but also waste memory
+ * for all those flood_structs]. If anyone rewrites a strober to do the spoofing and hash filling mentioned
+ * above, you are even more stupid than me for writing this patch. I still don't know why I did this. I
+ * think I just like playing with hashes :)
+ *
+ * Jesse Off [joff@iastate.edu]
+ */
+ cli(); /* Don't know much about race conditions, cli()/sti() actually needed? */
+ restart_fhash:
+ if ( (flood_hash[dummy_temp].timestamp < xtime.tv_sec) ) { /* simplest case: slot useable */
+ if (!sk) {
+ flood_hash[dummy_temp].ip = saddr;
+ flood_hash[dummy_temp].count = 1;
+ flood_hash[dummy_temp].timestamp = xtime.tv_sec;
+ }
+ } else { /* slot in use */
+ if ( flood_hash[dummy_temp].ip != saddr ) { /* handle collision */
+ dummy_temp = (dummy_temp + 1) % MAX_FLOOD;
+ if (dummy_temp != dummy_temp2) goto restart_fhash;
+ printk(KERN_CRIT "We're being strobed and I cant do a thing! Flood hash full, not good...\n"); }
+ else { /* slot in use by this current ip, increment or deny */
+ if ( flood_hash[dummy_temp].count >= MAX_SYN_SEC ) {
+ if (flood_hash[dummy_temp].count == MAX_SYN_SEC) {
+ printk(KERN_CRIT "Strobe from %d.%d.%d.%d, rejecting until they stop for %d seconds\n",
+ NIPQUAD(saddr), IGNORE_TIME);
+ flood_hash[dummy_temp].count++; /* Takes care of logfile runaway */
+ }
+ flood_hash[dummy_temp].timestamp = xtime.tv_sec + IGNORE_TIME;
+ goto no_tcp_socket; /* DENY */
+ sti();
+ }
+ if (!sk) flood_hash[dummy_temp].count++;
+ }
+ }
+ sti();
+ #endif
+ #ifdef CONFIG_TCP_AUDIT
+ printk( KERN_INFO "TCP connection request from %d.%d.%d.%d, port %d\n",
+ NIPQUAD(saddr), ntohs(th->dest) );
+ #endif
+
+
+
+
+ }
if (!sk)
goto no_tcp_socket;
skb->sk = sk;
***************
*** 2333,2338 ****
--- 2403,2409 ----
return(0);
}
}
+
/*
* If this socket has got a reset it's to all intents and purposes
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3615CBC2.CE45793>
