diff --git a/nmap.cc b/nmap.cc index fd4574701..2b351511a 100644 --- a/nmap.cc +++ b/nmap.cc @@ -521,6 +521,7 @@ public: this->advanced = false; this->af = AF_UNSPEC; this->decoys = false; + this->raw_scan_options = false; } // Pre-specified timing parameters. @@ -535,7 +536,7 @@ public: double pre_scripttimeout; #endif char *machinefilename, *kiddiefilename, *normalfilename, *xmlfilename; - bool iflist, decoys, advanced; + bool iflist, decoys, advanced, raw_scan_options; char *exclude_spec, *exclude_file; char *spoofSource, *decoy_arguments; const char *spoofmac; @@ -751,6 +752,7 @@ void parse_options(int argc, char **argv) { // If they only want open, don't spend extra time (potentially) distinguishing closed from filtered. o.defeat_rst_ratelimit = true; } else if (strcmp(long_options[option_index].name, "scanflags") == 0) { + delayed_options.raw_scan_options = true; o.scanflags = parse_scanflags(optarg); if (o.scanflags < 0) { fatal("--scanflags option must be a number between 0 and 255 (inclusive) or a string like \"URGPSHFIN\"."); @@ -776,6 +778,7 @@ void parse_options(int argc, char **argv) { fatal("Since April 2010, the default unit for --host-timeout is seconds, so your time of \"%s\" is %.1f hours. If this is what you want, use \"%ss\".", optarg, l / 1000.0 / 60 / 60, optarg); delayed_options.pre_host_timeout = l; } else if (strcmp(long_options[option_index].name, "ttl") == 0) { + delayed_options.raw_scan_options = true; o.ttl = atoi(optarg); if (o.ttl < 0 || o.ttl > 255) { fatal("ttl option must be a number between 0 and 255 (inclusive)"); @@ -795,6 +798,7 @@ void parse_options(int argc, char **argv) { /* I need to deal with this later, once I'm sure that I have output files set up, --datadir, etc. */ delayed_options.spoofmac = optarg; + delayed_options.raw_scan_options = true; } else if (strcmp(long_options[option_index].name, "allports") == 0) { o.override_excludeports = true; } else if (strcmp(long_options[option_index].name, "version-intensity") == 0) { @@ -851,6 +855,7 @@ void parse_options(int argc, char **argv) { o.setVersionTrace(true); o.debugging++; } else if (strcmp(long_options[option_index].name, "data") == 0) { + delayed_options.raw_scan_options = true; if (o.extra_payload) fatal("Can't use the --data option(s) multiple times, or together."); u8 *tempbuff=NULL; @@ -865,6 +870,7 @@ void parse_options(int argc, char **argv) { if (o.extra_payload_length > 1400) /* 1500 - IP with opts - TCP with opts. */ error("WARNING: Payloads bigger than 1400 bytes may not be sent successfully."); } else if (strcmp(long_options[option_index].name, "data-string") == 0) { + delayed_options.raw_scan_options = true; if (o.extra_payload) fatal("Can't use the --data option(s) multiple times, or together."); o.extra_payload_length = strlen(optarg); @@ -874,6 +880,7 @@ void parse_options(int argc, char **argv) { error("WARNING: Payloads bigger than 1400 bytes may not be sent successfully."); o.extra_payload = strdup(optarg); } else if (strcmp(long_options[option_index].name, "data-length") == 0) { + delayed_options.raw_scan_options = true; if (o.extra_payload) fatal("Can't use the --data option(s) multiple times, or together."); o.extra_payload_length = (int)strtol(optarg, NULL, 10); @@ -938,6 +945,7 @@ void parse_options(int argc, char **argv) { log_write(LOG_STDOUT, "!!Greets to Van Hauser, Plasmoid, Skyper and the rest of THC!!\n"); exit(0); } else if (strcmp(long_options[option_index].name, "badsum") == 0) { + delayed_options.raw_scan_options = true; o.badsum = true; } else if (strcmp(long_options[option_index].name, "iL") == 0) { if (o.inputfd) { @@ -968,12 +976,14 @@ void parse_options(int argc, char **argv) { o.verbose += 2; if (o.verbose > 10) o.verbose = 10; } else if (strcmp(long_options[option_index].name, "ff") == 0) { + delayed_options.raw_scan_options = true; o.fragscan += 16; } else if (strcmp(long_options[option_index].name, "privileged") == 0) { o.isr00t = 1; } else if (strcmp(long_options[option_index].name, "unprivileged") == 0) { o.isr00t = 0; } else if (strcmp(long_options[option_index].name, "mtu") == 0) { + delayed_options.raw_scan_options = true; o.fragscan = atoi(optarg); if (o.fragscan <= 0 || o.fragscan % 8 != 0) fatal("Data payload MTU must be >0 and multiple of 8"); @@ -992,6 +1002,7 @@ void parse_options(int argc, char **argv) { if (!ptr || o.topportlevel < 1 || ((double)((int)o.topportlevel)) != o.topportlevel) fatal("--top-ports should be an integer 1 or greater"); } else if (strcmp(long_options[option_index].name, "ip-options") == 0) { + delayed_options.raw_scan_options = true; o.ipoptions = (u8*) safe_malloc(4 * 10 + 1); if ((o.ipoptionslen = parse_ip_options(optarg, o.ipoptions, 4 * 10 + 1, &o.ipopt_firsthop, &o.ipopt_lasthop, errstr, sizeof(errstr))) == OP_FAILURE) fatal("%s", errstr); @@ -1056,6 +1067,7 @@ void parse_options(int argc, char **argv) { } break; case 'D': + delayed_options.raw_scan_options = true; delayed_options.decoy_arguments = optarg; break; case 'd': @@ -1082,9 +1094,11 @@ void parse_options(int argc, char **argv) { o.fastscan = true; break; case 'f': + delayed_options.raw_scan_options = true; o.fragscan += 8; break; case 'g': + delayed_options.raw_scan_options = true; o.magic_port = atoi(optarg); o.magic_port_set = true; if (o.magic_port == 0) @@ -1266,6 +1280,7 @@ void parse_options(int argc, char **argv) { if (o.spoofsource) fatal("You can only use the source option once! Use -D -D etc. for decoys\n"); delayed_options.spoofSource = strdup(optarg); + delayed_options.raw_scan_options = true; o.spoofsource = true; break; case 's': @@ -1757,6 +1772,12 @@ void apply_delayed_options() { for (i = o.numdecoys - 1; i > o.decoyturn; i--) o.decoys[i] = o.decoys[i - 1]; } + + if (delayed_options.raw_scan_options && (!o.isr00t || o.connectscan)) { + error("You have specified some options that require raw socket access.\n" + "These options will not be honored %s.", + o.isr00t ? "for TCP Connect scan" : "without the necessary privileges"); + } } // Free some global memory allocations.