Yet Another Portscanner (in Python)

I've written a custom TCP port scanner, to handle a broken target sporadically responding with SYN-ACKs even on filtered ports. Nmap detect such ports as open (in syn- and connect-scan modes).

$ sudo ./run.sh -s 172.16.33.1 -d 172.16.33.144 --p0 21 --p1 25 -i vmnet8
INFO:Scanner:res 172.16.33.144:24, res=closed)>
INFO:Scanner:res 172.16.33.144:22, res=open)>
INFO:Scanner:res 172.16.33.144:21, res=filtered)>
INFO:Scanner:res 172.16.33.144:23, res=fake-open)>

The code is working, but has some limitations:
* Locally-generated TCP-RSTs must be suppressed by an external command, for example with iptables -A OUTPUT -p tcp -m tcp --tcp-flags RST RST -j DROP
* Only very basic output format is supported (like shown)

There are a few command line options to tweak:

$ sudo ./run.sh -h
Usage: pscan (-h | -i iface -s src -d dest [--p0 P0] [--p1 P1])
Options:
--version show program's version number and exit
-h, --help show this help message and exit
-i IFACE Interface
-s SRC Source IP address
-d DST Destination IP address
--p0=P0 Min destination port (inclusive)
--p1=P1 Max destination port (non-inclusive)

Expected responses:
* Filtered port (returns nothing): res=filtered
* Closed port (returns RST): res=closed
* Port errorneously returning SYN-ACK, but not ack'ing our PUSH: res=fake-open
* Properly open port: res=open

The following iptables config (to be applied to a test target host) can be used to simulate a broken target and obtain the output shown above.

-A INPUT -p tcp -m tcp --dport 21 -j DROP
-A INPUT -p tcp -m tcp --dport 23 --tcp-flags SYN SYN -j ACCEPT
-A INPUT -p tcp -m tcp --dport 23 -j DROP

To create a dummy TCP/23 listener:

sudo socat TCP4-LISTEN:23,reuseaddr,fork EXEC:cat

The code can be downloaded from https://github.com/grwl/pscan/tags (or https://github.com/grwl/pscan/downloads for development version). If you want to contribute to the project, have a look at these instructions http://help.github.com/fork-a-repo/.