diff --git a/scan_engine.cc b/scan_engine.cc index a1dd77ddd..3e6640af2 100644 --- a/scan_engine.cc +++ b/scan_engine.cc @@ -969,6 +969,7 @@ void UltraScanInfo::Init(std::vector &Targets, const struct scan_lists ethsd = NULL; } } + base_port = UltraScanInfo::increment_base_port(); } /* Return the total number of probes that may be sent to each host. This never @@ -2730,8 +2731,6 @@ void ultra_scan(std::vector &Targets, const struct scan_lists *ports, stype scantype, struct timeout_info *to) { o.current_scantype = scantype; - increment_base_port(); - /* Load up _all_ payloads into a mapped table. Only needed for raw scans. */ init_payloads(); diff --git a/scan_engine.h b/scan_engine.h index ad77dec0a..ec1582af1 100644 --- a/scan_engine.h +++ b/scan_engine.h @@ -620,10 +620,42 @@ public: eth_t *ethsd; u32 seqmask; /* This mask value is used to encode values in sequence numbers. It is set randomly in UltraScanInfo::Init() */ + u16 base_port; + private: unsigned int numInitialTargets; std::multiset::iterator nextI; + /* We encode per-probe information like the tryno in the source + port, for protocols that use ports. (Except when o.magic_port_set is + true--then we honor the requested source port.) The tryno is + encoded as offsets from base_port, a base source port number (see + sport_encode and sport_decode). To avoid interpreting a late response from a + previous invocation of ultra_scan as a response for the same port in the + current invocation, we increase base_port by a healthy amount designed to be + greater than any offset likely to be used by a probe, each time ultra_scan is + run. + + If we don't increase the base port, then there is the risk of something like + the following happening: + 1. Nmap sends an ICMP echo and a TCP ACK probe to port 80 for host discovery. + 2. Nmap receives an ICMP echo reply and marks the host up. + 3. Nmap sends a TCP SYN probe to port 80 for port scanning. + 4. Nmap finally receives a delayed TCP RST in response to its earlier ACK + probe, and wrongly marks port 80 as closed. */ + + /* Base port must be chosen so that there is room to add an 8-bit value (tryno) + * without exceeding 16 bits. We increment modulo the largest prime number N + * such that 33000 + N + 256 < 65536, which ensures no overlapping cycles. */ + // Nearest prime not exceeding 65536 - 256 - 33000: +#define PRIME_32K 32261 + /* Change base_port to a new number in a safe port range that is unlikely to + conflict with nearby past or future invocations of ultra_scan. */ + static u16 increment_base_port() { + static u16 g_base_port = 33000 + get_random_uint() % PRIME_32K; + g_base_port = 33000 + (g_base_port - 33000 + 256) % PRIME_32K; + return g_base_port; + } }; diff --git a/scan_engine_raw.cc b/scan_engine_raw.cc index a9ab6c603..fc5d3ec86 100644 --- a/scan_engine_raw.cc +++ b/scan_engine_raw.cc @@ -198,38 +198,6 @@ u32 UltraProbe::sctpvtag() const { return probes.IP.pd.sctp.vtag; } - - -/* We encode per-probe information like the tryno and pingseq in the source - port, for protocols that use ports. (Except when o.magic_port_set is - true--then we honor the requested source port.) The tryno and pingseq are - encoded as offsets from base_port, a base source port number (see - sport_encode and sport_decode). To avoid interpreting a late response from a - previous invocation of ultra_scan as a response for the same port in the - current invocation, we increase base_port by a healthy amount designed to be - greater than any offset likely to be used by a probe, each time ultra_scan is - run. - - If we don't increase the base port, then there is the risk of something like - the following happening: - 1. Nmap sends an ICMP echo and a TCP ACK probe to port 80 for host discovery. - 2. Nmap receives an ICMP echo reply and marks the host up. - 3. Nmap sends a TCP SYN probe to port 80 for port scanning. - 4. Nmap finally receives a delayed TCP RST in response to its earlier ACK - probe, and wrongly marks port 80 as closed. */ - -/* Base port must be chosen so that there is room to add an 8-bit value (tryno) - * without exceeding 16 bits. We increment modulo the largest prime number N - * such that 33000 + N + 256 < 65536, which ensures no overlapping cycles. */ -// Nearest prime not exceeding 65536 - 256 - 33000: -#define PRIME_32K 32261 -static u16 base_port = 33000 + get_random_uint() % PRIME_32K; -/* Change base_port to a new number in a safe port range that is unlikely to - conflict with nearby past or future invocations of ultra_scan. */ -void increment_base_port() { - base_port = 33000 + (base_port - 33000 + 256) % PRIME_32K; -} - /* The try number can be encoded into a TCP SEQ or ACK field. This returns a 32-bit number which encodes this value along with a simple checksum. Decoding is done by seq32_decode. */ diff --git a/scan_engine_raw.h b/scan_engine_raw.h index 80159cab5..96b05ac50 100644 --- a/scan_engine_raw.h +++ b/scan_engine_raw.h @@ -73,7 +73,6 @@ class HostScanStats; class Target; -void increment_base_port(); int get_ping_pcap_result(UltraScanInfo *USI, struct timeval *stime); void begin_sniffer(UltraScanInfo *USI, std::vector &Targets); UltraProbe *sendArpScanProbe(UltraScanInfo *USI, HostScanStats *hss,