1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-16 19:39:03 +00:00

Fix --resume from IPv6 scans

This commit is contained in:
dmiller
2020-07-13 16:10:00 +00:00
parent 535e6382d4
commit bdc676238f
5 changed files with 42 additions and 20 deletions

View File

@@ -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]

View File

@@ -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.");

View File

@@ -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;

38
nmap.cc
View File

@@ -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<address addr=\"")))
found = q = q + 16;
while ((q = strstr(q, "\n<address addr=\""))) {
q += 16;
found = strchr(q, '"');
if (!found)
fatal("Unable to parse supposed log file %s. Sorry", fname);
if ((af == AF_INET && !strncmp("\" addrtype=\"ipv4\"", found, 17))
|| (af == AF_INET6 && !strncmp("\" addrtype=\"ipv6\"", found, 17))) {
found = q;
}
}
if (found) {
q = strchr(found, '"');
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) supposed log file %s. Sorry", found, fname);
*q = '"';
} else {
/* OK, I guess (hope) it is a normal log then (-oN) */
@@ -2482,16 +2501,15 @@ int gather_logfile_resumption_state(char *fname, int *myargc, char ***myargv) {
lastipstr = strdup(p + 1);
}
*q = p ? ')' : '\n'; /* recover changed chars */
if (inet_pton(AF_INET, lastipstr, &lastip) == 0)
if (resolve_numeric(lastipstr, 0, lastip, &sslen, af) != 0)
fatal("Unable to parse ip (%s) in supposed log file %s. Sorry", lastipstr, fname);
free(lastipstr);
} else {
error("Warning: You asked for --resume but it doesn't look like any hosts in the log file were successfully scanned. Starting from the beginning.");
lastip.s_addr = 0;
lastip->ss_family = AF_UNSPEC;
}
}
}
o.resume_ip = lastip;
/* Ensure the log file ends with a newline */
filestr[filelen - 1] = '\n';

View File

@@ -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;
}