Lua in Nmap: A Comprehensive Guide to Scripting and Network Security
óscar Boullosa Dapena
Aeroespacial Engineering | Network Engineering | Cybersecurity | Artificial Intelligence | Blockchain | Quantum Computing | Astrophysics
Introduction
In today's world of network security and management, having the right tools and knowledge is essential. While there are numerous simpler tools available for tasks like geolocating an IP address, understanding how to create custom scripts for advanced network scanning tools like Nmap provides deep insights into network security and programming. This article aims to explore the Lua programming language, its integration with Nmap, and a detailed explanation of a custom Lua script designed to geolocate an IP address. This exploration is conducted purely for educational and research purposes.
Understanding Lua
Lua is a lightweight, high-level programming language known for its simplicity and efficiency. Created in 1993 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes, Lua is designed to be embedded into other applications, making it a popular choice for scripting in various software environments, including game development, embedded systems, and network scanning tools like Nmap.
Key Features of Lua
Lua's Syntax and Semantics
Lua's syntax is straightforward and easy to learn, especially for those familiar with other programming languages. Here are some fundamental aspects of Lua's syntax and semantics:
local message = "Hello, World!"
local number = 42
local isActive = true
local person = {
name = "John Doe",
age = 30,
greet = function(self)
print("Hello, " .. self.name)
end
}
person:greet()
local function add(a, b)
return a + b
end
print(add(2, 3)) -- Output: 5
Using Lua in Nmap
Nmap, or Network Mapper, is an open-source tool used for network discovery and security auditing. It can scan large networks, identify open ports, services, operating systems, and provide comprehensive network information. Lua enhances Nmap's functionality through the Nmap Scripting Engine (NSE), allowing users to write custom scripts for various network tasks.
Nmap Scripting Engine (NSE)
The NSE uses Lua as its scripting language due to its lightweight nature and ease of embedding. NSE scripts extend Nmap's capabilities, enabling it to perform tasks such as vulnerability detection, network discovery, and more.
Writing a Lua Script for Nmap
In this section, we'll walk through the creation of a Lua script that geolocates an IP address by querying the ipinfo.io API. The script uses Nmap's socket API to make an HTTP request and parse the JSON response.
Script Description
The script begins with metadata that provides information about its purpose, author, license, and categories.
description = [[
This script retrieves the geographical location of a network device based on its IP address using sockets to perform the HTTP request.
]]
author = "Your Name <[email protected]>"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"external", "discovery"}
Importing Necessary Libraries
We import the necessary libraries: nmap for socket operations, stdnse for utility functions, and json for parsing JSON responses.
领英推荐
local nmap = require "nmap"
local stdnse = require "stdnse"
local json = require "json"
Defining the Host Rule
The hostrule function determines whether the script should run against a specific host. In this case, it always returns true, meaning the script will run against all hosts.
hostrule = function(host)
return true
end
The Geolocation Function
The core of the script is the get_geolocation function, which connects to the ipinfo.io API, sends an HTTP request, and parses the JSON response.
local function get_geolocation(ip)
local api_url = "/json"
local host = "ipinfo.io"
local port = 80
stdnse.print_debug(1, "Connecting to %s:%d", host, port)
local sock = nmap.new_socket()
local status, err = sock:connect(host, port)
if not status then
stdnse.print_debug(1, "Connection failed: %s", err)
return nil, "Connection failed: " .. err
end
local request = "GET /" .. ip .. api_url .. " HTTP/1.1\r\n" ..
"Host: " .. host .. "\r\n" ..
"Connection: close\r\n\r\n"
stdnse.print_debug(1, "Request: %s", request)
sock:send(request)
local response = ""
while true do
local status, line = sock:receive_lines(1)
if not status then break end
response = response .. line .. "\n"
end
sock:close()
local body = response:match("\r\n\r\n(.*)")
stdnse.print_debug(1, "Response body: %s", body)
if not body then
return nil, "No body in HTTP response"
end
local result, json_err = json.parse(body)
if not result then
stdnse.print_debug(1, "JSON parse error: %s", json_err)
return nil, "Error parsing JSON response: " .. json_err
end
return result
end
This function performs the following steps:
The Main Action Function
The action function is the entry point of the script. It calls the get_geolocation function and formats the output.
action = function(host)
local ip = host.ip
stdnse.print_debug(1, "Host IP: %s", ip)
local result, err = get_geolocation(ip)
if not result then
return "Error: " .. err
end
local output = {}
table.insert(output, string.format("IP: %s", ip))
table.insert(output, string.format("Country: %s", result.country or "N/A"))
table.insert(output, string.format("Region: %s", result.region or "N/A"))
table.insert(output, string.format("City: %s", result.city or "N/A"))
table.insert(output, string.format("Organization: %s", result.org or "N/A"))
table.insert(output, string.format("Location: %s", result.loc or "N/A"))
return stdnse.format_output(true, table.concat(output, "\n"))
end
Running the Script and Analyzing the Results
To execute the script, use the following Nmap command:
sudo nmap --script geolocate_ip_socket.nse x.x.x.x -d
The script performs the following steps:
Sample Output
Here's a sample output from running the script:
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-06-08 04:08 EDT
PORTS: Using ports open on 0% or more average hosts (TCP:1000, UDP:0, SCTP:0)
---------------
NSE: Using Lua 5.4.
NSE: Loaded 1 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 04:08
Completed NSE at 04:08, 0.00s elapsed
Initiating Ping Scan at 04:08
Scanning x.x.x.x [4 ports]
Completed Ping Scan at 04:08, 0.02s elapsed (1 total hosts)
Overall sending rates: 249.24 packets / s, 9471.00 bytes / s.
Initiating Parallel DNS resolution of 1 host. at 04:08
Completed Parallel DNS resolution of 1 host. at 04:08, 0.03s elapsed
Initiating SYN Stealth Scan at 04:08
Scanning x.x.x.x [1000 ports]
Discovered open port 21/tcp on x.x.x.x
Discovered open port 1723/tcp on x.x.x.x
Discovered open port 554/tcp on x.x.x.x
Completed SYN Stealth Scan at 04:08, 5.21s elapsed (1000 total ports)
Overall sending rates: 383.62 packets / s, 16876.96 bytes / s.
NSE: Script scanning x.x.x.x.
Initiating NSE at 04:08
NSE: Starting geolocate_ip_socket against x.x.x.x.
NSE: Host IP: x.x.x.x
NSE: Connecting to ipinfo.io:80
NSE: Request: GET /x.x.x.x/json HTTP/1.1
Host: ipinfo.io
Connection: close
NSE: Response body: {
"ip": "x.x.x.x",
"city": "***",
"region": "***",
"country": "**",
"loc": "***,***",
"org": "***",
"postal": "***",
"timezone": "***",
"readme": "***"
}
Completed NSE at 04:08, 19.87s elapsed
Nmap scan report for x.x.x.x
Host is up, received reset ttl 255 (0.016s latency).
Scanned at 2024-06-08 04:08:24 EDT for 25s
Not shown: 997 filtered tcp ports (no-response)
PORT STATE SERVICE REASON
21/tcp open ftp syn-ack ttl 255
554/tcp open rtsp syn-ack ttl 255
1723/tcp open pptp syn-ack ttl 255
Final times for host: srtt: 15775 rttvar: 24404 to: 113391
Nmap done: 1 IP address (1 host up) scanned in 25.30 seconds
Raw packets sent: 2004 (88.140KB) | Rcvd: 7 (292B)
Explanation of the Output
Conclusion
Lua's integration with Nmap through the NSE provides a powerful platform for customizing and extending network scanning capabilities. By understanding Lua's core principles and leveraging its features in Nmap, we can create sophisticated scripts for a variety of network security tasks. The geolocation script example demonstrates how to utilize Lua and Nmap together to achieve specific goals, while also highlighting the importance of robust error handling and validation. As you continue to explore Lua and Nmap, you'll discover even more possibilities for enhancing network security and management through scripting.