Bugtraq mailing list archives
Re: traceroute as a flooder
From: cjs () CYNIC NET (Curt Sampson)
Date: Tue, 16 Feb 1999 15:30:13 -0800
I've appended the set of patches for the traceroute bugs that I just commited to NetBSD. (It should work for other BSDs, and perhaps Linux too, if it's using the 4.4BSD traceroute.) This fixes two problems: 1. If uid != 0 (you're not superuser), it checks to see that the source address it's going to use is an address from a local interface that's up and not marked loopback. 2. It checks the return value from select() and, if select fails, exits. I believe that my solution for #2 is better than the one recently committed to FreeBSD because mine exits on all select() errors, not just EINVAL. So if you could somehow convince select() to fail with, for example, EINTR, you still can't utilise this to get around the inter-packet delay. (I don't believe you can do this as it stands, but if someone later adds a signal handler to this program that doesn't exit when a signal is caught, you'd probably be able to do it by sending a rapid stream of that signal to the program.) Also, I don't arbitrarially limit the timeout to a day, though I doubt that makes much difference to anyone. cjs -- Curt Sampson <cjs () cynic net> 604 801 5335 De gustibus, aut bene aut nihil. The most widely ported operating system in the world: http://www.netbsd.org Index: traceroute.c =================================================================== RCS file: /cvsroot/src/usr.sbin/traceroute/traceroute.c,v retrieving revision 1.26 retrieving revision 1.28 diff -u -r1.26 -r1.28 --- traceroute.c 1998/12/09 22:53:29 1.26 +++ traceroute.c 1999/02/16 23:18:40 1.28 @@ -378,7 +379,7 @@ int tos = 0, settos = 0, ttl_flag = 0; register int lsrr = 0; register u_short off = 0; - struct ifaddrlist *al; + struct ifaddrlist *al, *al2; char errbuf[132]; if ((cp = strrchr(argv[0], '/')) != NULL) @@ -699,6 +700,7 @@ /* Get the interface address list */ n = ifaddrlist(&al, errbuf, sizeof errbuf); + al2 = al; if (n < 0) { Fprintf(stderr, "%s: ifaddrlist: %s\n", prog, errbuf); exit(1); @@ -711,8 +713,8 @@ /* Look for a specific device */ if (device != NULL) { - for (i = n; i > 0; --i, ++al) - if (strcmp(device, al->device) == 0) + for (i = n; i > 0; --i, ++al2) + if (strcmp(device, al2->device) == 0) break; if (i <= 0) { Fprintf(stderr, "%s: Can't find interface %s\n", @@ -728,11 +730,11 @@ * Otherwise, use the first interface found. * Warn if there are more than one. */ - setsin(from, al->addr); + setsin(from, al2->addr); if (n > 1 && device == NULL && !find_local_ip(from, to)) { Fprintf(stderr, "%s: Warning: Multiple interfaces found; using %s @ %s\n", - prog, inet_ntoa(from->sin_addr), al->device); + prog, inet_ntoa(from->sin_addr), al2->device); } } else { hi = gethostinfo(source); @@ -754,7 +756,7 @@ * interface address. */ for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap) - if (*ap == al->addr) + if (*ap == al2->addr) break; if (i <= 0) { Fprintf(stderr, @@ -766,6 +768,25 @@ } freehostinfo(hi); } + + /* + * If not root, make sure source address matches a local interface. + * (The list of addresses produced by ifaddrlist() automatically + * excludes interfaces that are marked down and/or loopback.) + */ + if (getuid()) { + al2 = al; + for (i = n; i > 0; --i, ++al2) + if (from->sin_addr.s_addr == al2->addr) + break; + if (i <= 0) { + Fprintf(stderr, "%s: %s is not a valid local address " + "and you are not superuser.\n", prog, + inet_ntoa(from->sin_addr)); + exit(1); + } + } + outip->ip_src = from->sin_addr; #ifndef IP_HDRINCL if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0) { @@ -911,6 +932,7 @@ struct timezone tz; register int cc = 0; int fromlen = sizeof(*fromp); + int retval; FD_ZERO(&fds); FD_SET(sock, &fds); @@ -920,9 +942,16 @@ (void)gettimeofday(&now, &tz); tvsub(&wait, &now); - if (select(sock + 1, &fds, NULL, NULL, &wait) > 0) + retval = select(sock + 1, &fds, NULL, NULL, &wait); + if (retval < 0) { + /* If we continue, we probably just flood the remote host. */ + Fprintf(stderr, "%s: select: %s\n", prog, strerror(errno)); + exit(1); + } + if (retval > 0) { cc = recvfrom(s, (char *)packet, sizeof(packet), 0, (struct sockaddr *)fromp, &fromlen); + } return(cc); }
Current thread:
- traceroute as a flooder Alfonso De Gregorio (Feb 12)
- Re: traceroute as a flooder Kris Kennaway (Feb 13)
- <Possible follow-ups>
- Re: traceroute as a flooder Dag-Erling Smorgrav (Feb 15)
- Re: traceroute as a flooder Curt Sampson (Feb 16)
- Inherent weaknesses in NT system policies mnemonix (Feb 03)
- Re: Inherent weaknesses in NT system policies Matt Hargett (Feb 19)
- Re: traceroute as a flooder Stefan `Sec` Zehl (Feb 18)
- Re: traceroute as a flooder Curt Sampson (Feb 18)
- Re: traceroute as a flooder Curt Sampson (Feb 16)