1
0
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:
dmiller
2024-02-26 18:29:09 +00:00
parent f0882dc752
commit 630f2d27bc

View File

@@ -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;
}
} }