diff --git a/scan_engine.cc b/scan_engine.cc index 416f40550..afb68fcce 100644 --- a/scan_engine.cc +++ b/scan_engine.cc @@ -1,8 +1,8 @@ /*************************************************************************** * scan_engine.cc -- Includes much of the "engine" functions for scanning, * - * such as pos_scan and ultra_scan. It also includes dependant functions * - * such as those for collecting SYN/connect scan responses. * + * such as ultra_scan. It also includes dependant functions such as those * + * for collecting SYN/connect scan responses. * * * ***********************IMPORTANT NMAP LICENSE TERMS************************ * * @@ -103,7 +103,6 @@ #include "timing.h" #include "NmapOps.h" #include "nmap_tty.h" -#include "nmap_rpc.h" #include "payload.h" #include "Target.h" #include "targets.h" @@ -1684,7 +1683,7 @@ unsigned int UltraScanInfo::numProbesPerHost() { numprobes += ports->proto_ping_count; if (ptech.connecttcpscan) numprobes += ports->syn_ping_count; - } else assert(0); /* TODO: RPC scan */ + } else assert(0); return numprobes; } @@ -3581,7 +3580,7 @@ static UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss, hss->probeSent(packetlen); send_ip_packet(USI->rawsd, ethptr, hss->target->TargetSockAddr(), packet, packetlen); free(packet); - } else assert(0); /* TODO: Maybe RPC scan and the like */ + } else assert(0); /* Now that the probe has been sent, add it to the Queue for this host */ hss->probes_outstanding.push_back(probe); @@ -3701,8 +3700,6 @@ static void sendPingProbe(UltraScanInfo *USI, HostScanStats *hss) { sendArpScanProbe(USI, hss, 0, hss->nextPingSeq(true)); } else if (hss->target->pingprobe.type == PS_ND) { sendNDScanProbe(USI, hss, 0, hss->nextPingSeq(true)); - } else if (USI->scantype == RPC_SCAN) { - assert(0); /* TODO: fill out */ } else { assert(0); } @@ -5412,7 +5409,7 @@ static void waitForResponses(UltraScanInfo *USI) { gotone = get_pcap_result(USI, &stime); } else if (USI->scantype == CONNECT_SCAN) { gotone = do_one_select_round(USI, &stime); - } else assert(0); /* TODO: Must fill this out for maybe rpc scan, etc. */ + } else assert(0); } while (gotone && USI->gstats->num_probes_active > 0); gettimeofday(&USI->now, NULL); @@ -5905,335 +5902,3 @@ void bounce_scan(Target *target, u16 *portarray, int numports, numports, (long) time(NULL) - starttime); return; } - -/* I want to reverse the order of all PORT_TESTING entries in - the scan list -- this way if an intermediate router along the - way got overloaded and dropped the last X packets, they are - likely to get through (and flag us a problem if responsive) - if we let them go first in the next round */ -static void reverse_testing_order(struct portinfolist *pil, struct portinfo *scanarray) { - int nextidx; - struct portinfo *current; - - current = pil->testinglist; - - if (current == NULL || current->state != PORT_TESTING) - return; - - while (1) { - nextidx = current->next; - /* current->state is always PORT_TESTING here */ - current->next = current->prev; // special case 1st node dealt w/later - current->prev = nextidx; // special last TESTING node case dealt w/later - if (nextidx == -1) { - // Every node was in TESTING state - current->prev = -1; // New head of list - pil->testinglist->next = -1; - pil->testinglist = current; - break; - } else if (scanarray[nextidx].state != PORT_TESTING) { - current->prev = -1; // New head of list - pil->testinglist->next = nextidx; - scanarray[nextidx].prev = pil->testinglist - scanarray; - pil->testinglist = current; - break; - } - current = scanarray + nextidx; - } -} - - -/* Used to handle all the "positive-response" scans (where we get a - response telling us that the port is open based on the probe. This - includes SYN Scan, Connect Scan, RPC scan, Window Scan, and ACK - scan. Now ultra_scan() does all of those, except for RPC scan, - which is the only pos_scan now supported. */ -void pos_scan(Target *target, u16 *portarray, int numports, stype scantype) { - o.current_scantype = scantype; - - struct scanstats ss; - int senddelay = 0; - int rpcportsscanned = 0; - struct timeval starttm; - struct portinfo *scan = NULL, *current, *next; - struct portinfolist pil; - struct timeval now; - struct rpcscaninfo rsi; - unsigned long j; - struct serviceDeductions sd; - bool doingOpenFiltered = false; - Port port; - - ScanProgressMeter *SPM = NULL; - - if (target->timedOut(NULL)) - return; - - if (scantype != RPC_SCAN) - fatal("%s now handles only rpc scan", __func__); - - if (target->ports.getStateCounts(PORT_OPEN) == 0 && - (o.servicescan || target->ports.getStateCounts(PORT_OPENFILTERED) == 0)) - return; // RPC Scan only works against already known-open ports - - if (o.debugging) - log_write(LOG_STDOUT, "Starting RPC scan against %s\n", target->NameIP()); - - gettimeofday(&starttm, NULL); - target->startTimeOutClock(&starttm); - - ss.packet_incr = 4; - ss.initial_packet_width = (scantype == RPC_SCAN) ? 2 : 30; - ss.fallback_percent = 0.7; - ss.numqueries_outstanding = 0; - ss.ports_left = numports; - ss.alreadydecreasedqueries = 0; - - memset(&pil, 0, sizeof(pil)); - - ss.min_width = o.min_parallelism ? o.min_parallelism : 1; - ss.max_width = MAX(ss.min_width, o.max_parallelism ? o.max_parallelism : 150); - - ss.initial_packet_width = box(ss.min_width, ss.max_width, ss.initial_packet_width); - ss.numqueries_ideal = ss.initial_packet_width; - - get_rpc_procs(&(rsi.rpc_progs), &(rsi.rpc_number)); - scan = (struct portinfo *) safe_malloc(rsi.rpc_number * sizeof(struct portinfo)); - for (j = 0; j < rsi.rpc_number; j++) { - scan[j].state = PORT_FRESH; - scan[j].portno = rsi.rpc_progs[j]; - scan[j].trynum = 0; - scan[j].prev = j - 1; - scan[j].sd[0] = scan[j].sd[1] = scan[j].sd[2] = -1; - if (j < rsi.rpc_number - 1 ) - scan[j].next = j + 1; - else - scan[j].next = -1; - } - current = pil.testinglist = &scan[0]; - rsi.rpc_current_port = NULL; - - do { - ss.changed = 0; - - if (senddelay > 200000) { - ss.max_width = MIN(ss.max_width, 5); - ss.numqueries_ideal = MIN(ss.max_width, ss.numqueries_ideal); - } - - if (target->timedOut(NULL)) - goto posscan_timedout; - - /* Make sure we have ports left to scan */ - while (1) { - if (doingOpenFiltered) { - rsi.rpc_current_port = target->ports.nextPort(rsi.rpc_current_port, - &port, TCPANDUDPANDSCTP, - PORT_OPENFILTERED); - } else { - rsi.rpc_current_port = target->ports.nextPort(rsi.rpc_current_port, - &port, TCPANDUDPANDSCTP, - PORT_OPEN); - if (!rsi.rpc_current_port && !o.servicescan) { - doingOpenFiltered = true; - continue; - } - } - // When service scan is in use, we only want to scan ports that have already - // been determined to be RPC - - if (!rsi.rpc_current_port) - break; // done! - target->ports.getServiceDeductions(rsi.rpc_current_port->portno, rsi.rpc_current_port->proto, &sd); - if (sd.name && sd.service_tunnel == SERVICE_TUNNEL_NONE && - strcmp(sd.name, "rpcbind") == 0) - break; // Good - an RPC port for us to scan. - } - - if (!rsi.rpc_current_port) - break; /* Woop! Done! */ - - /* Reinit our testinglist so we try each RPC prog */ - pil.testinglist = &scan[0]; - rsi.valid_responses_this_port = 0; - rsi.rpc_status = RPC_STATUS_UNKNOWN; - rpcportsscanned++; - - - // This initial message is way down here because we don't want to print it if - // no RPC ports need scanning. - if (!SPM) { - char scanname[48]; - Snprintf(scanname, sizeof(scanname), "%s against %s", scantype2str(scantype), target->NameIP()); - scanname[sizeof(scanname) - 1] = '\0'; - SPM = new ScanProgressMeter(scanname); - } - - while (pil.testinglist != NULL) { /* While we have live queries or more ports to scan */ - - if (keyWasPressed()) { - // We can print out some status here if we want - } - - /* Check the possible retransmissions first */ - gettimeofday(&now, NULL); - - /* Insure we haven't overrun our allotted time ... */ - if (target->timedOut(&now)) - goto posscan_timedout; - - for ( current = pil.testinglist; current ; current = next) { - /* For each port or RPC program */ - next = (current->next > -1) ? &scan[current->next] : NULL; - if (current->state == PORT_TESTING) { - if ( TIMEVAL_SUBTRACT(now, current->sent[current->trynum]) > target->to.timeout) { - if (current->trynum > 1) { - /* No responses !#$!#@$ firewalled? */ - - if (rsi.valid_responses_this_port == 0) { - if (o.debugging) { - log_write(LOG_STDOUT, "RPC Scan giving up on port %hu proto %d due to repeated lack of response\n", rsi.rpc_current_port->portno, rsi.rpc_current_port->proto); - } - rsi.rpc_status = RPC_STATUS_NOT_RPC; - ss.numqueries_outstanding = 0; - break; - } else { - /* I think I am going to slow down a little */ - target->to.rttvar = MIN(2000000, (int) (target->to.rttvar * 1.2)); - } - - if (o.debugging > 2) { - log_write(LOG_STDOUT, "Moving port or prog %lu to the potentially firewalled list\n", (unsigned long) current->portno); - } - current->state = PORT_FILTERED; /* For various reasons */ - /* First delete from old list */ - if (current->next > -1) - scan[current->next].prev = current->prev; - if (current->prev > -1) - scan[current->prev].next = current->next; - if (current == pil.testinglist) - pil.testinglist = (current->next >= 0) ? &scan[current->next] : NULL; - current->next = -1; - current->prev = -1; - /* Now move into new list */ - - ss.numqueries_outstanding--; - } else { /* timeout ... we've got to resend */ - if (o.scan_delay) - enforce_scan_delay(NULL); - if (o.debugging > 2) - log_write(LOG_STDOUT, "Timeout, resending to portno/progno %lu\n", current->portno); - current->trynum++; - gettimeofday(¤t->sent[current->trynum], NULL); - now = current->sent[current->trynum]; - if (send_rpc_query(target, rsi.rpc_current_port->portno, - rsi.rpc_current_port->proto, - current->portno, current - scan, - current->trynum) == -1) { - /* Futz, I'll give up on this guy ... */ - rsi.rpc_status = RPC_STATUS_NOT_RPC; - break; - } - - if (senddelay) - usleep(senddelay); - } - } - } else { - if (current->state != PORT_FRESH) - fatal("State mismatch!!@ %d", current->state); - /* current->state == PORT_FRESH */ - /* OK, now we have gone through our list of in-transit queries, so now - we try to send off new queries if we can ... */ - if (ss.numqueries_outstanding >= (int) ss.numqueries_ideal) - break; - if (o.scan_delay) - enforce_scan_delay(NULL); - if (o.debugging > 2) - log_write(LOG_STDOUT, "Sending initial query to port/prog %lu\n", current->portno); - /* Otherwise lets send a packet! */ - current->state = PORT_TESTING; - current->trynum = 0; - /* if (!testinglist) testinglist = current; */ - ss.numqueries_outstanding++; - gettimeofday(¤t->sent[0], NULL); - if (send_rpc_query(target, - rsi.rpc_current_port->portno, - rsi.rpc_current_port->proto, current->portno, - current - scan, current->trynum) == -1) { - /* Futz, I'll give up on this guy ... */ - rsi.rpc_status = RPC_STATUS_NOT_RPC; - break; - } - if (senddelay) - usleep(senddelay); - } - } - if (o.debugging > 1) { - log_write(LOG_STDOUT, "Ideal number of queries: %d outstanding: %d max %d ports_left %d timeout %d senddelay: %dus\n", - (int) ss.numqueries_ideal, ss.numqueries_outstanding, ss.max_width, ss.ports_left, target->to.timeout, senddelay); - } - - /* Now that we have sent the packets we wait for responses */ - ss.alreadydecreasedqueries = 0; - /* We only bother worrying about responses if we haven't reached - a conclusion yet */ - if (rsi.rpc_status == RPC_STATUS_UNKNOWN) { - get_rpc_results(target, scan, &ss, &pil, &rsi); - } - if (rsi.rpc_status != RPC_STATUS_UNKNOWN) - break; - - /* I want to reverse the order of all PORT_TESTING entries in - the list -- this way if an intermediate router along the - way got overloaded and dropped the last X packets, they are - likely to get through (and flag us a problem if responsive) - if we let them go first in the next round */ - reverse_testing_order(&pil, scan); - - /* If we timed out while trying to get results -- we're outta here! */ - if (target->timedOut(NULL)) - goto posscan_timedout; - } - - /* Now we figure out the results of the port we just RPC scanned */ - - target->ports.setRPCProbeResults(rsi.rpc_current_port->portno, rsi.rpc_current_port->proto, - rsi.rpc_status, rsi.rpc_program, - rsi.rpc_lowver, rsi.rpc_highver); - - /* Time to put our RPC program scan list back together for the - next port ... */ - for (j = 0; j < rsi.rpc_number; j++) { - scan[j].state = PORT_FRESH; - scan[j].trynum = 0; - scan[j].prev = j - 1; - if (j < rsi.rpc_number - 1) - scan[j].next = j + 1; - else scan[j].next = -1; - } - current = pil.testinglist = &scan[0]; - pil.firewalled = NULL; - - if (o.debugging) { - log_write(LOG_STDOUT, "Finished round. Current stats: numqueries_ideal: %d; min_width: %d; max_width: %d; packet_incr: %d; senddelay: %dus; fallback: %.f%%\n", (int) ss.numqueries_ideal, ss.min_width, ss.max_width, ss.packet_incr, senddelay, floor(100 * ss.fallback_percent)); - } - ss.numqueries_ideal = ss.initial_packet_width; - } while (pil.testinglist); - - numports = rpcportsscanned; - if (SPM && o.verbose && (numports > 0)) { - char scannedportsstr[14]; - Snprintf(scannedportsstr, sizeof(scannedportsstr), "%d %s", numports, (numports > 1) ? "ports" : "port"); - SPM->endTask(NULL, scannedportsstr); - } -posscan_timedout: - target->stopTimeOutClock(NULL); - free(scan); - close_rpc_query_sockets(); - if (SPM) { - delete SPM; - SPM = NULL; - } - return; -} diff --git a/scan_engine.h b/scan_engine.h index 67725cc35..6001c644d 100644 --- a/scan_engine.h +++ b/scan_engine.h @@ -1,8 +1,8 @@ /*************************************************************************** * scan_engine.h -- Includes much of the "engine" functions for scanning, * - * such as pos_scan and ultra_scan. It also includes dependant functions * - * such as those for collecting SYN/connect scan responses. * + * such as ultra_scan. It also includes dependant functions such as * + * those for collecting SYN/connect scan responses. * * * ***********************IMPORTANT NMAP LICENSE TERMS************************ * * @@ -158,11 +158,6 @@ typedef struct probespec { void ultra_scan(std::vector &Targets, struct scan_lists *ports, stype scantype, struct timeout_info *to = NULL); -/* Handles the "positive-response" scans (where we get a response - telling us that the port is open based on the probe. This includes - SYN Scan, Connect Scan, RPC scan, Window Scan, and ACK scan */ -void pos_scan(Target *target, u16 *portarray, int numports, stype scantype); - /* FTP bounce attack scan. This function is rather lame and should be rewritten. But I don't think it is used much anyway. If I'm going to allow FTP bounce scan, I should really allow SOCKS proxy scan. */