From owner-freebsd-security Sat Oct 3 00:02:48 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id AAA08311 for freebsd-security-outgoing; Sat, 3 Oct 1998 00:02:48 -0700 (PDT) (envelope-from owner-freebsd-security@FreeBSD.ORG) Received: from thing.dyn.ml.org (dyn1-tnt12-164.detroit.mi.ameritech.net [209.18.31.164]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id AAA08269 for ; Sat, 3 Oct 1998 00:02:19 -0700 (PDT) (envelope-from mcdougall@ameritech.net) Received: from ameritech.net (bsdx [192.168.1.2]) by thing.dyn.ml.org (8.8.8/8.8.7) with ESMTP id DAA04808 for ; Sat, 3 Oct 1998 03:01:27 -0400 (EDT) (envelope-from mcdougall@ameritech.net) Message-ID: <3615CBC2.CE45793@ameritech.net> Date: Sat, 03 Oct 1998 03:01:22 -0400 From: Adam McDougall X-Mailer: Mozilla 4.06 [en] (X11; I; FreeBSD 3.0-BETA i386) MIME-Version: 1.0 To: security@FreeBSD.ORG Subject: Re: Changing 3-way handshakes to prevent port scans References: <199809261709.SAA07885@indigo.ie> Content-Type: multipart/mixed; boundary="------------F8D091035FCE578D91FA4FEA" Sender: owner-freebsd-security@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org This is a multi-part message in MIME format. --------------F8D091035FCE578D91FA4FEA Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit 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.. --------------F8D091035FCE578D91FA4FEA Content-Type: text/plain; charset=us-ascii; name="strobeprot-tcpd-2.0.33.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="strobeprot-tcpd-2.0.33.patch" 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 #include + + #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 --------------F8D091035FCE578D91FA4FEA-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message