I am trying to write a port scanner in PHP that correctly identifies whether a port is open, closed or blocked.
Most of the code on the web I have seen or examples given to me are incorrect as all they do is check the result of fsockopen and if its a resource say its open otherwise closed.
This does not account for Firewalls that are dropping packets on the ports.
Therefore the port maybe open from fsockpens perspective but its not truly open.
Before sending me any example code please can you make sure that you have tested that
a) Its not just checking the result of fsockopen
b) you have compared the results of open/closed ports with the results from the following site that allows you to do remote port probes e.g
http://networking.ringofsaturn.com/Tools/probe.php
Test it with
www.google.com
The only 2 ports that should be reported as open are 80 (http) and 443 (https). With fsockopen you will get those 2 as well as another load.
I am currently trying this code
Code:
function testPort($url,$port){
$result = "";
if (!getservbyport($port,"tcp")) {$pname = "N/A";}
else {$pname = getservbyport($port,"tcp");}
echo "Open $url port $port - $pname<br />";
$fp = @fsockopen($url, $port, $errno, $errstr, 2);
$response="";
echo "errorno = $errno error = $errstr <br />";
if (is_resource($fp)){
echo "is resource! fp = $fp<br/>";
$response = fread($fp,4096);
echo "response = $response<br/>";
$stat=socket_get_status($fp);
echo "socket status<br/>";
foreach($stat as $key=>$value){
echo "$key: $value<br />";
}
echo 'Open - $response<br />';
fclose($fp);
}else{
echo "no connection to port: $port<br />";
if($errno==10060){
echo 'Closed - $pname - Timeout<br />';
}else{
echo 'Closed - $pname - $errstr<br />'}
}
}
flush();
return;
}
which for the following 3 ports gives me
21,23,25,53
test port: 21
Open mydomain.com port 21 - ftp
errorno = 0 error =
is resource! fp = Resource id #2
response =
socket status
stream_type: tcp_socket
mode: r+
unread_bytes: 0
seekable:
timed_out: 1
blocked: 1
eof:
test port: 22
Open mydomain.com port 22 - N/A
errorno = 0 error =
is resource! fp = Resource id #3
response = SSH-2.0-OpenSSH_5.1p1 Debian-5
socket status
stream_type: tcp_socket
mode: r+
unread_bytes: 0
seekable:
timed_out:
blocked: 1
eof:
test port: 25
Open mydomain.com port 25 - smtp
errorno = 0 error =
is resource! fp = Resource id #2
response = 220 mydomain.com ESMTP Postfix (Debian/GNU)
socket status
stream_type: tcp_socket
mode: r+
unread_bytes: 0
seekable:
timed_out:
blocked: 1
eof:
test port: 53
Open mydomain.com port 53 - domain
errorno = 10060 error = A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
no connection to port: 53
So I am getting some of the details that
http://networking.ringofsaturn.com/Tools/probe.php manages to return in the response column but its not accuratley determining whether the port is open, closed OR blocked.
Can anyone advice me on the best way to do this. Its not for hacking and I am just new to PHP (c# ASP background) and just want to replicate the behaviour of that site that accuratley reports the port behaviour.
Any help would be much appreciated
Thanks