Article
UDP Portscanning in PHP
Using the UDP Portscanning Class
The UDP Port Scanning Class does an excellent job of abstracting the complexities of UDP port scanning. Use of the class is simplicity itself: include the class and new up an object based on the class that's passing it the the target ip address, and optionally, the port to start scanning at, the port to end scanning at, and whether the object should output information as it conducts the scan. By default, the start port is set to 1, the end port is set to 1024, and output is on.
Then call the objects doScan method and assign its output to a variable that will hold the results of the scan as an array. Here's an example:
include ('classes/udpPortScanner.inc');
$udpScanner = new udpPortScanner("$REMOTE_ADDR");
$ports = $udpScanner-> doScan();
if (count($ports) == 0) {
echo "no open udp ports detected.<br/>";
} else {
echo "open udp ports:<br/>";
foreach ($ports as $portNumber => $service) {
echo "$portNumber ($service)<br/>";
}
}
Closing
There are two modifications that I have to make and another that I'd like to make. First, the calculated value of the number of iterations to eliminate false positives resulted in a number that is too low if the network conditions are good, and I was getting ports returned that were not, in fact, open. I modified the code to bump the minimum number of cleanup iterations up to a value of five in order to compensate for this.
A UDP port scanner is heavily reliant upon the network conditions that exist between the two machines. In testing, I had friends in both Australia and South Africa (I'm located in the U.S.) volunteer to be scanned, and the scanner was having a really difficult time detecting closed ports. This was because the network conditions were leading to a very large number of packets being lost in transit, and very long runtimes were encountered. In defense of the scanner, an nmap scan of the first 1024 UDP ports on the host in South Africa took nearly an hour, indicating that this is endemic to UDP port scanning, not to this scanner's implementation. With this in mind, it became obvious that some of the network connections were just too bad to complete a scan in a reasonable amount of time. Because of this, I modified the code to abort if, during the initial network testing scan, more than 40% of the packets were lost. Feel free to eliminate or modify this value, but be warned that scanning over a bad network span can take a considerable amount of time.
Finally, I'd also like to collect information as to what ports Microsoft places its various services on, to complement the getservbyport function, which will only return services that are mapped to the traditional ports on a *nix box. I could then specify which Microsoft service is running on a port, and in a later version, indicate how comprimising this is, and describe methods to disable the service and close the port if it's not in use.
I'd like to thank David LaCroix of suddendecelaration.com for his assistance in setting up tcpdump for me to analyze the UDP port scans that I was conducting against one of his volunteered machines. His assistance was instrumental in completing the debugging of this software. Also, thanks to Daniel Bogan of waferbaby.com and Zak McGregor of carfolio.com, both of whom were helpful in determining that trans-oceanic UDP port scans are not that great an idea.
For additional information on Internet protocols, I highly recommend O'Reilly and Associates "Internet Core Protocols: The Definitive Guide," by Erik A. Hall. You can find more information on O'Reilly's Website.
The official home for the the tcpPortScan and udpPortScan classes is here. You can check there for the latest updates to the classes and to report any problems, issues or suggestions that you have.