mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Fix OS scan retries when system does not send RST
If the scanning system's OS does not send a RST for unsolicited SYN/ACK, the target port will stay in the SYN-RECEIVED state and will not acknowledge any new SYN from the same port number. Windows in particular does this, making retries basically useless. Solution: change source port number for each run of the osscan engine.
This commit is contained in:
29
osscan2.cc
29
osscan2.cc
@@ -1357,8 +1357,21 @@ HostOsScan::HostOsScan(Target *t) {
|
|||||||
ethsd = NULL;
|
ethsd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpPortBase = o.magic_port_set? o.magic_port : o.magic_port + get_random_u8();
|
if (o.magic_port_set) {
|
||||||
udpPortBase = o.magic_port_set? o.magic_port : o.magic_port + get_random_u8();
|
tcpPortBase = o.magic_port;
|
||||||
|
udpPortBase = o.magic_port;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* It would be best if we could get the next base port from UltraScan to
|
||||||
|
* avoid colliding with port scan states, but realistically there is enough
|
||||||
|
* time between the scan phases and a random 15-bit number is sufficiently
|
||||||
|
* unlikely to overlap. */
|
||||||
|
// See HostOsScan::reInitScanSystem() for explanation:
|
||||||
|
#define PRIME_32K 32261
|
||||||
|
tcpPortBase = 33000 + get_random_uint() % PRIME_32K;
|
||||||
|
udpPortBase = 33000 + get_random_uint() % PRIME_32K;
|
||||||
|
}
|
||||||
|
|
||||||
reInitScanSystem();
|
reInitScanSystem();
|
||||||
|
|
||||||
stats = new ScanStats();
|
stats = new ScanStats();
|
||||||
@@ -1386,6 +1399,18 @@ void HostOsScan::reInitScanSystem() {
|
|||||||
icmpEchoId = get_random_u16();
|
icmpEchoId = get_random_u16();
|
||||||
icmpEchoSeq = 295;
|
icmpEchoSeq = 295;
|
||||||
udpttl = (time(NULL) % 14) + 51;
|
udpttl = (time(NULL) % 14) + 51;
|
||||||
|
if (!o.magic_port_set) {
|
||||||
|
/* Base port must be incremented between rounds because the target port is
|
||||||
|
* in SYN-RECEIVED state, so it will continue to ACK the original sequence
|
||||||
|
* number and ignore the new one based on tcpSeqBase. Many supported
|
||||||
|
* systems send a RST upon receiving the unexpected SYN/ACK, which avoids
|
||||||
|
* this problem, but some (including Windows) drop those instead, so we
|
||||||
|
* have to change the source port to get a new TCP state. */
|
||||||
|
// See UltraScanInfo::increment_base_port() in scan_engine.h for explanation:
|
||||||
|
tcpPortBase = 33000 + (tcpPortBase - 33000 + 256) % PRIME_32K;
|
||||||
|
udpPortBase = 33000 + (udpPortBase - 33000 + 256) % PRIME_32K;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user