Loading courses...
Please wait while we prepare your learning journey.
Please wait while we prepare your learning journey.
Duration: 2 hours (Estimated)
Welcome to the eighth episode of our comprehensive Nmap course! In this module, we'll explore the Nmap Scripting Engine (NSE) - the powerful framework that transforms Nmap from a port scanner into a comprehensive network investigation platform.
A detective is only as good as their tools. But what if you could customize those tools for any situation, creating exactly what you need for each unique case? That's the power of the Nmap Scripting Engine. It allows you to extend Nmap's capabilities far beyond basic scanning, enabling automated vulnerability detection, service enumeration, and custom reconnaissance.
By the end of this module, you'll be able to use pre-built scripts, select the right scripts for different scenarios, and even write your own custom scripts to automate complex tasks and extract exactly the information you need from target systems.
The Nmap Scripting Engine is a powerful framework that allows Nmap to be extended with custom functionality written in the Lua programming language. It was introduced in 2007 and has since become one of Nmap's most valuable features.
This extensibility makes Nmap far more than just a port scanner—it becomes a comprehensive network investigation platform that can be customized for specific tasks and environments.
NSE scripts are organized into categories based on their purpose and behavior:
These scripts won't affect the target and are focused on information gathering only. Ideal for routine reconnaissance.
nmap --script banner 192.168.1.1These scripts may affect the target through active probing. Use with caution, especially in production environments.
nmap --script brute 192.168.1.1These scripts check for specific vulnerabilities. Essential for security assessments.
nmap --script ssl-heartbleed 192.168.1.1These scripts attempt to exploit vulnerabilities. Only use in authorized penetration tests.
nmap --script smb-vuln-ms17-010 192.168.1.1These scripts handle authentication credentials, identifying weak or default passwords.
nmap --script http-default-accounts 192.168.1.1These scripts discover network information, helping map networks and identify host relationships.
nmap --script hostmap-* 192.168.1.1These scripts extend service and version detection, providing more detailed information.
nmap -sV --script=version 192.168.1.1Understanding these categories helps select appropriate scripts for different scenarios and security requirements.
NSE scripts run at specific phases of the Nmap scanning process:
Run before any scanning begins. Can generate or modify targets.
nmap --script targets-xml -iL targets.xmlRun after host discovery, for each alive host. Perform host-specific actions.
nmap --script os-detection 192.168.1.1Run after port scanning, for specific open ports. Target specific services.
nmap --script http-enum 192.168.1.1 -p 80Run after all scanning is complete. Analyze and report on aggregate results.
nmap --script summary 192.168.1.0/24This phased execution allows scripts to generate targets, perform host-specific actions, run against relevant services, and analyze results. Understanding these phases helps predict script behavior and optimize scanning workflows.
Let's start with basic script usage:
nmap --script banner 192.168.1.1This runs the banner script to grab service banners from all open ports.
Starting Nmap 7.94 ( https://nmap.org ) at 2025-04-14 20:00 EDT Nmap scan report for 192.168.1.1 Host is up (0.0023s latency). Not shown: 995 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh | banner: SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.5 53/tcp open domain 80/tcp open http | banner: HTTP/1.1 200 OK Date: Mon, 14 Apr 2025 20:00:15 GMT |_ Server: Apache/2.4.41 (Ubuntu) Content-Type: text/html 443/tcp open https 8443/tcp open https-alt Nmap done: 1 IP address (1 host up) scanned in 1.31 seconds
nmap --script=http-title,http-headers 192.168.1.1 -p 80This runs both http-title and http-headers scripts against port 80.
Starting Nmap 7.94 ( https://nmap.org ) at 2025-04-14 20:05 EDT Nmap scan report for 192.168.1.1 Host is up (0.0023s latency). PORT STATE SERVICE 80/tcp open http | http-headers: | Date: Mon, 14 Apr 2025 20:05:15 GMT | Server: Apache/2.4.41 (Ubuntu) | Content-Type: text/html; charset=UTF-8 | |_ (Request type: GET) |_http-title: Example Domain Nmap done: 1 IP address (1 host up) scanned in 0.45 seconds
You can run entire categories of scripts:
# Run all safe scripts
nmap --script safe 192.168.1.1
# Run all HTTP scripts
nmap --script http-* 192.168.1.1 -p 80
# Run all vulnerability detection scripts
nmap --script vuln 192.168.1.1You can use wildcards to select scripts:
# All scripts starting with "ssl-"
nmap --script "ssl-*" 192.168.1.1 -p 443
# All scripts with "enum" in the name
nmap --script "*enum*" 192.168.1.1Scripts work well with other Nmap options:
# Comprehensive scan with scripts
nmap -sV -O --script default 192.168.1.1
# Target specific ports with scripts
nmap -p 80,443 --script http-* 192.168.1.1Many scripts accept arguments to customize their behavior:
nmap --script http-brute --script-args userdb=users.txt,passdb=passwords.txt 192.168.1.1This passes custom username and password files to the http-brute script.
nmap --script http-enum --script-args http-enum.category="default,safe" 192.168.1.1This specifies which categories of paths to check with http-enum.
# Global argument (applies to all scripts)
nmap --script "http-*" --script-args useragent="Mozilla/5.0" 192.168.1.1
# Script-specific argument
nmap --script http-enum --script-args http-enum.maxpagecount=500 192.168.1.1To discover what arguments a script accepts:
nmap --script-help http-enumhttp-enum Categories: discovery intrusive https://nmap.org/nsedoc/scripts/http-enum.html Enumerates directories used by popular web applications and servers. This parses a fingerprint file that's similar in format to the Nikto Web application scanner. This script, however, takes it one step further by building in advanced pattern matching as well as having the ability to identify specific versions of Web applications. Script Arguments http-enum.basepath Base path to prepend to all requests. Default: / http-enum.displayall Display all status codes, not just 200 OK and 401 Authentication Required http-enum.fingerprintfile Specify a different file containing fingerprint data http-enum.category Set the category of fingerprints to use (default: safe,intrusive) ...
Let's explore some of the most useful NSE scripts for different tasks:
# HTTP server information nmap --script http-enum,http-headers,http-methods 192.168.1.1 -p 80 # SMB enumeration nmap --script smb-enum-shares,smb-enum-users 192.168.1.1 -p 445 # SSH information nmap --script ssh2-enum-algos 192.168.1.1 -p 22 # Database enumeration nmap --script mysql-info,mysql-databases 192.168.1.1 -p 3306
# General vulnerability scan nmap --script vuln 192.168.1.1 # Web application vulnerabilities nmap --script http-vuln* 192.168.1.1 -p 80,443 # SSL/TLS vulnerabilities nmap --script ssl-* 192.168.1.1 -p 443 # SMB vulnerabilities nmap --script smb-vuln* 192.168.1.1 -p 445
# Default credential checking nmap --script http-default-accounts 192.168.1.1 -p 80 # Brute force SSH nmap --script ssh-brute --script-args userdb=users.txt,passdb=passwords.txt 192.168.1.1 -p 22 # Brute force HTTP forms nmap --script http-form-brute --script-args http-form-brute.path=/login.php 192.168.1.1 -p 80
# DNS information nmap --script dns-* 192.168.1.1 -p 53 # WHOIS information nmap --script whois-* philocyber.com # SSL certificate information nmap --script ssl-cert 192.168.1.1 -p 443
One of the most powerful features of NSE is the ability to create your own scripts:
description = [[
This is a simple example script that prints "Hello, World!" for each open port.
]]
-- The rule that determines when this script should run
portrule = function(host, port)
return port.state == "open"
end
-- The action that is performed when the rule returns true
action = function(host, port)
return "Hello, World! Port " .. port.number .. " is open."
endSave this as `hello-world.nse` in the Nmap scripts directory (usually `/usr/share/nmap/scripts/` or similar).
# Run the script
nmap --script hello-world 192.168.1.1NSE provides libraries for common tasks:
description = [[
Example script that uses the HTTP library to fetch a web page title.
]]
-- Load the HTTP library
local http = require "http"
local shortport = require "shortport"
-- Run against HTTP ports
portrule = shortport.http
-- The action
action = function(host, port)
-- Make an HTTP request
local response = http.get(host, port, "/")
-- Extract the title
local title = response.body:match("<title>(.-)</title>")
if title then
return "Page title: " .. title
else
return "No title found"
end
endExplore different script categories:
# List all available scripts ls /usr/share/nmap/scripts/ # Find scripts related to HTTP ls /usr/share/nmap/scripts/http* # Get help for a specific script nmap --script-help http-enum
Try running different script categories against a target:
# Safe scripts nmap --script safe 192.168.1.1 # Discovery scripts nmap --script discovery 192.168.1.1 # Default scripts (same as -sC) nmap --script default 192.168.1.1
Use NSE to gather detailed information about services:
# Web server enumeration nmap --script "http-enum,http-headers,http-methods,http-title" 192.168.1.1 -p 80,443 # Database enumeration nmap --script "mysql-*" 192.168.1.1 -p 3306
Compare results with basic scanning:
nmap -sV 192.168.1.1 -p 80,443,3306 -oN basic.txt nmap -sV --script "http-*,mysql-*" 192.168.1.1 -p 80,443,3306 -oN with_scripts.txt diff basic.txt with_scripts.txt
Create a table documenting what additional information the scripts provided.
Use NSE for basic vulnerability scanning:
# General vulnerability scan nmap --script vuln 192.168.1.1 -oN vuln_scan.txt # Targeted vulnerability scan nmap --script "ssl-heartbleed,ssl-poodle,http-shellshock" 192.168.1.1 -p 80,443 -oN targeted_vuln_scan.txt
Analyze the results:
Create a simple custom script:
description = [[
Prints a custom message based on the port number.
]]
portrule = function(host, port)
return port.state == "open"
end
action = function(host, port)
local messages = {
[22] = "SSH server found!",
[80] = "Web server found!",
[443] = "Secure web server found!",
[3306] = "MySQL database found!"
}
local message = messages[port.number]
if message then
return message
else
return "Port " .. port.number .. " is open."
end
endnmap --script port-message.nse 192.168.1.1Scripts fail to run or produce errors.
Solution:
# Check if script exists ls /usr/share/nmap/scripts/missing-script.nse # Update script database sudo nmap --script-updatedb # Run with debugging nmap -d --script http-enum 192.168.1.1
Script execution is too slow.
Solution:
# Limit to specific ports nmap --script http-enum -p 80,8080,8000 192.168.1.1 # Limit script timeout nmap --script http-enum --script-timeout 30s 192.168.1.1 # Run scripts against only relevant services nmap -sV --version-intensity 2 --script "http-*" 192.168.1.1
Scripts report vulnerabilities incorrectly.
Solution:
# Increase script verbosity nmap -v --script vuln 192.168.1.1 # Manually verify findings (e.g., Heartbleed) openssl s_client -connect 192.168.1.1:443 -tlsextdebug
Scripts require external dependencies.
Solution:
# For Debian/Ubuntu (Lua libraries) sudo apt install lua-ldap lua-json lua-socket # For scripts requiring brute force capabilities # (Often included in nmap package, check installation)
A security team used NSE to assess web applications:
nmap -sV --script "http-..." 10.0.0.0/24 ...nmap --script "http-vuln*" ... 10.0.0.5 ...nmap --script http-default-accounts 10.0.0.5 ...Identified: Outdated CMS, default credentials, SQL injection.
During a security audit, NSE scripts were used to:
nmap --script "ssl-enum-ciphers" ...nmap --script "smb-vuln*,rdp-vuln*,..." ...nmap --script "ftp-anon,smtp-enum-users,..." ...Revealed: Weak SSL/TLS, unpatched systems, information leaks.
In the next episode, we'll explore:
The primary resource for understanding NSE.
Browse all available official NSE scripts.
Detailed documentation for NSE libraries.
Learn the Lua language used in NSE scripts.
Tutorial on creating your own NSE scripts.
Note: Use this video as a visual guide to complement the written material.
1. In the context of the Nmap Scripting Engine (NSE), what programming language is primarily used to write scripts?
2. If you want to run NSE scripts that are designed to gather information about a target without actively trying to exploit vulnerabilities or cause harm, which category of scripts should you primarily focus on?
3. At which phase of the Nmap scanning process do "portrule" NSE scripts typically execute?
4. What is the purpose of using the `--script-args` option when executing NSE scripts with Nmap?
5. In the basic structure of a custom NSE script, which function is responsible for defining the condition under which the script's action will be executed (e.g., checking if a port is open)?