Basics of Lua Programming for Nmap NSE

Learn the basics of Lua programming as it applies to writing Nmap NSE scripts.

Introduction

Nmap (Network Mapper) is a powerful open-source tool widely used for network discovery and security auditing. One of its most powerful features is the Nmap Scripting Engine (NSE), which allows users to write custom scripts for advanced network scanning and security assessments. These scripts are written in Lua, a lightweight and efficient scripting language known for its simplicity and flexibility.

This article will cover the basics of Lua programming as it applies to writing Nmap NSE scripts. By the end, you will have a foundational understanding of Lua and be able to create simple NSE scripts to extend Nmap’s capabilities.

Why Lua for NSE?

Lua is chosen for NSE scripting because:

  • Lightweight: Lua has a small footprint and is highly efficient.
  • Easy to learn: The syntax is simple and intuitive.
  • Powerful: It offers excellent extensibility and flexibility.
  • Embedded-friendly: Lua integrates well into larger applications like Nmap.

Lua Basics for Nmap NSE

Before diving into NSE scripting, let’s go over some fundamental Lua concepts.

1. Variables and Data Types

Lua has a few basic data types:

  • nil (represents absence of a value)
  • boolean (true or false)
  • number (all numbers are floating-point by default)
  • string (text enclosed in quotes)
  • table (associative arrays, similar to dictionaries in Python)

Example:

local a = nil
local b = true
local c = 10
local d = "Hello, Lua!"

2. Control Structures

Lua supports standard control structures like if-else statements and loops.

If-Else Example

local x = 10
if x > 5 then
    print("x is greater than 5")
else
    print("x is 5 or less")
end

Loops

While loop:

local i = 1
while i <= 5 do
    print(i)
    i = i + 1
end

For loop:

for i = 1, 5 do
    print(i)
end

3. Functions

Functions help modularize code and improve readability.

function greet(name)
    return "Hello, " .. name
end
print(greet("Nmap"))

4. Tables (Lua’s Only Data Structure)

Tables are versatile and can act as arrays, dictionaries, or objects.

local person = {name = "John", age = 30}
print(person.name) -- Output: John

Writing NSE Scripts in Lua

NSE scripts follow a specific structure and are written in Lua. Let’s break down the key components.

1. NSE Script Structure

An NSE script consists of:

  • Description metadata
  • Categories
  • The action function

Example structure:

-- Script Metadata
--
-- @usage nmap --script myscript.nse -p 80 <target>
-- @output Example output of the script
--
-- @category discovery

-- Load required NSE libraries
local nmap = require "nmap"
local socket = require "socket"

-- Define the script
portrule = function(host, port)
    return port.number == 80 and port.state == "open"
end

action = function(host, port)
    return "Port 80 is open!"
end

2. Using NSE Libraries

Nmap provides built-in NSE libraries to interact with networks and process data. Commonly used ones include:

  • nmap (access scanning functions)
  • socket (network communication)
  • http (HTTP requests)
  • string (string manipulations)
  • stdnse (utility functions for NSE scripts)

Example: Using HTTP Library

local http = require "http"
local url = "http://example.com"
local response = http.get(url)
if response.status == 200 then
    print("Website is up!")
end

3. Writing an NSE Script to Fetch HTTP Headers

Now, let’s write a simple NSE script to retrieve HTTP headers from a target web server.

local http = require "http"
local nmap = require "nmap"
local stdnse = require "stdnse"

portrule = function(host, port)
    return port.number == 80 and port.protocol == "tcp" and port.state == "open"
end

action = function(host, port)
    local response = http.get(host, port, "/")
    if response == nil then
        return "No response received"
    end
    return stdnse.format_output(true, response.rawheader)
end

4. Running Your NSE Script

Save your script as http-headers.nse and execute it with:

nmap --script=http-headers.nse -p 80 <target>

Debugging NSE Scripts

To debug an NSE script, use:

nmap --script=http-headers.nse --script-trace -p 80 <target>
  • --script-trace provides detailed debugging information.
  • Use stdnse.debug in the script for custom debugging:
stdnse.debug(1, "Debugging message here")

Conclusion

This article covered the basics of Lua programming and how to apply it to Nmap NSE scripting. You learned about Lua syntax, control structures, tables, and functions, as well as how to create an NSE script to interact with a web server. With these fundamentals, you can explore writing more advanced scripts to extend Nmap’s functionality.

Next Steps

  • Experiment with different NSE libraries.
  • Modify existing NSE scripts to understand their functionality.
  • Create your own scripts for specific scanning needs.

By mastering Lua and NSE, you can customize Nmap to perform powerful security assessments tailored to your requirements.