Yet Another Portscanner (in Python)

Submitted by abb on Fri, 04/13/2012 - 14:34

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 ./ -s -d --p0 21 --p1 25 -i vmnet8
INFO:Scanner:res, res=closed)>
INFO:Scanner:res, res=open)>
INFO:Scanner:res, res=filtered)>
INFO:Scanner:res, 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 ./ -h
Usage: pscan (-h | -i iface -s src -d dest [--p0 P0] [--p1 P1])
--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 (or for development version). If you want to contribute to the project, have a look at these instructions


+32 (0) 2 215 53 58

Gremwell BVBA
Sint-Katherinastraat 24
1742 Ternat
VAT: BE 0821.897.133.