This may be a duplicate post, BUT I've not seen any answer that correctly resolves this.
I'm trying to find a php script that can correctly determine the state of a TCP or UDP port.
I've tried several of the ones I've found online and they all return the wrong results. EG: On my local network I have ports 5000 UDP & 5060 TCP/UDP open and routing correctly.
If I run a test via http://www.ipfingerprints.com/portscan.php or GRC Shields Up then the correct results are returned, but all of the PHP Scripts I've tried fail and show the ports as closed.
I'm running the php script via my hosted account and trying to scan and test my own network.
This is one of the scripts I've tried:
<html>
<head>
<?php echo "<title>Port Scanning " . $_GET['host'] . "</title>"; ?>
</head>
<body>
<?php
ini_set('display_errors', 0);
if(isset($_GET['host']) == true)
$host = $_GET['host'];
else
{
echo "You didn't set the host parameter";
die();
}
if(isset($_GET['sport']) == true)
$sport = $_GET['sport'];
else
{
echo "You didn't set the sport parameter";
die();
}
if(isset($_GET['eport']) == true)
$eport = $_GET['eport'];
else
{
echo "You didn't set the eport parameter";
die();
}
if($sport > $eport)
{
$sport = $eport;
}
$scanned = 0;
$openports = 0;
$maxports = 1;
$totalports = ($eport - $sport) + 1;
$mins = floor(($totalports / 10) / 60);
$secs = ($totalports / 10) - $mins * 60;
echo "<font color=\"blue\">Scanning " . $totalports . " ports on " . $host . ", this should take around " . $mins . " minute(s) and " . $secs . " second(s), probably more depending on local website load, hardware, and other factors.<br/><br/></font>";
flush();
do
{
if($scanned >= $maxports && $maxports != 0)
{
echo "<font color=\"darkgreen\" size=\"4\">Scan limit of " . $maxports . " ports reached, scanning stopped.</font><br/><br/><font color=\"darkred\" size=\"4\">Scanner written by Samo502</font>";
flush();
die();
}
if(fsockopen($host, $sport, $errorno, $errorstr, 0.1))
{
echo "<font color=\"darkgreen\">Port " . $sport . " is open on " . $host . "</font><br/>";
$openports++;
flush();
}
else
{
echo "<font color=\"red\">Port " . $sport . " is not open on " . $host . "</font><br/>";
flush();
}
$scanned++;
$sport++;
} while($sport <= $eport);
echo "<br/><font color=\"blue\">Done, " . $openports . " out of " . $totalports . " ports are open.</font><br/><br/><br/><font color=\"darkred\" size=\"4\">Scanner written by Samo502</font>";
die();
?>
</body>
</html>
Does anyone know of a way to do this correctly ?
Thanks
**UPDATE** I've found this which seems to work a bit better, but it's still not detecting that port 21 is currently open on my network..
http://resources.infosecinstitute.com/php-build-your-own-mini-port-scanner-2/
Any help gratefully received. Thanks
The best solution is to write a wrapper in PHP for nmap
- seriously, you can't recode a better portscan than nmap.
If you really want to do it, you should not simply open TCP port and check wether it does connect, you should start from a lower level of sockets, raw sockets.
$mysocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
This allows you to investigate SYN
, ACK
handshake flags and do stealth or simply faster scans.
You can create (non-blocking) sockets in parallel and check their buffer/connection using socket_select();
, which is the fastest and most reliable way to handle several sockets in PHP. I'd probably use forks or threads or dispatch parts of the code to run a full portscan within the same time as a single port scan.
Other functions you'd like to use are socket_set_timeout()
and socket_set_blocking()
.
shell_exec not working with nmap command
https://unix.stackexchange.com/questions/28732/fastest-way-to-port-scan-nmap
http://phpnmap.sourceforge.net/
Probably the best solution, a PEAR package nmap wrapper: http://pear.php.net/package/Net_Nmap/