You have a few options. My first thought would be that there may be an intermediate system that is responding with SYN/ACK packets to prohibited (firewalled) ports. If this is the case, you may be able to distinguish truly-open ports by the TTL of the response. If you saved the XML output of your scan (-oX
or -oA
), you can check the //port/state/@reason_ttl
attribute. This is similar to the technique of "firewalking." You can find some related info here: Firewalking with nmap.
Another alternative would be to use a different scan type. Nmap's SYN scan (-sS
or default when scanning as root) can be detected by the TCP options, MSS, and window size, so an IDS/IPS could be responding to that. Try using the TCP Connect scan (-sT
) instead. Other scan types (ACK, FIN, Maimon, etc) could be used to filter your results; they won't show open ports by themselves, but they could flag some of these "open" ports as firewalled, or at least show that they behave differently. Use caution here, though, since these send very noticeable "bad" packets, and rely on behaviors that aren't often present in modern OSs.
Finally, you can use Nmap's service version detection (-sV
) to identify the services behind the "open" ports. It is likely that the false-positives will simply time-out or send a RST to close the connection soon after opening it. This will slow your scan down a lot, but sometimes it's important to be accurate. I would recommend starting with --version-intensity 0
, which will simply do a banner grab and possibly any probes that are tagged to the specific port being scanned, as opposed to the default, which does this and up to 8 other tests.