nmap_dns.cc
来自「Ubuntu packages of security software。 相」· CC 代码 · 共 1,321 行 · 第 1/3 页
CC
1,321 行
sz = sizeof(buf); if (RegQueryValueEx(hKey, "NameServer", NULL, NULL, (LPBYTE) buf, (LPDWORD) &sz) == ERROR_SUCCESS) add_dns_server(buf); sz = sizeof(buf); if (RegQueryValueEx(hKey, "DhcpNameServer", NULL, NULL, (LPBYTE) buf, (LPDWORD) &sz) == ERROR_SUCCESS) add_dns_server(buf); RegCloseKey(hKey); Snprintf(keybasebuf, sizeof(keybasebuf), "SYSTEM\\%s\\Services\\Tcpip\\Parameters\\Interfaces", controlset); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keybasebuf, 0, KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS) { sz = sizeof(buf); for (i=0; RegEnumKeyEx(hKey, i, buf, &sz, NULL, NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS; i++) { Snprintf(keyname, sizeof(keyname), "SYSTEM\\%s\\Services\\Tcpip\\Parameters\\Interfaces\\%s", controlset, buf); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &hKey2) == ERROR_SUCCESS) { sz = sizeof(buf); if (RegQueryValueEx(hKey2, "DhcpNameServer", NULL, NULL, (LPBYTE) buf, (LPDWORD) &sz) == ERROR_SUCCESS) add_dns_server(buf); sz = sizeof(buf); if (RegQueryValueEx(hKey2, "NameServer", NULL, NULL, (LPBYTE) buf, (LPDWORD) &sz) == ERROR_SUCCESS) add_dns_server(buf); RegCloseKey(hKey2); } sz = sizeof(buf); } RegCloseKey(hKey); }}#endif// Parses /etc/resolv.conf (unix) or the registry (win32) and adds// all the nameservers found via the add_dns_server() function.static void parse_resolvdotconf() {#ifndef WIN32 FILE *fp; char buf[2048], *tp; char ipaddr[16]; fp = fopen("/etc/resolv.conf", "r"); if (fp == NULL) { if (firstrun) error("mass_dns: warning: Unable to open /etc/resolv.conf. Try using --system-dns or specify valid servers with --dns-servers"); return; } while (fgets(buf, sizeof(buf), fp)) { tp = buf; // Clip off comments #, \r, \n while (*tp != '\r' && *tp != '\n' && *tp != '#' && *tp) tp++; *tp = '\0'; tp = buf; // Skip any leading whitespace while (*tp == ' ' || *tp == '\t') tp++; if (sscanf(tp, "nameserver %15s", ipaddr) == 1) add_dns_server(ipaddr); } fclose(fp);#else win32_read_registry("CurrentControlSet");#endif}static void parse_etchosts(char *fname) { FILE *fp; char buf[2048], hname[256], ipaddrstr[16], *tp; struct in_addr ia; host_elem *he; fp = fopen(fname, "r"); if (fp == NULL) return; // silently is OK while (fgets(buf, sizeof(buf), fp)) { tp = buf; // Clip off comments #, \r, \n while (*tp != '\r' && *tp != '\n' && *tp != '#' && *tp) tp++; *tp = '\0'; tp = buf; // Skip any leading whitespace while (*tp == ' ' || *tp == '\t') tp++; if (sscanf(tp, "%15s %255s", ipaddrstr, hname) == 2) { if (inet_pton(AF_INET, ipaddrstr, &ia)) { he = new host_elem; he->name = strdup(hname); he->addr = (u32) ia.s_addr; he->cache_hits = 0; etchosts[he->addr % HASH_TABLE_SIZE].push_front(he); } } } fclose(fp);}void free_etchosts() { host_elem *he; std::list<host_elem *>::iterator hi; int i; for(i=0; i < HASH_TABLE_SIZE; i++){ for(hi = etchosts[i].begin(); hi != etchosts[i].end(); hi++) { he = *hi; if(he) { free(he->name); delete he; } } etchosts[i].clear(); }}/* Executed when the DNS cache is full, ages entries * and removes any with a cache hit of 0 (the least used) */bool remove_and_age(host_elem *host) { if(host->cache_hits) { host->cache_hits /=2; return false; } else return true;}/* Add to the dns cache. If there is no space we age and * remove the least frequently used entries until there * is space */static void addto_etchosts(u32 ip, const char *hname) { static u16 total_size = 0; std::list<host_elem*>::iterator it; host_elem *he; int i; if(lookup_etchosts(ip) != NULL) return; while(total_size >= HASH_TABLE_SIZE) { for(i = 0; i < HASH_TABLE_SIZE; i++) { while((it = find_if(etchosts[i].begin(), etchosts[i].end(), remove_and_age)) != etchosts[i].end()) { etchosts[i].erase(it); total_size--; } } } he = new host_elem; he->name = strdup(hname); he->addr = ip; he->cache_hits = 0; etchosts[ip % HASH_TABLE_SIZE].push_back(he); total_size++;}/* Search for a hostname in the cache and increment * its cache hit counter if found */static char *lookup_etchosts(u32 ip) { std::list<host_elem *>::iterator hostI; host_elem *tpelem; for(hostI = etchosts[ip % HASH_TABLE_SIZE].begin(); hostI != etchosts[ip % HASH_TABLE_SIZE].end(); hostI++) { tpelem = *hostI; if (tpelem->addr == ip) { if(tpelem->cache_hits < UCHAR_MAX) tpelem->cache_hits++; return tpelem->name; } } return NULL;}/* External interface to dns cache */const char *lookup_cached_host(u32 ip) { const char *tmp = lookup_etchosts(ip); return tmp==NULL?"":tmp;}static void etchosts_init(void) { static int initialized = 0; if (initialized) return; initialized = 1;#ifdef WIN32 char windows_dir[1024]; char tpbuf[2048]; int has_backslash; if (!GetWindowsDirectory(windows_dir, sizeof(windows_dir))) fatal("Failed to determine your windows directory"); // If it has a backslash it's C:\, otherwise something like C:\WINNT has_backslash = (windows_dir[strlen(windows_dir)-1] == '\\'); // Windows 95/98/Me: Snprintf(tpbuf, sizeof(tpbuf), "%s%shosts", windows_dir, has_backslash ? "" : "\\"); parse_etchosts(tpbuf); // Windows NT/2000/XP/2K3: Snprintf(tpbuf, sizeof(tpbuf), "%s%ssystem32\\drivers\\etc\\hosts", windows_dir, has_backslash ? "" : "\\"); parse_etchosts(tpbuf);#else parse_etchosts("/etc/hosts");#endif}//------------------- Main loops ---------------------// Actual main loopstatic void nmap_mass_rdns_core(Target **targets, int num_targets) { Target **hostI; std::list<request *>::iterator reqI; request *tpreq; int timeout; char *tpname; int i; bool lasttrace = false; char spmobuf[1024]; if (o.mass_dns == false) { Target *currenths; struct sockaddr_storage ss; size_t sslen; char hostname[MAXHOSTNAMELEN + 1] = ""; for(hostI = targets; hostI < targets+num_targets; hostI++) { currenths = *hostI; if (((currenths->flags & HOST_UP) || o.resolve_all) && !o.noresolve) stat_actual++; } Snprintf(spmobuf, sizeof(spmobuf), "System DNS resolution of %d host%s.", num_targets, num_targets-1 ? "s" : ""); SPM = new ScanProgressMeter(spmobuf); for(i=0, hostI = targets; hostI < targets+num_targets; hostI++, i++) { currenths = *hostI; if (keyWasPressed()) SPM->printStats((double) i / stat_actual, NULL); if (((currenths->flags & HOST_UP) || o.resolve_all) && !o.noresolve) { if (currenths->TargetSockAddr(&ss, &sslen) != 0) fatal("Failed to get target socket address."); if (getnameinfo((struct sockaddr *)&ss, sslen, hostname, sizeof(hostname), NULL, 0, NI_NAMEREQD) == 0) { stat_ok++; currenths->setHostName(hostname); } } } SPM->endTask(NULL, NULL); delete SPM; return; } // If necessary, set up the dns server list from resolv.conf if (servs.size() == 0) { if (o.dns_servers) add_dns_server(o.dns_servers); else parse_resolvdotconf(); if (servs.size() == 0 && firstrun) error("mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns_servers"); } // If necessary, set up the /etc/hosts hashtable etchosts_init(); total_reqs = 0; id_counter = get_random_u16(); // Set up the request structure for(hostI = targets; hostI < targets+num_targets; hostI++) { if (!((*hostI)->flags & HOST_UP) && !o.resolve_all) continue; // See if it's in /etc/hosts or cached tpname = lookup_etchosts((u32) (*hostI)->v4hostip()->s_addr); if (tpname) { (*hostI)->setHostName(tpname); continue; } tpreq = new request; tpreq->targ = *hostI; tpreq->tries = 0; tpreq->servers_tried = 0; tpreq->id = id_counter++; new_reqs.push_back(tpreq); stat_actual++; total_reqs++; } if (total_reqs == 0 || servs.size() == 0) return; // And finally, do it! if ((dnspool = nsp_new(NULL)) == NULL) fatal("Unable to create nsock pool in %s()", __func__); if ((lasttrace = o.packetTrace())) nsp_settrace(dnspool, 5, o.getStartTime()); connect_dns_servers(); cname_reqs.clear(); read_timeout_index = MIN(sizeof(read_timeouts)/sizeof(read_timeouts[0]), servs.size()) - 1; Snprintf(spmobuf, sizeof(spmobuf), "Parallel DNS resolution of %d host%s.", num_targets, num_targets-1 ? "s" : ""); SPM = new ScanProgressMeter(spmobuf); while (total_reqs > 0) { timeout = deal_with_timedout_reads(); do_possible_writes(); if (total_reqs <= 0) break; /* Because this can change with runtime interaction */ if (o.packetTrace() != lasttrace) { lasttrace = !lasttrace; if (lasttrace) nsp_settrace(dnspool, 5, o.getStartTime()); else nsp_settrace(dnspool, 0, o.getStartTime()); } nsock_loop(dnspool, timeout); } SPM->endTask(NULL, NULL); delete SPM; close_dns_servers(); nsp_delete(dnspool); if (cname_reqs.size() && o.debugging) log_write(LOG_STDOUT, "Performing system-dns for %d domain names that use CNAMEs\n", (int) cname_reqs.size()); if (cname_reqs.size()) { Snprintf(spmobuf, sizeof(spmobuf), "System CNAME DNS resolution of %u host%s.", (unsigned) cname_reqs.size(), cname_reqs.size()-1 ? "s" : ""); SPM = new ScanProgressMeter(spmobuf); for(i=0, reqI = cname_reqs.begin(); reqI != cname_reqs.end(); reqI++, i++) { struct sockaddr_storage ss; size_t sslen; char hostname[MAXHOSTNAMELEN + 1] = ""; if (keyWasPressed()) SPM->printStats((double) i / cname_reqs.size(), NULL); tpreq = *reqI; if (tpreq->targ->TargetSockAddr(&ss, &sslen) != 0) fatal("Failed to get target socket address."); if (getnameinfo((struct sockaddr *)&ss, sslen, hostname, sizeof(hostname), NULL, 0, NI_NAMEREQD) == 0) { stat_ok++; stat_cname++; tpreq->targ->setHostName(hostname); } delete tpreq; } SPM->endTask(NULL, NULL); delete SPM; } cname_reqs.clear();}// Publicly available function. Basically just a wrapper so we// can record time information, restart statistics, etc.void nmap_mass_rdns(Target **targets, int num_targets) { struct timeval now; gettimeofday(&starttv, NULL); stat_actual = stat_ok = stat_nx = stat_sf = stat_trans = stat_dropped = stat_cname = 0; nmap_mass_rdns_core(targets, num_targets); gettimeofday(&now, NULL); if (stat_actual > 0) { if (o.debugging || o.verbose >= 3) { if (o.mass_dns) { // #: Number of DNS servers used // OK: Number of fully reverse resolved queries // NX: Number of confirmations of 'No such reverse domain eXists' // DR: Dropped IPs (no valid responses were received) // SF: Number of IPs that got 'Server Failure's // TR: Total number of transmissions necessary. The number of domains is ideal, higher is worse log_write(LOG_STDOUT, "DNS resolution of %d IPs took %.2fs. Mode: Async [#: %lu, OK: %d, NX: %d, DR: %d, SF: %d, TR: %d, CN: %d]\n", stat_actual, TIMEVAL_MSEC_SUBTRACT(now, starttv) / 1000.0, (unsigned long) servs.size(), stat_ok, stat_nx, stat_dropped, stat_sf, stat_trans, stat_cname); } else { log_write(LOG_STDOUT, "DNS resolution of %d IPs took %.2fs. Mode: System [OK: %d, ??: %d]\n", stat_actual, TIMEVAL_MSEC_SUBTRACT(now, starttv) / 1000.0, stat_ok, stat_actual - stat_ok); } } } firstrun=0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?