Nmap Development mailing list archives

Spurious port closed bug.


From: James Rogers <jamesmrogers () gmail com>
Date: Wed, 13 Jun 2012 15:27:42 -0400

When a scan of this form is sent

 sudo ./nmap  -n -p 80 nmap.org --packet-trace

 it almost always comes back like this:

SENT (0.2146s) TCP 192.168.5.96:62799 > 74.207.254.18:443 S ttl=57
id=26684 iplen=44  seq=3835492086 win=1024 <mss 1460>
SENT (0.2148s) TCP 192.168.5.96:62799 > 74.207.254.18:80 A ttl=58
id=4759 iplen=40  seq=0 win=1024
SENT (0.7961s) TCP 192.168.5.96:62799 > 74.207.254.18:80 S ttl=55
id=26240 iplen=44  seq=4209866743 win=1024 <mss 1460>

RCVD (0.9954s) TCP 74.207.254.18:80 > 192.168.5.96:62799 SA ttl=52
id=0 iplen=44  seq=3953231165 win=14600 <mss 1356>

and the http is reported as open:
Host is up (0.53s latency).
PORT   STATE SERVICE
80/tcp open  http

(I am ignoring the ICMP packets for this to make the results clearer.)

On a good, fast network it is almost impossible to get the wrong
result.  This makes trouble shooting the issue a problem.  When you
can't recreate it, did you fix the issue, or did the network
congestion just get better.

But on a network that is dropping packets or delivering them out of
order it is a different story. Depending on how bad the network is you
can get a wrong result anywhere from 1 in 10 to 1 in 5 packets.  The
McDonald's network was really bad this morning.

The bad results look like:

SENT (0.2067s) TCP 192.168.5.96:33389 > 74.207.254.18:443 S ttl=40
id=35821 iplen=44  seq=298682555 win=1024 <mss 1460>
SENT (0.2069s) TCP 192.168.5.96:33389 > 74.207.254.18:80 A ttl=46
id=2272 iplen=40  seq=0 win=1024
SENT (0.4014s) TCP 192.168.5.96:33389 > 74.207.254.18:80 S ttl=59
id=16598 iplen=44  seq=2367880103 win=1024 <mss 1460>

RCVD (0.4049s) TCP 74.207.254.18:80 > 192.168.5.96:33389 R ttl=52 id=0
iplen=40  seq=298682555 win=0

Host is up (0.17s latency).
PORT   STATE  SERVICE
80/tcp closed http

Nmap done: 1 IP address (1 host up) scanned in 0.43 seconds

Or even this:

SENT (0.2372s) TCP 192.168.5.96:49360 > 74.207.254.18:443 S ttl=49
id=50774 iplen=44  seq=3212604348 win=1024 <mss 1460>
SENT (0.2374s) TCP 192.168.5.96:49360 > 74.207.254.18:80 A ttl=40
id=24380 iplen=40  seq=0 win=1024
SENT (0.4769s) TCP 192.168.5.96:49360 > 74.207.254.18:80 S ttl=58
id=27597 iplen=44  seq=235178041 win=1024 <mss 1460>

RCVD (0.4823s) TCP 74.207.254.18:443 > 192.168.5.96:49360 SA ttl=52
id=0 iplen=44  seq=155794850 win=14600 <mss 1356>
RCVD (0.4825s) TCP 74.207.254.18:80 > 192.168.5.96:49360 R ttl=52 id=0
iplen=40  seq=3212604348 win=0

Host is up (0.20s latency).
PORT   STATE  SERVICE
80/tcp closed http

This is what RFC 793 says starting on page 64:

If the state is LISTEN then

      second check for an ACK

        Any acknowledgment is bad if it arrives on a connection still in
        the LISTEN state.  An acceptable reset segment should be formed
        for any arriving ACK-bearing segment.  The RST should be
        formatted as follows:

          <SEQ=SEG.ACK><CTL=RST>

        Return.

      third check for a SYN

        If the SYN bit is set, check the security.  If the
        security/compartment on the incoming segment does not exactly
        match the security/compartment in the TCB then send a reset and
        return.

          <SEQ=SEG.ACK><CTL=RST>

        If the SEG.PRC is greater than the TCB.PRC then if allowed by
        the user and the system set TCB.PRC<-SEG.PRC, if not allowed
        send a reset and return.

          <SEQ=SEG.ACK><CTL=RST>

        If the SEG.PRC is less than the TCB.PRC then continue.

        Set RCV.NXT to SEG.SEQ+1, IRS is set to SEG.SEQ and any other
        control or text should be queued for processing later.  ISS
        should be selected and a SYN segment sent of the form:

          <SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK>

        SND.NXT is set to ISS+1 and SND.UNA to ISS.  The connection
        state should be changed to SYN-RECEIVED.  Note that any other
        incoming control or data (combined with SYN) will be processed
        in the SYN-RECEIVED state, but processing of SYN and ACK should
        not be repeated.  If the listen was not fully specified (i.e.,
        the foreign socket was not fully specified), then the
        unspecified fields should be filled in now.

If a syn comes in on a listen port, then it is supposed to send a
syn-ack back.
If an ack comes in on a listen port, then it is supposed to send rst back.

I believe that is happening is that the two packets we send to port
80, an ACK and a SYN are returning in different orders depending on
network quality/congestion.   If the packets get there in SYN - ACK
order then that could really confuse the host on the other side,
especially considering how the sequence numbers are not properly
aligned for a syn, syn-ack, ack handshake.

I am noticing that we never get the receive for all three packets. and
if we get more than just the SA packet back then we think the
connection is closed.

How can I match up the returning packet to the packet that was sent?
I'm not seeing a clear way to differentiate between an RST on the A
packet and the one on the SYN packet.

The strange thing is that the seq number in the RST packet from port
80 on the other host is always equal to the sequence number in the
segment we sent to port 443.   So I am really confused about which
segment this RST belongs to.

I am thinking that if I send all three packets from different ports
then I would know for sure which returning packet belonged to which
sent packet, is that a practical solution?   Is there a command line
option to do that?   Do we match the packets by the ACK  (number - 1)?
 If I put the ack number in the --packet-trace output could this help
us line the acks up to the sends better?
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/


Current thread: