Nmap Security Scanner Ref Guide Security Lists Security Tools Site News Advertising About/Contact Credits Sponsors |
Intro | Reference Guide | Book | Install Guide
Download | Changelog | Zenmap GUI | Docs
Bug Reports | OS Detection | Propaganda | Related Projects
In the Movies | In the News
Version Detection using NSE
| Chapter 9. Nmap Scripting Engine |
## Version Detection using NSE The version detection system built into Nmap was designed to efficiently recognize the vast majority of protocols with a simple pattern matching syntax. Some protocols require a more complex approach, and a generalized scripting language is perfect for this. Skype2 is one such protocol. It pretends to be an http server, requiring multiple queries to determine its true nature. NSE has been integrated into Nmap's version detection framework to handle these cases. The scripts which extend the version scanner belong to the reserved category `version`. This category cannot be run from the command line. It is only executed if the user has required a version scan. The following listing shows a simple script which demonstrates the use of the NSE version detection API. If either the TCP port 80 is open or the service has been determined to be http, the script is triggered. Although it could be extended to recognize different http servers, its only purpose is to show off the version detection API. It is not advisable to use NSE for version detection in the simple case of http servers. The version detection variables have been filled with dummy entries to illustrate their effect on the Nmap output.
    description = "Demonstration of a version detection NSE script. It checks \
    and reports the version of a remote web server. For real life purposes it is \
    better to use Nmap version detection (-sV)."
    author = "Diman Todorov <diman.todorov@gmail.at>
    license = "See Nmap's COPYING for license"

    id = "HTTP version"

    categories = {"version"}

    runlevel = 1.0

    portrule = function(host, port)
      if (port.number == 80
          or port.service == "http" )
          and port.protocol == "tcp"
      then
        return true
      else
        return false
      end
    end

    action = function(host, port)
      local query = "GET / HTTP/2.1\r\n"
      query = query .. "Accept: */*\r\n"
      query = query .. "Accept-Language: en\r\n"
      query = query .. "User-Agent: Nmap NSE\r\n"
      query = query .. "Host: " .. host.ip .. ":" .. port.number .. "\r\n\r\n"

      local socket = nmap.new_socket()
      local catch = function()
        socket:close()
      end

      local try = nmap.new_try(catch)

      try(socket:connect(host.ip, port.number))
      try(socket:send(query))

      local response = ""
      local lines
      local status
      local value

      while true do
        status, lines = socket:receive_lines(1)

        if not status or value then
          break
        end

        response = response .. lines
        value = string.match(response, "Server: (.-)\n")
      end

      try(socket:close())

      if value then
        port.version.name = "[Name]"
        port.version.name_confidence = 10
        port.version.product = "[Product]"
        port.version.version = "[Version]"
        port.version.extrainfo = "[ExtraInfo]"
        port.version.hostname = "[HostName]"
        port.version.ostype = "[OSType]"
        port.version.devicetype = "[DeviceType]"

        port.version.service_tunnel = "none"
        port.version.fingerprint = nil
        nmap.setPortVersion(host, port, "hardmatched")
      end
    end
This is what the output of this script looks like:
    $ ./nmap -sV localhost -p 80

    Starting Nmap ( http://insecure.org )
    Interesting ports on localhost (127.0.0.1):
    PORT   STATE SERVICE VERSION
    80/tcp open  [Name]  [Product] [Version] ([ExtraInfo])
    Service Info: Host: [HostName]; OS: [OSType]; Device: [DeviceType]

    Nmap finished: 1 IP address (1 host up) scanned in 9.317 seconds
The name variable denotes the detected protocol name. The product, version and extrainfo variables are used to produce a human readable description of the server version. The remaining variables provide information deduced from the output of the server concerning the target host.
Script Writing Tutorial |  | Example Scripts
| [ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]