Verifying Nmap scans

So the other day while talking with Slurpgeit the following issue came up:

During a scan nmap reported 1000 ports filtered for the host, but wireshark told us otherwise a RST was received for a few ports but with a delay of ~18 seconds

Hmm that’s interesting, so that means that if wireshark hadn’t been monitored during the scan, the closed ports would have been missed or even worse what if open ports had been missed? The RTT to the host however were within normal ranges, also a simple ping worked fine without any delay whatsoever. Which brings us to an ancient saying about hacking:

Never trust your tools completely, always verify your results! Then verify them again and finally check that they are correct.

Since this is (assumed) something that doesn’t occur that often, you most probably want to automate the verification step. Unless you love looking at scrolling packets in your wireshark window. We can do it actively (real time sniffing) or passively (pcap) after the scans are done. I choose to implement the latter, the passive and after-the-facts verification. Reason being that all you most probably want is to check if something has gone wrong, if not just continue hacking your target. So let’s setup a lab environment to reproduce this issue and then let’s write a script for it using scapy.

I chose to just create two virtual machines within the same subnet, one being the attacker and one being the victim. To delay the traffic on the victim side I used netem since I didn’t manage to do it with iptables. I delayed one port with the following lines I found on the interwebs:

sudo tc qdisc add dev eth0 root handle 1: prio
sudo tc qdisc add dev eth0 parent 1:1 handle 2: netem delay 5s
sudo tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip sport 22 0xffff flowid 1:1

This will effectively delay all outgoing packets from port 22 with 5 seconds, which is more then enough to make nmap think it’s a filtered port. Fun fact: while playing with netem, if you apply the delay to all packets then nmap won’t even begin to scan the host, since according to it’s arp scan the host is down. Let’s fire up nmap and take a look at the output:

sudo nmap -vv -n -p22 10.50.0.103
Starting Nmap 6.25 ( http://nmap.org ) at 2013-05-07 10:31 PDT
Initiating ARP Ping Scan at 10:31
Scanning 10.50.0.103 [1 port]
Completed ARP Ping Scan at 10:31, 0.01s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 10:31
Scanning 10.50.0.103 [1 port]
Completed SYN Stealth Scan at 10:31, 0.20s elapsed (1 total ports)
Nmap scan report for 10.50.0.103
Host is up (0.00024s latency).
Scanned at 2013-05-07 10:31:03 PDT for 0s
PORT STATE SERVICE
22/tcp filtered ssh
MAC Address: 00:0C:29:8B:B2:D3 (VMware)
Read data files from: /usr/local/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.25 seconds
 Raw packets sent: 3 (116B) | Rcvd: 1 (28B)

Now for the on-the-wire version:

sudo tcpdump -i eth0 -n 'host 10.50.0.103 and port 22'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
10:31:03.679609 IP 10.50.0.107.34123 > 10.50.0.103.22: Flags [S], seq 1904800584, win 1024, options [mss 1460], length 0
10:31:03.780684 IP 10.50.0.107.34124 > 10.50.0.103.22: Flags [S], seq 1904866121, win 1024, options [mss 1460], length 0
10:31:08.679889 IP 10.50.0.103.22 > 10.50.0.107.34123: Flags [R.], seq 0, ack 1904800585, win 0, length 0
10:31:08.781834 IP 10.50.0.103.22 > 10.50.0.107.34124: Flags [R.], seq 0, ack 1904866122, win 0, length 0

That looks exactly as expected right? A nice and clean 5 second delay before we receive the RST,ACK response. Now let’s run our script against the saved pcap and see if it sees the delayed packets:

./scanverify.py delayedresponse.pcap 4
1367887795.686521 5.00033283234 10.50.0.107 10.50.0.103 22 ['RST', 'ACK']
1367887796.788743 5.00114893913 10.50.0.107 10.50.0.103 22 ['RST', 'ACK']

That looks exactly right, doesn’t it? If we redo the test while also having a service listening on port 22 the output looks like this:

./scanverify.py delayedresponse.pcap 4
1367887784.231386 5.00098395348 10.50.0.107 10.50.0.103 22 ['SYN', 'ACK']
1367887784.231386 5.99704408646 10.50.0.107 10.50.0.103 22 ['SYN', 'ACK']

If you don’t know the delay upfront, which is normally the case, you can run the script giving it a threshold of zero and it will then display all responses. You can then look for yourself to see which threshold will fit best to detect ‘delayed responses’. My opinion is that a human is way better at detecting anomalies then a computer, so I’ve left this out of the script on purpose.

The script, an example pcap and some other utils are available on my github:

https://github.com/DiabloHorn/DiabloHorn/tree/master/scanverify

Resources

2 thoughts on “Verifying Nmap scans”

  1. Interesting script! I would take it one step further and parse the Nmap output of a scan run with –reason and verify if the pcap agrees with what Nmap says and misses ;-)

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.