Sunday 27 December 2009

Writing a Port Scanner In PHP

How to write a Port Scanner in PHP

I am pretty new to PHP but one of the things I like about PHP as opposed to other server side scripting languages such as ASP Classic (JavaScript or VBScript) is the amount of functionality that is built into the language. 

With ASP Classic if you want to do anything remotely sexy you have to write a COM component and then register the DLL on the web server which most tech support teams hate to do when they know its a custom COM component so it can be quite a pain to do anything on a socket level, Reverse DNS checks, Whois checks and other functions that are easy to do in PHP.

One of the things I liked about PHP was its socket functionality and I stumbled across a couple of Port Scanner tools on the web however they seemed to give incorrect results when running them against sites where I knew the open ports.

Whether this was due to the firewall running on their webserver preventing access to certain ports I do not know. However to validate whether your port scan results are correct you should run the following test on the server you want to scan to list out all the public ports that are currently listening:

C:\DOCUME~1\me>netstat -a

Active Connections

Proto  Local Address          Foreign Address        State
TCP    somecomputer:http  LISTENING
TCP    somecomputer:epmap  LISTENING
TCP    somecomputer:microsoft-ds  LISTENING
TCP    somecomputer:1032  LISTENING
TCP    somecomputer:1110  LISTENING
TCP    somecomputer:pptp  LISTENING
TCP    somecomputer:2869  LISTENING
TCP    somecomputer:3306  LISTENING
TCP    somecomputer:6670  LISTENING
TCP    somecomputer:netbios-ssn  LISTENING
TCP    somecomputer:1161        ESTABLISHED
TCP    somecomputer:1036  LISTENING
TCP    somecomputer:1110       localhost:4809         ESTABLISHED
TCP    somecomputer:1110       localhost:4857         TIME_WAIT
TCP    somecomputer:1110       localhost:4863         TIME_WAIT

This is just a snapshot of the full output you would expect to get. However for those ports on the server you are checking that appear as LISTENING and who don't have a foreign address that ends in port number of zero then a port scanner tool with full access should be able to find them.

The tool you need to use in PHP for this exercise is the fsockopen function which allows you to open a socket to a port. You can then read in any default response which certain ports will give you whereas for others you will not get any response unless you send a valid request first in a similar way to a Telnet conversation.

You can also check whether a port on a server should respond to a port scan by running a Telnet session on the command prompt e.g

C:\DOCUME~1\me>telnet 80

If you do not get a timeout response then you have an open port.

The PHP port scanner script I wrote can be downloaded here: portscanner.php
To get the best out of it and not be blocked by your public webservers firewall run it from your localhost e.g:

Enter in the domain or IP you are wanting to port scan and then hit run.
For example port scanning one of my sites with this tool returns the following results (I am only showing a few of the results).

The Port is shown in the left hand side column and the right hand side will show either Closed and the error message if the port could not be accessed or Open and any response from the Port or "none" if none was returned.
20 - FTP-Data Closed - Timeout
21 - FTP Closed - Timeout
22 - SSH Open - SSH-2.0-OpenSSH_5.1p1 Debian-5
23 - Telnet Closed - Timeout
25 - SMTP Open - 220 ESMTP Postfix (Debian/GNU)
37 - Time Closed - Timeout
53 - DNS Open - none

The main bit of code is here:
// open the port on the required host and set a timeout to 1 second.
$fp = fsockopen($url, $port, $errno, $errstr, 1);

// check whether object is a valid resource
if (is_resource($fp)){

// check for a response back from the port
$response = trim(fread($fp,4096)); 

Let me know of any problems with it and don't go using it for nefarious means.

Remember hacking is illegal and is actually now considered as terrorism in certain countries. So if you don't want to end up in an orange jump suit being water boarded then don't go off port scanning US military installation networks or you will end up like Gary McKinnon!

No comments: