From bdc676238f8d1840a42d9923e91e35ad3d6e2d89 Mon Sep 17 00:00:00 2001 From: dmiller Date: Mon, 13 Jul 2020 16:10:00 +0000 Subject: [PATCH] Fix --resume from IPv6 scans --- CHANGELOG | 4 ++++ NmapOps.cc | 6 +++--- NmapOps.h | 8 ++++---- nmap.cc | 38 ++++++++++++++++++++++++++++---------- targets.cc | 6 +++--- 5 files changed, 42 insertions(+), 20 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 989c07c80..6613adfb4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ #Nmap Changelog ($Id$); -*-text-*- +o Allow resuming IPv6 scans with --resume. The address parsing was assuming IPv4 + addresses, leading to "Unable to parse ip" error. In a related fix, MAC addresses + will not be parsed as IP addresses when resuming from XML. [Daniel Miller] + o [GH#1622][GH#2068] Fix reverse-DNS handling of PTR records that are not lowercase. Nmap was failing to identify reverse-DNS names when the DNS server delivered them like ".IN-ADDR.ARPA". [Lucas Nussbaum, Richard Schütz, Daniel Miller] diff --git a/NmapOps.cc b/NmapOps.cc index 650c03896..ff7aa4f18 100644 --- a/NmapOps.cc +++ b/NmapOps.cc @@ -330,7 +330,7 @@ void NmapOps::Initialize() { scanflags = -1; defeat_rst_ratelimit = false; defeat_icmp_ratelimit = false; - resume_ip.s_addr = 0; + resume_ip.ss_family = AF_UNSPEC; osscan_limit = false; osscan_guess = false; numdecoys = 0; @@ -565,8 +565,8 @@ administrator privileges."; fatal("Option --defeat-icmp-ratelimit works only with a UDP scan (-sU)"); } - if (resume_ip.s_addr && generate_random_ips) - resume_ip.s_addr = 0; + if (resume_ip.ss_family != AF_UNSPEC && generate_random_ips) + resume_ip.ss_family = AF_UNSPEC; if (magic_port_set && connectscan) { error("WARNING: -g is incompatible with the default connect() scan (-sT). Use a raw scan such as -sS if you want to set the source port."); diff --git a/NmapOps.h b/NmapOps.h index 78ea32476..a3738cd9f 100644 --- a/NmapOps.h +++ b/NmapOps.h @@ -318,11 +318,11 @@ class NmapOps { when it changes the port's state because of ICMP response, as the latter might be rate-limited. Doing so we can get scan results faster. */ - struct in_addr resume_ip; /* The last IP in the log file if user + struct sockaddr_storage resume_ip; /* The last IP in the log file if user requested --restore . Otherwise - restore_ip.s_addr == 0. Also - target_struct_get will eventually set it - to 0. */ + resume_ip.ss_family == AF_UNSPEC. Also + Target::next_target will eventually set it + to AF_UNSPEC. */ // Version Detection Options bool override_excludeports; diff --git a/nmap.cc b/nmap.cc index 5ad0573bc..3c06f0d83 100644 --- a/nmap.cc +++ b/nmap.cc @@ -2347,7 +2347,9 @@ int gather_logfile_resumption_state(char *fname, int *myargc, char ***myargv) { char *filestr; s64 filelen; char nmap_arg_buffer[4096]; /* roughly aligned with arg_parse limit */ - struct in_addr lastip; + struct sockaddr_storage *lastip = &o.resume_ip; + int af = AF_INET; // default without -6 is ipv4 + size_t sslen; char *p, *q, *found, *lastipstr; /* I love C! */ /* We mmap it read/write since we will change the last char to a newline if it is not already */ filestr = mmapfile(fname, &filelen, O_RDWR); @@ -2427,6 +2429,15 @@ int gather_logfile_resumption_state(char *fname, int *myargc, char ***myargv) { fatal("Unable to parse supposed log file %s. Sorry", fname); } + for (int i=0; i < *myargc; i++) { + if (!strncmp("-4", (*myargv)[i], 2)) { + af = AF_INET; + } + else if (!strncmp("-6", (*myargv)[i], 2)) { + af = AF_INET6; + } + } + /* Now it is time to figure out the last IP that was scanned */ q = p; found = NULL; @@ -2439,22 +2450,30 @@ int gather_logfile_resumption_state(char *fname, int *myargc, char ***myargv) { if (!q) fatal("Unable to parse supposed log file %s. Sorry", fname); *q = '\0'; - if (inet_pton(AF_INET, found, &lastip) == 0) - fatal("Unable to parse supposed log file %s. Sorry", fname); + if (resolve_numeric(found, 0, lastip, &sslen, af) != 0) + fatal("Unable to parse ip (%s) in supposed log file %s. Sorry", found, fname); *q = ' '; } else { /* Let's see if it's an XML log (-oX) */ q = p; found = NULL; - while ((q = strstr(q, "\n
ss_family = AF_UNSPEC; } } } - o.resume_ip = lastip; /* Ensure the log file ends with a newline */ filestr[filelen - 1] = '\n'; diff --git a/targets.cc b/targets.cc index 68dd02cfb..7e9ebe6cb 100644 --- a/targets.cc +++ b/targets.cc @@ -526,10 +526,10 @@ tryagain: /* If we are resuming from a previous scan, we have already finished scanning up to o.resume_ip. */ - if (ss.ss_family == AF_INET && o.resume_ip.s_addr) { - if (o.resume_ip.s_addr == ((struct sockaddr_in *) &ss)->sin_addr.s_addr) + if (o.resume_ip.ss_family != AF_UNSPEC) { + if (!sockaddr_storage_cmp(&o.resume_ip, &ss)) /* We will continue starting with the next IP. */ - o.resume_ip.s_addr = 0; + o.resume_ip.ss_family = AF_UNSPEC; goto tryagain; }