nmap-web: Port Scanning Made Easy
Hardly a day goes by that you don't read about crackers (blackhats) breaking into a machine and causing problems. While there are a number of ways to break into machines, a very common approach is via back doors. These are typically unguarded ports that are either running an unnecessary service (because the vendor shipped it that way) or perhaps a necessary service (e.g., ftp, Sendmail, ssh) that is being handled by an unsecure software version. After that, the blackhat may often configure a process to listen on a high-numbered port that allows future undetected access. Systems administrators (whitehats) should know what ports are open and what software is answering in order to maintain security on their systems.
nmap-web provides a Web interface to the nmap program and makes port scanning super easy. You can not only tell which ports are open, but also acquire information on what is answering at those ports. nmap-web can be used to answer the following type of questions:
Are you aware of what ports are open on your machines and sure that only those you need are open? That is, would you know if a someone has installed a back door?
Is anyone running an unauthorized Web server?
Can you easily check the version of Sendmail running on hundreds of machines?
Can you easily check the time synchronization of hundreds of machines?
Can you do a quick-n-dirty check of DNS A and PTR records?
Although nmap-web can also be used by blackhats, it is a useful tool for whitehats to stay one step ahead.
A Brief Background on TCP/IP and Ports
A complete discussion of TCP/IP is beyond the scope of this article, and I assume you have some knowledge of networking, but here's a brief background to bring you up to speed.
There are typically 65,536 ports that are available on machines running modern TCP/IP networking protocols. Although the assignment of a particular port number to a protocol is arbitrary, there are a number of well-known ports, such as ftp on port 21, telnet on port 23, Sendmail on port 25, httpd on port 80, etc.
So when you hit a Web site with your favorite browser, it opens a TCP connection to port 80 (by default) on that Web site. Your browser sends some data and the Web site responds, which the Browser then formats for you. If you'd ever like to see this manually, here's an example of how this looks behind the scenes:
My-Machine$ telnet SOME-WEB-SITE 80 \
(assumes no proxies in between)
Trying 18.104.22.168 ......
Connected to SOME-WEB-SITE
Escape character is '^]'.
GET / (<CR>)
(Actual HTML code will be shown \
on your screen)
Connection closed by foreign host.
And here's an example of the conversation/protocol for Sendmail on port 25:
My-Machine$ telnet SOME-MAIL-SERVER 25
Connected to SOME-MAIL-SERVER
Escape character is '^]'.
220 SOME-MAIL-SERVER ESMTP Sendmail \
8.9.3/8.9.3; "DATE FIELD"
>>> EHLO My-Machine
250-SOME-MAIL-SERVER. Hello My-Machine, \
pleased to meet you
>>> MAIL From:<alek@My-Machine>
250 <alek@My-Machine>... Sender ok
>>> RCPT To:<alek@SOME-MAIL-SERVER \
250 <alek@SOME-MAIL-SERVER>... \
354 Enter mail, end with "." on a line by \
250 OAA14516 Message accepted for delivery
alek@SOME-MAIL-SERVER ... Sent (OAA14516 \
Message accepted for delivery)
221 SOME-MAIL-SERVER closing connection
A similar conversation goes on for other protocols such as ftp, ssh, telnet, etc. An interesting thing to note about the Sendmail example above is that the blackhat now knows that you are running Sendmail version 8.9.3 on port 25, which may be useful information. That version happens to be a pretty secure version, but what if you had one machine out of hundreds running an older unsecure version? It is possible to configure Sendmail to hide this information (which is a good idea), but you shouldn't rely on this security through obscurity approach.
Note that the focus of this article (and nmap-web) is on TCP ports -- there are also UDP (and other) types of ports. For instance, DNS queries are often handled via UDP queries to port 53. While these are important (and nmap has extensive capabilities in that area), nmap-web currently only does TCP queries. This is mostly because TCP queries tend to be more of interest, and you can do them without root access. I wanted to minimize privileges for nmap-web.
What is Port Scanning?
Port scanning is (basically) the process of seeing which ports are open and responding to queries. Here's a sample code snippet that attempts a telnet connection to each of the 65,536 ports. On most machines, you will get a connection refused for most of these queries, meaning that the port is not open.
set hostname = SOMEHOSTNAME
@ port = 1
while ( $port <= 65535 )
echo -n "Checking $port ... "
cat /dev/null | telnet $hostname $port
Not only is this output difficult to read, but it took 40 minutes to run. A more efficient approach is to use a port scanner that is optimized to scan all the ports (doing the work in parallel) and present the results in a more readable format. For instance, it took nmap 24 seconds to complete the same type of scan as above. You could run netstat (or lsof) on the local machine to show what ports are open, but these tools don't allow scanning of remote machines. These tools are more useful for obtaining additional information once you figure out something is amiss.
Many of the subtleties of port scanning are beyond the scope of this article -- for instance, firewalls may filter or drop queries, making it more difficult for the port scanner to assess what is out there. On the other hand, port scanners can use advanced features of the TCP/IP protocol to ferret out information that might not be obtainable through normal means. There are many resources on the Web (e.g., Fyodor's Web Site at http://www.insecure.org/) with information on this topic.
Some administrators may think that because they have a firewall they don't have to worry about port scanning, since the firewall blocks these from the Internet. Although that may be true (are you certain your firewall can not be penetrated?) for external access, you should still make sure you aren't vulnerable from internal access. The classic model of a hard exterior (via the firewall) that's soft-n-chewy internally can be improved upon by tightening up stuff on all machines.
What is nmap?
nmap (http://www.insecure.org/nmap/) is a very powerful and easy-to-use tool to check which ports are open/responding on your computer. Note that a lot more things can be done with it (e.g., remote OS fingerprinting). Check out the Web site for further information. It is lightning fast -- depending on the number of ports you scan, rates of 100+hosts/seconds are easily obtainable. Fyodor, who has been very responsive to requests and questions, actively maintains nmap. Here is a quote from SANS:
nmap is perhaps the most versatile and widely used tool for penetration testing today. Offering a wide range of port-scanning techniques, this utility will report which ports are open, who owns each process, which service is typically assigned to the port, the probability of a TCP sequence prediction attack, and more. Another useful feature of nmap is its ability to remotely fingerprint a machine's operating system. This utility has become the penetration tester's Swiss Army Knife. (http://www.sans.org).
If nothing else, this quote should convince administrators that they need to be using something like nmap (or nmap-web) for port scanning so they can stay one step ahead of crackers.
What is nmap-web?
I wrote nmap-web because I wanted an easy-to-use Web interface to nmap. My initial interest was a quick-n-dirty way to determine which machines were running Web servers, since there was a corporate effort underway to get a handle on this. But it quickly became obvious that there were other interesting things one could do with it. Since a picture is worth a thousand words, check out Figure 1:
The abbreviated example in Figure 1 (I didn't want to show all 1,000+ UNIX boxes) demonstrates a scan of port 80 (default for HTTPD). From the top, the figure shows:
Select port(s) to check: This is a pull-down that lists which port(s) you want to scan for. This is defined by the administrator who installed nmap-web. So, you can control the type of scans that are allowed.
Port Numbers: Click here to see information on port numbers and what is typically running on that port (e.g., port 80 is typically httpd).
Show machines that appear but do not seem to be up: If a machine is not pingable, then we assume it must not be running (see mojo in the lower frame). It's usually a good idea to have this selected, unless you have a lot of down machines and don't want them to clutter the display.
Show machines that don't answer at any of the selected ports: A machine may be up but not answering at the selected port (in this example, no Web servers are running on africa, nowhere, and perth). Similar to comments above, you can decide whether this information is of interest to you.
Get program/version information running on an individual port selected: If not clicked, then nmap-web will just display whether something is answering at the port. If you do select it, then nmap-web will try to determine what version of software is running there. In this example, we can see various types of Web servers and versions.
Select one of these groupings: The administrator who installs nmap-web can preload a list of hosts or netgroups that show up in this box, so it's easy to quickly take a look at machines of interest.
Enter a space-separated list to scan: Enter the name(s) of hosts you want to scan or their IP addresses. Some wildcards are allowed to do subnet scanning.
Start the Scan
Help/Information/README: Miscellaneous information about nmap-web.
Once you have defined your scan and hit Start the Scan, the bottom frame shows the results. It gives a count of the number of machines and shows what is being scanned. In the left column, it shows each IP/hostname. Forward or reverse lookups are done depending on whether you enter hostnames or IP addresses. For example, if the IP address for nowhere cannot be found, it shows unresolvable. This is rather handy, since errors in your DNS configuration will be obvious, and it's especially easy to forget a reverse PTR record. The right column shows the results of the scan. Since we clicked on show version, nmap-web shows what is running on that port. The standard Web server is Apache (defined by the admin who installed nmap-web), so anything answering as something different is highlighted in red. There's also some summary information at the bottom.
So, not only did we find out which machines are running Web servers (determined by seeing if something was answering on port 80), but we also got a list of type of Web servers and even a misconfigured DNS entry as a bonus!
Figure 2 shows another useful way of using nmap-web. On this network, port 13 (daytime) is enabled via inetd. So, you can do a telnet HOST 13, and it will return the current date/time on that machine. nmap-web can do a quick scan of your network and check whether your time synchronization (via ntp, I hope) is working correctly. In this example, everything looks okay with the exception of two machines that are 80 and 90 seconds off. These would be worth looking at further. nmap-web lets you set the allowable time skew with anything exceeding that highlighted in red. Time synchronization is a good thing, and with ntp it's easy. So, there's no excuse not to be time synced.
Figure 3 shows an example of scanning multiple ports. As mentioned earlier, administrators installing nmap-web can predefine a list of port(s) to scan. In this example, we are checking for a variety of ports that should not be enabled on most of the machines. Note that we only want to see those machines that are either down or are answering at these ports (i.e., don't show the uninteresting situation of a machine up and running with all those ports closed).
This output clearly shows that we have several machines that are running the finger daemon (port 79) and various POP/IMAP services (109, 110, and 143). Further investigation of this would be warranted to make sure we truly need those services running on those machines and have the software appropriately configured to make them secure.
Installing and Configuring nmap-web
Installing and configuring nmap-web is straightforward. From the INSTALL docs:
1. Get/compile/install nmap (>=2.52) from http://www.insecure.org/nmap/.
2. Create a directory under your Web site and put all the files there.
An example is /home/httpd/html/nmap-web/.
Modify nmap-web's index.html to reflect the cgi-bin path selected in #3 below.
Optionally, create log and counter directories (see nmap_web_local.pm).
3. Copy cgi-bin/check-for-web.pl into the appropriate cgi-bin directory.
An example is /home/httpd/cgi-bin/.
Modify the location of Perl and the INCLUDE directory, which should be the path in #2 above with include appended.
4. There are several include files that are used -- the idea is that you should NOT have to change any of these except the local ones; and those should be relatively constant between releases. Please do review these and make changes as appropriate from the comments!
5. You can use the sample misc/getnetgroup (see nmap_web_local.pm).
6. Point your browser to the directory listed above and rock-n-roll. It should be fairly self-explanatory. If you peruse the code, you'll see there is the ability to put a -ports manually into the host field. This is handy if you decide there is a new port you want to scan, and you don't want to have to change the code.
The nmap_web_local.pm allows you to configure which types of scans are allowed, optionally restrict which browser IPs are even allowed to run it (above and beyond any .htaccess Web server permissions you might set up), log all nmap-web runs, and other cool tricks.
How Does nmap-web Work in Real Life?
nmap-web has been very useful as a quick and easy-to-use check of which ports are open on various machines. While you could use nmap itself for this, nmap-web provides a Web interface, plus it tidies up the output a bit for certain functions that are useful when scanning large numbers of machines.
A couple of examples mentioned above were scanning for Web servers (and what version of software), checking time synchronization, and seeing if any unnecessary ports were open. Other useful things include:
Version scanning/checking is very useful to make sure you're running the latest Sendmail, sshd, ftpd, etc.
While scanning all 65,536 ports can take a few minutes, this can be done on similarly configured machines to see whether anything looks different (i.e., basically a Tripwire concept for network port scanning). Remember that a non-root user can listen on ports greater than 1023, which is a common approach used by the crackers to open a back door.
You can use the command line capability of nmap-web to generate periodic snapshots, and then do diffs/compares to see whether anything has changed.
For example, a recent security advisory warned about a remote exploit with older versions of qpopper. It was trivial to use nmap-web to identify which machines were running POP, and which ones had older software that needed to be updated. After this was done, nmap-web was used to confirm that no older versions were still running.
nmap-web has been downloaded hundreds of times by the Internet community and the email feedback has been positive and has also resulted in polishing of the code. It provides an interface to allow controlled, audited port scanning. I hope nmap-web will encourage more whitehats to use hacking tools, such as port scanners, to test their machines and networks before the blackhats find them.
Future nmap-web Work
nmap-web was designed as a tool to help admins easily discover which ports are open and what is running on them in order to take any appropriate action. There's a temptation to tweak nmap-web to provide a Web interface to everything that nmap can do, but there are already various TK/X-based toolkits that allow this. So, rather than incorporate all the scanning options available, I decided to just provide the most interesting ones that don't require root access.
One area where work can be done is to add more code to assess what versions of software are running for different ports. nmap-web currently has some code to do simple connections to the named port and look for what is expected there. More sophisticated approaches can be done and, in fact, there is discussion about adding this functionality into nmap itself. nmap-web could, of course, take advantage of that.
A tarball of nmap-web with code, documentation, and examples can be found at: http://www.komar.org/komar/alek/ -> Misc. Tech Stuff -> nmap-web or downloaded from Sys Admin's Web site: http://www.sysadminmag.com. I welcome any suggested enhancements, bug reports or fixes, and comments in general.
About the Author
Alek Komarnitsky (firstname.lastname@example.org) has spent the last 5+ years as Chief Technologist for a large IT consulting/outsourcing firm and helps manage a network of over 1,000 UNIX workstations supporting rocket scientists. Before that he was the Network/Systems Manager for two Boulder County software start-ups, and he spent his first 4 years out of college as an Air Force Officer doing weapons research. He has an Aero/Astro Engineering undergraduate degree from the University of Washington and an MBA from CU-Boulder.