nmap_dns.cc

来自「Ubuntu packages of security software。 相」· CC 代码 · 共 1,261 行 · 第 1/3 页

CC
1,261
字号
    s->nsd = nsi_new(dnspool, NULL);    s->reqs_on_wire = 0;    s->capacity = CAPACITY_MIN;    s->write_busy = 0;    nsock_connect_udp(dnspool, s->nsd, connect_evt_handler, NULL, (struct sockaddr *) &s->addr, sizeof(struct sockaddr), 53);    nsock_read(dnspool, s->nsd, read_evt_handler, -1, NULL);    s->connected = 1;  }}#ifdef WIN32void win32_read_registry(char *controlset) {  HKEY hKey;  HKEY hKey2;  char keybasebuf[2048];  char buf[2048], keyname[2048], *p;  DWORD sz, i;  snprintf(keybasebuf, sizeof(keybasebuf), "SYSTEM\\%s\\Services\\Tcpip\\Parameters", controlset);  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keybasebuf,                    0, KEY_READ, &hKey) != ERROR_SUCCESS) {    if (firstrun) error("mass_dns: warning: Error opening registry to read DNS servers. Try using --system-dns or specify valid servers with --dns-servers");    return;  }  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;        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();  }}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) return tpelem->name;  }  return NULL;}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    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 nmap_mass_rdns_core()");  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 + -
显示快捷键?