1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-09 22:21:29 +00:00
Files
nmap/scan_engine.cc
david 1a87380b44 Merge the difference between this branch at r15954 and
/nmap-exp/david/nmap-token. This brings in the following changes:

Use a strict tryno equality test in check_tryno_pingseq. This appears to
have no effect in the current code, because the way we traverse the
probe list backwards ensures that probes with a higher tryno are tried
first. However this protects against matching the wrong tryno if that
behavior is ever changed.

Factor out the code that checks for a match of a TCP packet.

Add some extra checks when matching up TCP probes, to avoid confusing
responses to SYN and ACK probes when they are sent to the same host on
the same port, with the same tryno and pingseq, in a ping scan that
includes both -PS and -PA. I think this is the only case where there can
be confusion. The new rules are: A SYN/ACK can only be matched to a SYN
probe. A RST/ACK can only be matched to a SYN or FIN. A bare RST cannot
be matched to a SYN or FIN.

Make an important change in the way the tryno and pingseq are encoded
for TCP probes with the ACK flag set when --source-port is in effect.
According to RFC 793, responses to ACK packets on an unestablished
connection (CLOSED and LISTEN states in particular) should send a RST
response with a SEQ value the same as the received ACK value. So for
example, if it's in the CLOSED state and wants to send a RST, it sends
        <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>
if the received packet does not have the ACK flag set, but
        <SEQ=SEG.ACK><CTL=RST>

This caused a problem because in the second case, the response does not
reflect our sent SEQ value, which is where the tryno and pingseq are
encoded. The response's acknowledgement number, while not valid because
the ACK flag is not set, is typically 0. Decoding this with seq32_decode
would result in a decoding error, leading to a
        Bad Sequence number from host
message. In this case the probe was allowed to match any TCP probe with
the same ports and address, even though the pingseq and tryno might be
off or the probe is a different kind of probe entirely (like a SYN
probe).

Here's a summary of what has changed, with <tryno,pingseq> standing for
an encoded tryno and pingseq.
Before:
        Non-ACK probes sent with SEQ=<tryno,pingseq>, ACK=0.
        ACK probes sent with SEQ=<tryno,pingseq>, ACK=random
        Probes matched against ACK and ACK - 1.
Now:
        Non-ACK probes sent with SEQ=<tryno,pingseq>, ACK=0.
        ACK probes sent with SEQ=0, ACK=<tryno,pingseq>.
        Probes matched against ACK, ACK - 1, and SEQ.

Matching against the SEQ field may also help in some other weird cases.
In the LISTEN state, the receiving TCP is supposed to check that "the
security/compartment on the incoming segment does not exactly match the
security/compartment in the TCB," and if it doesn't, return
        <SEQ=SEG.ACK><CTL=RST>
just like in the ACK case. I don't know how common that sort of thing is.
2009-11-04 01:52:59 +00:00

211 KiB