Nmap Development mailing list archives
Re: Spurious port closed bug.
From: James Rogers <jamesmrogers () gmail com>
Date: Mon, 18 Jun 2012 15:56:10 -0400
On Wed, Jun 13, 2012 at 3:27 PM, James Rogers <jamesmrogers () gmail com> wrote:
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?
Greetings All, I was able to stop the bug from happening by incrementing the port of the first ack in massping(). Evidently this earlier ack is sometimes triggering a reset to be sent which we were seeing as the response to the later packet. I traced back to where we set the default ports inside validate_scan_lists() and instead of setting them to 443 and 80 for the syn and ack host detection packets I set them to random values above 32,000. Ports in these higher ranges are often allowed to receive packets when port 80 or 443 are heavily guarded by firewall and packet filter rules. By randomizing these host detection ports each time we scan, we could make nmap less predictable and harder to spot. An alternative is to change port 80 to a random higher value if we are tcp scanning for port 80 later. Unfortunately this information is not available to validate_scan_lists at the time port 80 and port 443 are being added to the ping syn and ping ack lists. Thanks, James Rogers
Attachment:
spuriousPortClosedBugFix2.diff
Description:
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://seclists.org/nmap-dev/
Current thread:
- Spurious port closed bug. James Rogers (Jun 13)
- Re: Spurious port closed bug. James Rogers (Jun 18)