diff options
author | EUcancER <root@euer.krebsco.de> | 2012-04-18 23:14:55 +0200 |
---|---|---|
committer | EUcancER <root@euer.krebsco.de> | 2012-04-18 23:14:55 +0200 |
commit | 3c52c7895c28e7f63e27680bd7ef533b93ec37ba (patch) | |
tree | c5acac4a10aa9a7cf0b5ed82c7e3ead39e823e24 /Reaktor/repos/dnsmap/dnsmap.c | |
parent | 9917d1d3974cb156a434e6f3a518de3ac643163e (diff) |
Reaktor: add dnsmap-0.30
Diffstat (limited to 'Reaktor/repos/dnsmap/dnsmap.c')
-rw-r--r-- | Reaktor/repos/dnsmap/dnsmap.c | 795 |
1 files changed, 795 insertions, 0 deletions
diff --git a/Reaktor/repos/dnsmap/dnsmap.c b/Reaktor/repos/dnsmap/dnsmap.c new file mode 100644 index 00000000..5276e305 --- /dev/null +++ b/Reaktor/repos/dnsmap/dnsmap.c @@ -0,0 +1,795 @@ +/* + * ** dnsmap - DNS Network Mapper by pagvac + * ** Copyright (C) 2010 gnucitizen.org + * ** + * ** This program is free software; you can redistribute it and/or modify + * ** it under the terms of the GNU General Public License as published by + * ** the Free Software Foundation; either version 2 of the License, or + * ** (at your option) any later version. + * ** + * ** This program is distributed in the hope that it will be useful, + * ** but WITHOUT ANY WARRANTY; without even the implied warranty of + * ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * ** GNU General Public License for more details. + * ** + * ** You should have received a copy of the GNU General Public License + * ** along with this program; if not, write to the Free Software + * ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * */ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <netdb.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include "dnsmap.h" // built-in subdomains list and define macros + + +// function prototypes +unsigned short int wildcarDetect(char *, char *); +unsigned short int dodelay(unsigned short int); +unsigned short int isPrivateIP(char *); +unsigned short int isValidDomain(char *); +unsigned short int usesOpenDNS(char *); +unsigned short int isIPblacklisted(char *); + +int main(int argc, char *argv[]) { + + unsigned short int i=0, j=0, k=0, l=0, found=0, ipCount=0, filtIPcount=0, milliseconds=10, intIPcount=0, + wordlist=FALSE, txtResults=FALSE, csvResults=FALSE, + delay=TRUE, filter=FALSE; + unsigned long int start=0, end=0; + char dom[MAXSTRSIZE]={'\0'}, csvResultsFilename[MAXSTRSIZE]={'\0'}, + txtResultsFilename[MAXSTRSIZE]={'\0'}, wordlistFilename[MAXSTRSIZE]={'\0'}, + ipstr[INET_ADDRSTRLEN]={'\0'}, wildcardIpStr[INET_ADDRSTRLEN]={'\0'}, + filterIPs[5][INET_ADDRSTRLEN]={{'\0'}}, + invalidTldIpstr[INET_ADDRSTRLEN]={'\0'}; + void *addr; + char *ipver, *strP; + + struct hostent *h; + // start of IPv6 stuff + struct addrinfo hints, *res, *p; + int status; + char ipv6str[INET6_ADDRSTRLEN]; + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_INET6; // AF_INET or AF_INET6 to force version + hints.ai_socktype = SOCK_STREAM; + // end of IPv6 stuff + + FILE *fpWords,*fpCsvLogs,*fpTxtLogs; + + time_t now; + struct tm *ts; + char timestampBuf[18]; + + printf("%s", BANNER); + + // get the current time + now = time(NULL); + + // timestamp format: yyyy_mm_dd_hhmmss + ts = localtime(&now); + strftime(timestampBuf, sizeof(timestampBuf), "%Y_%m_%d_%H%M%S", ts); + + + // start of *primitive* input validation + // ideally more work should be spent on this! + if(argc==1) { + printf("%s%s", USAGE, EXAMPLES); + exit(1); + } + else if(argc%2==1 && argc>2) { + printf("%s%s", USAGE, EXAMPLES); + exit(1); + } + for(i=0;argv[1][i];++i) // convert domain to lower case + argv[1][i]=(tolower(argv[1][i])); + #if DEBUG + printf("domain: %s\n", argv[1]); + #endif + if(!isValidDomain(argv[1])) { + printf("%s", DOMAINERR); + exit(1); + } + + for(i=0;i<argc;++i) { + if((strlen(argv[i]))>MAXSTRSIZE) { + printf("%s",INPUTERR); + exit(1); + } + } + // end of simple input validation + + /* + else if ((h=gethostbyname(argv[1])) == NULL) { // get the host info + herror("gethostbyname"); + exit(1); + } + */ + + start=(int)time(NULL); + + #if DEBUG + printf("start time: %d\n", (int)start); + #endif + + // parse options + for(i=0;i<argc;++i) { + // save results in file using regular format + if(!strcmp(argv[i],"-r")) { + // contruct path where txt results file will be created + txtResults=TRUE; + //strncpy(csvResultsFilename, argv[(i+1)], MAXSTRSIZE); + strncpy(txtResultsFilename, argv[(i+1)], MAXSTRSIZE-strlen(txtResultsFilename)-1); + fpTxtLogs=fopen(txtResultsFilename, "a"); + if(!fpTxtLogs) { + strncat(txtResultsFilename, "dnsmap_", MAXSTRSIZE-strlen(txtResultsFilename)-1); + strncat(txtResultsFilename, argv[1], MAXSTRSIZE-strlen(txtResultsFilename)-1); + strncat(txtResultsFilename, "_", MAXSTRSIZE-strlen(txtResultsFilename)-1); + strncat(txtResultsFilename, timestampBuf, MAXSTRSIZE-strlen(txtResultsFilename)-1); + // replace dots '.' with underscores '_' in filename + for(l=0;l<strlen(txtResultsFilename);++l) + if(txtResultsFilename[l]=='.') + txtResultsFilename[l]='_'; + strncat(txtResultsFilename, ".txt", MAXSTRSIZE-strlen(txtResultsFilename)-1); + fpTxtLogs=fopen(txtResultsFilename, "a"); + if(!fpTxtLogs) { + printf(CREATEFILEERR); + exit(1); + } + } + } + + // save results in file using CSV format + if(!strcmp(argv[i],"-c")) { + // contruct path where CSV results file will be created + csvResults=TRUE; + strncpy(csvResultsFilename, argv[(i+1)], MAXSTRSIZE-strlen(csvResultsFilename)-1); + fpCsvLogs=fopen(csvResultsFilename, "a"); + if(!fpCsvLogs) { + strncat(csvResultsFilename, "dnsmap_", MAXSTRSIZE-strlen(csvResultsFilename)-1); + strncat(csvResultsFilename, argv[1], MAXSTRSIZE-strlen(csvResultsFilename)-1); + strncat(csvResultsFilename, "_", MAXSTRSIZE-strlen(csvResultsFilename)-1); + strncat(csvResultsFilename, timestampBuf, MAXSTRSIZE-strlen(csvResultsFilename)-1); + // replace dots '.' with underscores '_' in filename + for(l=0;l<strlen(csvResultsFilename);++l) + if(csvResultsFilename[l]=='.') + csvResultsFilename[l]='_'; + strncat(csvResultsFilename, ".csv", MAXSTRSIZE-strlen(csvResultsFilename)-1); + fpCsvLogs=fopen(csvResultsFilename, "a"); + if(!fpCsvLogs) { + printf(CREATEFILEERR); + exit(1); + } + } + } + + // use provided wordlist as opposed to built-in one + if(!strcmp(argv[i],"-w")) { + wordlist=TRUE; + strncpy(wordlistFilename, argv[(i+1)],MAXSTRSIZE); + } + + // delay between subdomain resolution requests + if(!strcmp(argv[i],"-d")) { + if(atoi(argv[(i+1)])<1 || atoi(argv[(i+1)])>300000) { // delay must be between 1 ms and 5 minutes + printf("%s", DELAYINPUTERR); + exit(1); + } + delay=TRUE; + milliseconds=atoi(argv[(i+1)]); + } + // filter out user-provided IP(s) + if(!strcmp(argv[i],"-i")) { + for(filtIPcount=1,j=0;argv[i+1][j]!='\0';++j) + if(argv[i+1][j]==',') + ++filtIPcount; + #if DEBUG + printf("%d IP(s) to filter found\nParsing ...\n", filtIPcount); + #endif + if(filtIPcount<=5) { + printf(FILTERMSG); + strP=strtok(argv[i+1],","); + for(j=0;strP;) { + if(strlen(strP)<INET_ADDRSTRLEN) { + strncpy(filterIPs[j],strP,INET_ADDRSTRLEN); + #if DEBUG + printf("%s\n",filterIPs[j]); + #endif + ++j; + } + strP=strtok(NULL," ,"); + } + } + else { + printf(FILTIPINPUTERR); + exit(1); + } + } + } + + // read subdomains from built-in list + if(!wordlist) { + // openDNS detection + if(usesOpenDNS(invalidTldIpstr)) + printf("%s",OPENDNSMSG); + + // wildcard detection + wildcarDetect(argv[1],wildcardIpStr); + + if(strcmp(invalidTldIpstr,wildcardIpStr)) + printf(WILDCARDWARN); + printf(BUILTINMSG); + if(milliseconds>=1) + printf(DELAYMSG); + + printf("%s", "\n"); + for(i=0;i<(sizeof(sub)/MAXSUBSIZE);++i) { + //skipResolve=FALSE; + strncpy(dom,sub[i],MAXSTRSIZE-strlen(dom)-1); + strncat(dom,".",MAXSTRSIZE-strlen(dom)-1);//TEST + strncat(dom,argv[1],MAXSTRSIZE-strlen(dom)-1); + #if DEBUG + printf("brute-forced domain: %s\n",dom); + #endif + + // ipv6 code modded from www.kame.net + status = getaddrinfo(dom, NULL, &hints, &res); + if ((status=getaddrinfo(dom, NULL, &hints, &res))==0) { + printf("%s\n", dom); + ++found; + if(txtResults) + fprintf(fpTxtLogs, "%s\n", dom); + if(csvResults) + fprintf(fpCsvLogs, "%s", dom); + for(p=res,k=0;p;p=p->ai_next,++k) { + if (p->ai_family==AF_INET6) { // IPv6 + struct sockaddr_in6 *ipv6=(struct sockaddr_in6 *)p->ai_addr; + addr = &(ipv6->sin6_addr); + ipver = "IPv6"; + } + // convert the IP to a string and print it: + inet_ntop(p->ai_family, addr, ipv6str, sizeof ipv6str); + printf("%s address #%d: %s\n",ipver,k+1,ipv6str); + ++ipCount; + if(txtResults) + fprintf(fpTxtLogs,"%s address #%d: %s\n",ipver,k+1,ipv6str); + if(csvResults) + fprintf(fpCsvLogs,",%s", ipv6str); + } + printf("%s", "\n"); + if(txtResults) + fprintf(fpTxtLogs,"\n"); + if(csvResults) + fprintf(fpCsvLogs,"\n"); + freeaddrinfo(res); // free the linked list + } // end of if conditional + h=gethostbyname(dom); + //sprintf(ipstr,inet_ntoa(*((struct in_addr *)h->h_addr_list[0])),"%s"); + //for(j=0;h->h_addr_list[j];++j) { + // sprintf(ipstr,inet_ntoa(*((struct in_addr *)h->h_addr_list[j])),"%s"); + // if(isIPblacklisted(ipstr)) { + // skipResolve=TRUE; + // break; + // } + //} + //if(h && !skipResolve) { + //if(h && !isIPblacklisted(ipstr)) { + if(h && !isIPblacklisted(inet_ntoa(*((struct in_addr *)h->h_addr_list[0])))) { + for(j=0;h->h_addr_list[j];++j) { + sprintf(ipstr,inet_ntoa(*((struct in_addr *)h->h_addr_list[j])),"%s"); + for(k=0;k<filtIPcount;++k) { + if(strcmp(filterIPs[k],ipstr)==0) { // filtered IP found + // 1st IP of array - weird output formatting bug + if(j!=0 && strcmp(wildcardIpStr,filterIPs[k])) { + printf("\n"); + if(txtResults) + fprintf(fpTxtLogs, "%s", "\n"); + if(csvResults) + fprintf(fpCsvLogs, "%s", "\n"); + } + #if DEBUG + printf("%s found and ignored\n",filterIPs[k]); + #endif + filter=TRUE; + if(h->h_addr_list[j+1]) + ++j; + else + break; + } + } + // END OF TEST + //if(strcmp(wildcardIpStr,ipstr) && strcmp(filterIpStr,ipstr)) { + if(strcmp(wildcardIpStr,ipstr) && filter==FALSE) { + if(j==0) { + ++found; + printf("%s\n", dom); + + if(txtResults) + fprintf(fpTxtLogs, "%s\n", dom); + if(csvResults) + fprintf(fpCsvLogs, "%s", dom); + } + printf("[%d] %s : %s\n", j+1,dom,ipstr); + ++ipCount; + + if(isPrivateIP(ipstr)) { + //if(isPrivateIP(inet_ntoa(*((struct in_addr *)h->h_addr_list[j])))) { + printf("%s",INTIPWARN); + ++intIPcount; + } + if(!strcmp(ipstr,"127.0.0.1") && strcmp(wildcardIpStr,ipstr)) { + //if(!strcmp(inet_ntoa(*((struct in_addr *)h->h_addr_list[j])), + //"127.0.0.1")) + printf("%s",SAMESITEXSSWARN); + } + if(txtResults) { + //fprintf(fpCsvLogs,",%s", + // inet_ntoa(*((struct in_addr *)h->h_addr_list[j]))); + fprintf(fpTxtLogs,"IP address #%d: %s\n", j+1, ipstr); + if(isPrivateIP(ipstr) && strcmp(wildcardIpStr,ipstr)) + fprintf(fpTxtLogs,"%s",INTIPWARN); + if(!strcmp(ipstr,"127.0.0.1") && strcmp(wildcardIpStr,ipstr)) + fprintf(fpTxtLogs,"%s",SAMESITEXSSWARN); + } + if(csvResults && strcmp(wildcardIpStr,ipstr)) + fprintf(fpCsvLogs,",%s",ipstr); + } + } + //if(strcmp(wildcardIpStr,ipstr) && strcmp(filterIpStr,ipstr)) { + if(strcmp(wildcardIpStr,ipstr) && filter==FALSE) { + printf("%s", "\n"); + if(txtResults) + fprintf(fpTxtLogs,"%s","\n"); + if(csvResults) + fprintf(fpCsvLogs,"%s","\n"); + } + filter=FALSE; + } + // user wants delay between DNS requests? + if(delay) + dodelay(milliseconds); + } + if(txtResults) + fclose(fpTxtLogs); + if(csvResults) + fclose(fpCsvLogs); + } + + // read subdomains from wordlist file + else if(wordlist) { + // openDNS detection + if(usesOpenDNS(invalidTldIpstr)) + printf("%s",OPENDNSMSG); + + // wildcard detection + wildcarDetect(argv[1],wildcardIpStr); + if(strcmp(invalidTldIpstr,wildcardIpStr)) + printf(WILDCARDWARN); + + fpWords=fopen(wordlistFilename, "r"); + if(fpWords) { + printf(EXTERNALMSG); + if(milliseconds>=1) + printf(DELAYMSG); + printf("%s","\n"); + + while(!feof(fpWords)) { + //strncpy(dom,"",MAXSTRSIZE-strlen(dom)-1); + for(i=0;i<strlen(dom);++i) + dom[i]='\0'; + fscanf(fpWords,"%100s",dom); // wordlist subdomain not allowed to be more than 100 chars + #if DEBUG + printf("lengh of dom: %d\n",strlen(dom)); + #endif + strncat(dom,".",MAXSTRSIZE-strlen(dom)-1); + strncat(dom,argv[1],MAXSTRSIZE-strlen(dom)-1); + + #if DEBUG + printf("brute-forced domain: %s\n",dom); + #endif + // ipv6 code modded from www.kame.net + status = getaddrinfo(dom, NULL, &hints, &res); + if ((status=getaddrinfo(dom, NULL, &hints, &res))==0) { + printf("%s\n", dom); + ++found; + if(txtResults) + fprintf(fpTxtLogs, "%s\n", dom); + if(csvResults) + fprintf(fpCsvLogs, "%s", dom); + for(p=res,k=0;p;p=p->ai_next,++k) { + void *addr; + char *ipver; + if (p->ai_family==AF_INET6) { // IPv6 + struct sockaddr_in6 *ipv6=(struct sockaddr_in6 *)p->ai_addr; + addr = &(ipv6->sin6_addr); + ipver = "IPv6"; + } + // convert the IP to a string and print it: + inet_ntop(p->ai_family, addr, ipv6str, sizeof ipv6str); + printf("%s address #%d: %s\n",ipver,k+1,ipv6str); + ++ipCount; + if(txtResults) + fprintf(fpTxtLogs,"%s address #%d: %s\n",ipver,k+1,ipv6str); + if(csvResults) + fprintf(fpCsvLogs,",%s", ipv6str); + } + printf("%s", "\n"); + if(txtResults) + fprintf(fpTxtLogs,"\n"); + if(csvResults) + fprintf(fpCsvLogs,"\n"); + + freeaddrinfo(res); // free the linked list + // ipv6 code modded from www.kame.net + } // end of if conditional + + h=gethostbyname(dom); + + if(h && !isIPblacklisted(inet_ntoa(*((struct in_addr *)h->h_addr_list[0])))) { + for(j=0;h->h_addr_list[j];++j) { + sprintf(ipstr,inet_ntoa(*((struct in_addr *)h->h_addr_list[j])),"%s"); + //TEST + for(k=0;k<filtIPcount;++k) { + if(strcmp(filterIPs[k],ipstr)==0) { // filtered IP found + // 1st IP of array - weird output formatting bug + if(j!=0 && strcmp(wildcardIpStr,filterIPs[k])) { + printf("\n"); + if(txtResults) + fprintf(fpTxtLogs, "%s", "\n"); + if(csvResults) + fprintf(fpCsvLogs, "%s", "\n"); + } + #if DEBUG + printf("%s found and ignored\n",filterIPs[k]); + #endif + filter=TRUE; + if(h->h_addr_list[j+1]) + ++j; + else + break; + } + } + // END OF TEST + + //if(strcmp(wildcardIpStr,ipstr) && strcmp(filterIpStr,ipstr)) { + if(strcmp(wildcardIpStr,ipstr) && filter==FALSE) { + if(j==0) { + ++found; + printf("%s\n",dom); + + if(txtResults) { + //fprintf(fpCsvLogs,"%s",dom); + fprintf(fpTxtLogs,"%s\n",dom); + } + if(csvResults) { + //fprintf(fpCsvLogs,"%s",dom); + fprintf(fpCsvLogs,"%s",dom); + } + } + printf("IP address #%d: %s\n",j+1,ipstr); + ++ipCount; + + if(isPrivateIP(ipstr) && strcmp(wildcardIpStr,ipstr)) { + printf("%s",INTIPWARN); + ++intIPcount; + } + if(!strcmp(ipstr,"127.0.0.1") && strcmp(wildcardIpStr,ipstr)) + printf("%s",SAMESITEXSSWARN); + if(txtResults && strcmp(wildcardIpStr,ipstr)) { + fprintf(fpTxtLogs,"IP address #%d: %s\n",j+1,ipstr); + if(isPrivateIP(ipstr)) + fprintf(fpTxtLogs,"%s",INTIPWARN); + if(!strcmp(ipstr,"127.0.0.1")) + fprintf(fpTxtLogs,"%s",SAMESITEXSSWARN); + } + if(csvResults && strcmp(wildcardIpStr,ipstr)) + fprintf(fpCsvLogs,",%s",ipstr); + } + } + //if(strcmp(wildcardIpStr,ipstr) && strcmp(filterIpStr,ipstr)) { + if(strcmp(wildcardIpStr,ipstr) && filter==FALSE) { + printf("%s", "\n"); + if(txtResults) + fprintf(fpTxtLogs,"%s","\n"); + if(csvResults) + fprintf(fpCsvLogs,"%s","\n"); + } + filter=FALSE; + } + // user wants delay between DNS requests? + if(delay) + dodelay(milliseconds); + } // end while() loop + fclose(fpWords); + } + else { + printf(OPENFILEERR); + exit(1); + } + if(txtResults) + fclose(fpTxtLogs); + if(csvResults) + fclose(fpCsvLogs); + } + + printf(RESULTSMSG4); + if(intIPcount>=1) + printf(RESULTSMSG1); + + if(txtResults) + printf(RESULTSMSG2); + if(csvResults) + printf(RESULTSMSG5); + + end=(int)time(NULL); + printf(RESULTSMSG3); + + return 0; +} + +// return true if domain wildcards are enabled +unsigned short int wildcarDetect(char *dom, char *ipstr) { + char strTmp[30]={'\0'},s[MAXSTRSIZE]={'\0'}; + unsigned short int i=0,n=0,max=0; + struct hostent *h; + + srand(time(NULL)); + max=rand()%20; + // max should be between 10 and 20 + if(max<10) + max=max+(10-max); + + // generate up to random 20 digits-long subdomain + // e.g. 06312580442146732554 + + for(i=0;i<max;++i) { + n=rand()%10; + sprintf(strTmp, "%d", n); + if(i==0) + strncpy(s,strTmp,MAXSTRSIZE-strlen(s)-1); + else + strncat(s,strTmp,MAXSTRSIZE-strlen(s)-1); + } + strncat(s,".",MAXSTRSIZE-strlen(s)-1); + strncat(s, dom,MAXSTRSIZE-strlen(s)-1); + #if DEBUG + printf("random subdomain for wildcard testing: %s\n",s); + #endif + + // random subdomain resolves, thus wildcards are enabled + h=gethostbyname(s); // replace with getaddrinfo() ? + if(h) { /* + for(i=0;h->h_addr_list[i];++i) { + */ + //sprintf(ipstr,inet_ntoa(*((struct in_addr *)h->h_addr_list[i])),"%s"); + sprintf(ipstr,inet_ntoa(*((struct in_addr *)h->h_addr_list[0])),"%s"); + #if DEBUG + printf("wildcard domain\'s IP address: %s\n",ipstr); + #endif + return TRUE; + } + else + return FALSE; +} + +// return number of milliseconds delayed +unsigned short int dodelay(unsigned short int maxmillisecs) { + unsigned short int n=0; + + srand(time(NULL)); + n=rand()%maxmillisecs; + ++n; + maxmillisecs=n; + #if DEBUG + printf("sleeping %d milliseconds ...\n",maxmillisecs); + #endif + usleep(maxmillisecs*1000); + + return maxmillisecs; +} + +// return true if IP addr is internal (RFC1918) +unsigned short int isPrivateIP(char *ip) { + + char classB[][8]={"172.16.","172.17.","172.18.","172.19.", + "172.20.","172.21.","172.22.","172.23.","172.24.", + "172.25.","172.26.","172.27.","172.28.","172.29.", + "172.30.","172.31."}; + + unsigned short int i=0,j=0; + size_t len = strlen(ip); + + // shortest: 0.0.0.0 - 8 chars inc \0 + // longest: 255.255.255.255 - 16 chars inc \0 + if(len<8 || len>16) + return 0; + // ip addr must have three period signs + for(i=0,j=0;i<len;++i) { + if(ip[i]=='.') + ++j; + } + if(j!=3 || ip[0]=='.' || ip[len-1]=='.') + return 0; + + // 10.0.0.0 - 10.255.255.255 (10/8 prefix) + if(strncmp(ip,"10.",3)==0) + return 1; + + // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) + else if(strncmp(ip,"192.168.",8)==0) + return 1; + + + else { + // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) + for(i=0;i<sizeof(classB)/8;++i) { + if(strncmp(ip,classB[i],7)==0) + return 1; + } + return 0; + } +} + +// return true if domain is valid, false otherwise +unsigned short int isValidDomain(char *d) { + + unsigned int i=0, j=0; + char *tld; + size_t len; + char strTmp[30]={'\0'},s[MAXSTRSIZE]={'\0'}; + unsigned short int n=0,max=0; + + struct hostent *h; + + if(strlen(d)<4) // smallest possible domain provided. e.g. a.pl + return 0; + if(!strstr(d,".")) // target domain must have at least one dot. e.g. target.va, branch.target.va + return 0; + tld=strstr(d,"."); + tld=tld+1; + while(strstr(tld,".")){ + tld=strstr(tld,"."); + tld=tld+1; + } + #if DEBUG + printf("tld\'s length: %d\n",strlen(tld)); + printf("dom: %s tld: %s\n",d,tld); + #endif + if((strlen(tld)<2) || (strlen(tld)>6)) // tld must be between 2-6 char. e.g. .museum, .uk + return FALSE; + + // valid domain can only contain digits, letters, dot (.) and dash symbol (-) + len = strlen(d); + for(i=0;i<len;++i) { + if (!(d[i] >= '0' && d[i] <= '9') && + !(d[i] >= 'a' && d[i] <= 'z') && + !(d[i] >= 'A' && d[i] <= 'Z') && + !(d[i] >= '-' && d[i] <= '.')) + return 0; + } + + srand(time(NULL)); + max=rand()%20; + // max should be between 10 and 20 + if(max<10) + max=max+(10-max); + + // generate up to random 20 digits-long subdomain + // e.g. 06312580442146732554 + + for(i=0;i<max;++i) { + n=rand()%10; + sprintf(strTmp, "%d", n); + if(i==0) + strncpy(s,strTmp,MAXSTRSIZE-strlen(s)-1); + else + strncat(s,strTmp,MAXSTRSIZE-strlen(s)-1); + } + strncat(s,".",MAXSTRSIZE-strlen(s)-1); + strncat(s, d,MAXSTRSIZE-strlen(s)-1); + #if DEBUG + printf("random subdomain for wildcard testing: %s\n",s); + #endif + + // some domains like proboards.com return more than 1 IP address + // when resolving random subdomains (wildcards are enabled) + h=gethostbyname(s); + if(h) { + for(j=0;h->h_addr_list[j];++j) + inet_ntoa(*((struct in_addr *)h->h_addr_list[j])); + if(j>1) { + #if DEBUG + + printf("wildcard domain\'s number of IP address(es): %d" + " (this causes dnsmap to produce false positives)\n",j); + #endif + return FALSE; + } + } + + return TRUE; + +} + +// return true if IP is blacklisted, false otherwise +unsigned short int isIPblacklisted(char *ip) { + int i; + // add you own blacklisted IP addresses here if dnsmap is producing false positives. + // this could be caused by your ISP returning a captive portal search page when + // when requesting invalid domains on your browser + char ips[][INET_ADDRSTRLEN]={ + "81.200.64.50", + "67.215.66.132", + "1.2.3.4", + "0.0.0.0" // add your false positive IPs here + }; + + //for(i=0;ips[i];++i) { + for(i=0;i<(sizeof(ips)/INET_ADDRSTRLEN);++i) { + if(!strcmp(ips[i],ip)) + return TRUE; + } + + return FALSE; +} + + +// return true if usage of public DNS server is detected +// Note: right now this function only detects openDNS, but might be +// updated in the future to detect other common public DNS servers +unsigned short int usesOpenDNS(char *ipstr) { + char strTmp[30]={'\0'}, s[MAXSTRSIZE]={'\0'}, dummyLTD[4]={"xyz"}/*, ipstr[INET_ADDRSTRLEN]={'\0'}*/; + char ips[][INET_ADDRSTRLEN]={"67.215.65.132"}; + unsigned short int i=0,j=0,n=0,max=0; + struct hostent *h; + + srand(time(NULL)); + max=rand()%20; + // max should be between 10 and 20 + if(max<10) + max=max+(10-max); + + // generate up to random 20 digits-long subdomain + // e.g. 06312580442146732554 + + for(i=0;i<max;++i) { + n=rand()%10; + sprintf(strTmp, "%d", n); + if(i==0) + strncpy(s,strTmp,MAXSTRSIZE-strlen(s)-1); + else + strncat(s,strTmp,MAXSTRSIZE-strlen(s)-1); + } + strncat(s,".",MAXSTRSIZE-strlen(s)-1); + strncat(s, dummyLTD,MAXSTRSIZE-strlen(s)-1); + #if DEBUG + printf("random domain for public DNS testing: %s\n",s); + #endif + + // random invalid domain resolves, thus public DNS in use + h=gethostbyname(s); + if(h) { + for(i=0;h->h_addr_list[i];++i) { + sprintf(ipstr,inet_ntoa(*((struct in_addr *)h->h_addr_list[i])),"%s"); + #if DEBUG + printf("public DNS server\'s default IP address #%d: %s\n",i+1,ipstr); + #endif + for(j=0;i<(sizeof(ips)/INET_ADDRSTRLEN);++j) { + if(!strcmp(ips[i],ipstr)) + return TRUE; + } + } + return TRUE; + } + else + return FALSE; +} |