} else if (strcmp(long_options[option_index].name, "oS") == 0) {
kiddiefilename = optarg;
} else if (strcmp(long_options[option_index].name, "oH") == 0) {
fatal("HTML output is not yet supported");
} else if (strcmp(long_options[option_index].name, "oX") == 0) {
xmlfilename = optarg;
} else if (strcmp(long_options[option_index].name, "oA") == 0) {
char buf[MAXPATHLEN];
snprintf(buf, sizeof(buf), "%s.nmap", optarg);
normalfilename = strdup(buf);
snprintf(buf, sizeof(buf), "%s.gnmap", optarg);
machinefilename = strdup(buf);
snprintf(buf, sizeof(buf), "%s.xml", optarg);
xmlfilename = strdup(buf);
}
else if (strcmp(long_options[option_index].name, "iL") == 0) {
if (inputfd) {
fatal("Only one input filename allowed");
}
if (!strcmp(optarg, "-")) {
inputfd = stdin;
log_write(LOG_STDOUT, "Reading target specifications from stdin\n");
} else {
inputfd = fopen(optarg, "r");
if (!inputfd) {
fatal("Failed to open input file %s for reading", optarg);
}
log_write(LOG_STDOUT, "Reading target specifications from FILE: %s\n", optarg);
}
} else if (strcmp(long_options[option_index].name, "iR") == 0) {
o.generate_random_ips = 1;
} else if (strcmp(long_options[option_index].name, "sI") == 0) {
o.idlescan = 1;
idleProxy = optarg;
} else if (strcmp(long_options[option_index].name, "vv") == 0) {
/* Compatability hack ... ugly */
o.verbose += 2;
} else {
fatal("Unknown long option (%s) given@#!$#$", long_options[option_index].name);
}
break;
case 'b':
o.bouncescan++;
if (parse_bounce_argument(&ftp, optarg) < 0 ) {
fprintf(stderr, "Your argument to -b is fucked up. Use the normal url style: user:pass@server:port or just use server and use default anon login\n Use -h for help\n");
}
break;
case 'D':
p = optarg;
do {
q = strchr(p, ',');
if (q) *q = '\0';
if (!strcasecmp(p, "me")) {
if (o.decoyturn != -1)
fatal("Can only use 'ME' as a decoy once.\n");
o.decoyturn = o.numdecoys++;
} else {
if (o.numdecoys >= MAX_DECOYS -1)
fatal("You are only allowed %d decoys (if you need more redefine MAX_DECOYS in nmap.h)");
if (resolve(p, &o.decoys[o.numdecoys])) {
o.numdecoys++;
} else {
fatal("Failed to resolve decoy host: %s (must be hostname or IP address", optarg);
if (!o.magic_port) fatal("-g needs nonzero argument");
break;
case 'h': printusage(argv[0], 0); break;
case '?': printusage(argv[0], -1); break;
case 'I': o.identscan++; break;
case 'i':
if (inputfd) {
fatal("Only one input filename allowed");
}
if (!strcmp(optarg, "-")) {
inputfd = stdin;
log_write(LOG_STDOUT, "Reading target specifications from stdin\n");
} else {
inputfd = fopen(optarg, "r");
if (!inputfd) {
fatal("Failed to open input file %s for reading", optarg);
}
log_write(LOG_STDOUT, "Reading target specifications from FILE: %s\n", optarg);
}
break;
case 'M':
o.max_parallelism = atoi(optarg);
if (o.max_parallelism < 1) fatal("Argument to -M must be at least 1!");
if (o.max_parallelism > MAX_SOCKETS_ALLOWED) {
fprintf(stderr, "Warning: You are limited to MAX_SOCKETS_ALLOWED (%d) parallel sockets. If you really need more, change the #define and recompile.\n", MAX_SOCKETS_ALLOWED);
fatal("Unknown timing mode (-T argment). Use either \"Paranoid\", \"Sneaky\", \"Polite\", \"Normal\", \"Aggressive\", \"Insane\" or a number from 0 (Paranoid) to 5 (Insane)");
}
break;
case 'V':
printf("\nnmap V. %s\n", NMAP_VERSION);
exit(0);
break;
case 'v': o.verbose++; break;
}
}
#ifdef WIN32
winip_postopt_init();
#endif
#if HAVE_SIGNAL
if (!o.debugging)
signal(SIGSEGV, sigdie);
#endif
if (o.pingtype == PINGTYPE_UNKNOWN) {
if (o.isr00t) o.pingtype = PINGTYPE_TCP|PINGTYPE_TCP_USE_ACK|PINGTYPE_ICMP;
else o.pingtype = PINGTYPE_TCP;
}
/* Open the log files, now that we know whether the user wants them appended
if (o.verbose) error("No tcp,udp, or ICMP scantype specified, assuming vanilla tcp connect() scan. Use -sP if you really don't want to portscan (and just want to see what hosts are up).");
}
if (o.pingtype != PINGTYPE_NONE && o.spoofsource) {
error("WARNING: If -S is being used to fake your source address, you may also have to use -e <iface> and -P0 . If you are using it to specify your real source address, you can ignore this warning.");
}
if (o.pingtype != PINGTYPE_NONE && o.idlescan) {
error("WARNING: Many people use -P0 w/Idlescan to prevent pings from your true IP");
sleep(1); /* Give ppl a chance for ^C :) */
}
if (o.numdecoys > 1 && o.idlescan) {
error("WARNING: Your decoys won't be used in the Idlescan portion of your scanning (although all packets sent to the target are spoofed anyway");
}
if (o.connectscan && o.spoofsource) {
error("WARNING: -S will not affect the source address used in a connect() scan. Use -sS or another raw scan if you want to use the specified source address for the port scanning stage of nmap");
/* By now, we've got our port lists. Give the user a warning if no
* ports are specified for the type of scan being requested. Other things
* (such as OS ident scan) might break cause no ports were specified, but
* we've given our warning...
*/
if ((o.windowscan|o.synscan|o.connectscan|o.fragscan|o.finscan|o.maimonscan|o.bouncescan|o.nullscan|o.xmasscan|o.ackscan|o.idlescan) && ! ports->tcp_count)
error("WARNING: a TCP scan type was requested, but no tcp ports were specified. Skipping this scan type.");
if (o.udpscan && ! ports->udp_count)
error("WARNING: UDP scan was requested, but no udp ports were specified. Skipping this scan type.");
if (o.ipprotscan && ! ports->prot_count)
error("WARNING: protocol scan was requested, but no protocols were specified to be scanned. Skipping this scan type.");
/* Default dest port for tcp probe */
if (!o.tcp_probe_port) o.tcp_probe_port = DEFAULT_TCP_PROBE_PORT;
fatal("You requested a scan type which requires r00t privileges, and you do not have them.\n");
#else
winip_barf(0);
#endif
}
if (o.numdecoys > 0) {
#ifndef WIN32
fatal("Sorry, but you've got to be r00t to use decoys, boy!");
#else
winip_barf(0);
#endif
}
if (o.fragscan) {
#ifndef WIN32
fatal("Sorry, but fragscan requires r00t privileges\n");
#else
winip_barf(0);
#endif
}
if (o.osscan) {
#ifndef WIN32
fatal("TCP/IP fingerprinting (for OS scan) requires root privileges which you do not appear to possess. Sorry, dude.\n");
#else
winip_barf(0);
#endif
}
}
if (o.numdecoys > 0 && o.rpcscan) {
error("WARNING: RPC scan currently does not make use of decoys so don't count on that protection");
}
if (o.bouncescan && o.pingtype != PINGTYPE_NONE)
log_write(LOG_STDOUT, "Hint: if your bounce scan target hosts aren't reachable from here, remember to use -P0 so we don't try and ping them prior to the scan\n");
fprintf(stderr, "Warning: Packet fragmentation selected on a host other than Linux, OpenBSD, FreeBSD, or NetBSD. This may or may not work.\n");
}
#endif
if (o.max_parallelism > MAX_SOCKETS_ALLOWED) {
error("Warning: You are limited to MAX_SOCKETS_ALLOWED (%d) parallel sockets. If you really need more, change the #define and recompile.\n", MAX_SOCKETS_ALLOWED);
o.max_parallelism = MAX_SOCKETS_ALLOWED;
}
if (o.osscan && o.pingscan) {
fatal("WARNING: OS Scan is unreliable with a ping scan. You need to use a scan type along with it, such as -sS, -sT, -sF, etc instead of -sP");
}
if (o.magic_port_set && o.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.");
/* We need to find what interface to route through if:
* --None have been specified AND
* --We are root and doing tcp ping OR
* --We are doing a raw sock scan and NOT pinging anyone */
if (o.source && !*o.device) {
if (ipaddr2devname(o.device, o.source) != 0) {
fatal("Could not figure out what device to send the packet out on with the source address you gave me! If you are trying to sp00f your scan, this is normal, just give the -e eth0 or -e ppp0 or whatever. Otherwise you can still use -e, but I find it kindof fishy.");
/* more fakeargv junk, BTW malloc'ing extra space in argv[0] doesn't work */
if (quashargv) {
argvlen = strlen(argv[0]);
if (argvlen < strlen(FAKE_ARGV))
fatal("If you want me to fake your argv, you need to call the program with a longer name. Try the full pathname, or rename it fyodorssuperdedouperportscanner");
signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE so our program doesn't crash because
of it, but we really shouldn't get an unsuspected
SIGPIPE */
#endif
if (o.max_parallelism && (i = max_sd()) && i < o.max_parallelism) {
fprintf(stderr, "WARNING: Your specified max_parallel_sockets of %d, but your system says it might only give us %d. Trying anyway\n", o.max_parallelism, i);
}
if (o.debugging > 1) log_write(LOG_STDOUT, "The max # of sockets we are using is: %d\n", o.max_parallelism);
if (randomize) {
if (ports->tcp_count)
shortfry(ports->tcp_ports, ports->tcp_count);
if (ports->udp_count)
shortfry(ports->udp_ports, ports->udp_count);
if (ports->prot_count)
shortfry(ports->prots, ports->prot_count);
}
starttime = time(NULL);
/* Time to create a hostgroup state object filled with all the requested
fprintf(stderr, "WARNING: We could not determine for sure which interface to use, so we are guessing %s . If this is wrong, use -S <my_IP_address>.\n", inet_ntoa(currenths->source_ip));
sourceaddrwarning = 1;
}
}
/* Figure out what link-layer device (interface) to use (ie eth0, ppp0, etc) */
fatal("Could not figure out what device to send the packet out on! You might possibly want to try -S (but this is probably a bigger problem). If you are trying to sp00f the source of a SYN/FIN scan with -S <fakeip>, then you must use -e eth0 (or other devicename) to tell us what interface to use.\n");
/* Set up the decoy */
o.decoys[o.decoyturn] = currenths->source_ip;
/* Time for some actual scanning! */
/* Time for some actual scanning! */
if (o.synscan) pos_scan(currenths, ports->tcp_ports, ports->tcp_count, SYN_SCAN);
if (o.windowscan) pos_scan(currenths, ports->tcp_ports, ports->tcp_count, WINDOW_SCAN);
if (o.connectscan) pos_scan(currenths, ports->tcp_ports, ports->tcp_count, CONNECT_SCAN);
if (o.ackscan) pos_scan(currenths, ports->tcp_ports, ports->tcp_count, ACK_SCAN);
if (o.finscan) super_scan(currenths, ports->tcp_ports, ports->tcp_count, FIN_SCAN);
if (o.xmasscan) super_scan(currenths, ports->tcp_ports, ports->tcp_count, XMAS_SCAN);
if (o.nullscan) super_scan(currenths, ports->tcp_ports, ports->tcp_count, NULL_SCAN);
if (o.maimonscan) super_scan(currenths, ports->tcp_ports,
ports->tcp_count, MAIMON_SCAN);
if (o.udpscan) super_scan(currenths, ports->udp_ports,
ports->udp_count, UDP_SCAN);
if (o.ipprotscan) super_scan(currenths, ports->prots,
ports->prot_count, IPPROT_SCAN);
if (o.idlescan) idle_scan(currenths, ports->tcp_ports,
ports->tcp_count, idleProxy);
if (o.bouncescan) {
if (ftp.sd <= 0) ftp_anon_connect(&ftp);
if (ftp.sd > 0) bounce_scan(currenths, ports->tcp_ports,
ports->tcp_count, &ftp);
}
/* This scantype must be after any TCP or UDP scans since it
* get's it's port scan list from the open port list of the current
* host rather than port list the user specified.
*/
if (o.rpcscan) pos_scan(currenths, NULL, 0, RPC_SCAN);
if (o.osscan) {
os_scan(currenths);
}
if (currenths->timedout) {
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"Skipping host %s (%s) due to host timeout\n", currenths->name,
if (o.debugging) log_write(LOG_STDOUT, "Final times for host: srtt: %d rttvar: %d to: %d\n", currenths->to.srtt, currenths->to.rttvar, currenths->to.timeout);
fprintf(stderr, "I have never seen this type of socket selectable for read only. Please let me know how you did it and what OS you are running (fyodor@insecure.org).\n");
goto success;
}
else {
fprintf(stderr, "Wow, select blatantly lied to us! Please let fyodor know what OS you are running (fyodor@insecure.org).\n");
goto failure;
}
}
failure:
close(sd);
if (o.debugging || o.verbose) log_write(LOG_STDOUT, "identd port not active\n");
return 0;
success:
close(sd);
if (o.debugging || o.verbose) log_write(LOG_STDOUT, "identd port is active\n");
return 1;
}
/* returns 0 for possibly temporary error, -1 means we shouldn't attempt
inetd again on this host */
int getidentinfoz(struct in_addr target, u16 localport, u16 remoteport,
char *owner, int ownersz) {
int sd;
struct sockaddr_in sock;
int res;
char request[16];
char response[1024];
char *p,*q;
char *os;
if (ownersz == 0) return 0;
owner[0] = '\0';
if ((sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{perror("Socket troubles"); exit(1);}
sock.sin_family = AF_INET;
sock.sin_addr.s_addr = target.s_addr;
sock.sin_port = htons(113);
usleep(50000); /* If we aren't careful, we really MIGHT take out inetd,
some are very fragile */
res = connect(sd, (struct sockaddr *) &sock, sizeof(struct sockaddr_in));
if (res < 0 ) {
if (o.debugging)
fprintf(stderr, "Identd port not open, cannot obtain port owner info.\n");
res = snprintf(filename_returned, bufferlen, "%s/%s", dirptr, file);
if (res > 0 && res < bufferlen) {
if (fileexistsandisreadable(filename_returned))
foundsomething = 1;
}
}
#ifndef WIN32
if (!foundsomething) {
pw = getpwuid(getuid());
if (pw) {
res = snprintf(filename_returned, bufferlen, "%s/.nmap/%s", pw->pw_dir, file);
if (res > 0 && res < bufferlen) {
if (fileexistsandisreadable(filename_returned))
foundsomething = 1;
}
}
if (!foundsomething && getuid() != geteuid()) {
pw = getpwuid(geteuid());
if (pw) {
res = snprintf(filename_returned, bufferlen, "%s/nmap/%s", pw->pw_dir, file);
if (res > 0 && res < bufferlen) {
if (fileexistsandisreadable(filename_returned))
foundsomething = 1;
}
}
}
}
#else
if (!foundsomething) { /* Try the nMap directory */
char fnbuf[MAX_PATH];
int i;
res = GetModuleFileName(GetModuleHandle(0), fnbuf, 1024);
if(!res) fatal("GetModuleFileName failed (!)\n");
// Strip it
for(i = res - 1; i >= 0 && fnbuf[i] != '/' && fnbuf[i] != '\\'; i--);
if(i >= 0) // we found it
fnbuf[i] = 0;
res = snprintf(filename_returned, bufferlen, "%s/%s", fnbuf, file);
if(res > 0 && res < bufferlen) {
if (fileexistsandisreadable(filename_returned))
foundsomething = 1;
}
}
#endif
if (!foundsomething) {
res = snprintf(filename_returned, bufferlen, "%s/%s", NMAPDATADIR, file);
if (res > 0 && res < bufferlen) {
if (fileexistsandisreadable(filename_returned))
foundsomething = 1;
}
}
if (foundsomething && (*filename_returned != '.')) {
res = snprintf(dot_buffer, sizeof(dot_buffer), "./%s", file);
if (res > 0 && res < bufferlen) {
if (fileexistsandisreadable(dot_buffer)) {
if (warningcount++ < 5)
error("WARNING! The following files exist and are readable: %s and %s. I am choosing %s for security reasons. set NMAPDIR=. to give priority to files in your local directory", filename_returned, dot_buffer, filename_returned);
}
}
}
if (!foundsomething) {
res = snprintf(filename_returned, bufferlen, "./%s", file);