by Paul Asadoorian
Back when I worked for a university I need to write a fast banner grabber. This had to grab banners either on a specific port, or a set of ports and run against two class B networks. Speed was key, the faster the better as my incident response process relied on saving time. Why? I was trying to look for one of two things:
* Compromised hosts listening on a particular port using a backdoor or FTP server that had a known banner
* Vulnerable software that had a specific banner which was being used by attackers to compromise systems
bootoutput.jpgI wrote a quick banner grabber in C because Nmap was not quite right (at the time). Nmap was awesome at finding ports, and awesome at sending a bunch of packets at a port to determine the version and type of service running. With two class B networks, I didn’t have time to wait for Nmap to send a whole bunch of packets to each port. I want to complete the handshake, send one packet with a “nr”, and grab what comes back. Turns out, Nmap Scripting Engine solved my problem! Now with a little bit of Lua-Foo I can do what I want with Nmap, and take advantage of all of its powerful features (such as host discovery). I took my banner grabbing problem and just a few lines of code later, I had ported this functionality to Nmap:

id="Banner"
description="connects to each open port and send CRLF to grab banner"
author = "Paul Asadoorian ([email protected])"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"discovery"}

require "comm" require "shortport"
portrule = function(host, port) return (port.number and port.protocol == "tcp") end
action = function(host, port) local try = nmap.new_try()
return try(comm.exchange(host, port, "rn", {lines=100, proto=port.protocol, timeout=500}))
end

The output looks as follows:

# Nmap 4.76 scan initiated Wed Oct  8 23:15:50 2008 as: nmap -sV -oA bannertest%T%D -T4 -sS --script=bannergrab.nse -p1-65535 192.168.1.230
Interesting ports on 192.168.1.230:
Not shown: 65531 closed ports
PORT     STATE SERVICE    VERSION
23/tcp   open  telnet     HP JetDirect printer telnetd
|  Banner: xFFxFCx01
|  Please type [Return] two times, to initialize telnet configuration
|  For HELP type "?"
|_ >
515/tcp  open  printer?
9099/tcp open  unknown?
9100/tcp open  jetdirect?
MAC Address: 00:60:B0:BD:68:B0 (Hewlett-packard CO.)
Service Info: Device: printer

Service detection performed. Please report any incorrect results at http://nmap.org/submit/ . # Nmap done at Wed Oct 8 23:27:14 2008 -- 1 IP address (1 host up) scanned in 684.29 seconds

I ran both my script and -sV so you can see an example of the difference.
– Paul Asadoorian, Security Weekly Enterprises
[Editor’s note: Awesome work Paul! A great compliment to the official release of Fyodor’s Nmap book. Hail the power of NSE!]