Most security professionals know Nmap for port scanning, but the Nmap Scripting Engine (NSE) transforms it from a port scanner into a full-featured network auditing platform. With over 600 built-in scripts covering everything from vulnerability detection to service brute-forcing, NSE can dramatically extend what a basic scan reveals. This guide focuses on the scripts and techniques that matter most in real penetration testing engagements.
NSE Fundamentals
NSE scripts are written in Lua and live in /usr/share/nmap/scripts/ on most Linux systems. They execute against open ports or hosts and return structured output alongside normal scan results.
Scripts are organized into categories:
| Category | Purpose |
|---|
auth | Authentication bypass and default credentials |
broadcast | Discover hosts without scanning |
brute | Credential brute forcing |
default | Safe, general-purpose (run with -sC) |
discovery | Service and network enumeration |
exploit | Active exploitation (use with care) |
fuzzer | Input fuzzing |
intrusive | May crash or affect services |
malware | Detect malware backdoors |
safe | Low risk, no side effects |
version | Enhanced version detection |
vuln | Vulnerability detection |
Running Scripts
# Run default scripts (equivalent to -sC)
nmap -sV --script=default 192.168.1.1
# Run a specific script
nmap --script=http-title 192.168.1.1
# Run all scripts in a category
nmap --script=vuln 192.168.1.1
# Run multiple categories
nmap --script=auth,vuln 192.168.1.0/24
# Run a script with arguments
nmap --script=http-brute --script-args http-brute.path=/admin/ 192.168.1.1
The vuln Category
The vuln category contains scripts that check for specific known vulnerabilities. These are some of the most valuable for penetration testing.
EternalBlue (MS17-010)
nmap -p 445 --script=smb-vuln-ms17-010 192.168.1.0/24
This checks for the SMB vulnerability exploited by WannaCry and EternalBlue. Still present on unpatched systems years later. A positive result (VULNERABLE) means the host is susceptible to remote code execution without authentication.
Heartbleed
nmap -p 443 --script=ssl-heartbleed 192.168.1.1
Checks whether an HTTPS server leaks memory via the Heartbleed OpenSSL bug (CVE-2014-0160). Though old, it still appears on legacy systems.
SMB Signing Detection
nmap -p 445 --script=smb-security-mode 192.168.1.0/24
SMB without required signing enables relay attacks. This script reveals whether message signing is enabled, required, or disabled.
HTTP Slowloris
nmap -p 80 --script=http-slowloris-check 192.168.1.1
Checks if a web server is vulnerable to Slowloris DoS without actually launching the attack.
The auth Category
The auth category tests for authentication weaknesses — default credentials, anonymous access, and authentication bypasses.
Anonymous FTP
nmap -p 21 --script=ftp-anon 192.168.1.0/24
Lists directories accessible to anonymous FTP users. A common misconfiguration that exposes sensitive files.
Default Credentials
nmap --script=http-default-accounts -p 80,443,8080 192.168.1.0/24
Tries known default credentials against web login forms. Covers hundreds of devices including routers, IP cameras, and management interfaces.
nmap -p 22 --script=ssh-auth-methods --script-args ssh.user=root 192.168.1.1
Identifies which SSH authentication methods are accepted (password, publickey, keyboard-interactive).
Discovery Scripts
HTTP Enumeration
nmap -p 80,443 --script=http-enum 192.168.1.1
Probes for common web directories and files using a built-in wordlist. Finds /admin/, /backup/, /phpinfo.php, and hundreds of other targets.
DNS Zone Transfer
nmap --script=dns-zone-transfer --script-args dns-zone-transfer.domain=target.com -p 53 ns1.target.com
Attempts an AXFR DNS zone transfer. A successful transfer reveals all DNS records for the domain — a significant information disclosure.
Writing a Custom NSE Script
NSE scripts follow a standard structure. Here’s a minimal script that checks for a custom HTTP endpoint:
-- my-check.nse
-- Checks for an exposed /debug endpoint
description = [[
Checks if a web server exposes a /debug endpoint.
]]
categories = {"discovery", "safe"}
local http = require "http"
local shortport = require "shortport"
local stdnse = require "stdnse"
portrule = shortport.http
action = function(host, port)
local response = http.get(host, port, "/debug")
if response.status == 200 then
return stdnse.format_output(true, "DEBUG ENDPOINT EXPOSED at /debug")
end
return nil
end
Save to /usr/share/nmap/scripts/my-check.nse, then update the script database:
nmap --script-updatedb
nmap --script=my-check 192.168.1.1
Practical Scan Recipes
Full internal network audit:
nmap -sV -sC --script=vuln,auth,discovery \
-p 21,22,23,25,53,80,443,445,3306,3389,8080,8443 \
192.168.1.0/24 \
-oA internal_audit
Quick web server sweep:
nmap -p 80,443,8080,8443 \
--script=http-title,http-headers,http-methods,http-enum \
192.168.1.0/24 \
-oN web_survey.txt
SMB vulnerability check across subnet:
nmap -p 445 \
--script=smb-vuln-ms17-010,smb-vuln-ms08-067,smb-security-mode,smb-os-discovery \
192.168.1.0/24 \
-oA smb_audit
NSE scripts can slow scans considerably. Tune with:
# Aggressive timing (faster, more packets)
nmap -T4 --script=vuln 192.168.1.0/24
# Limit parallelism
nmap --min-parallelism 10 --max-parallelism 50
# Set script timeout
nmap --script-timeout 30s
nmap -oA output_basename # Normal + XML + grepable
nmap -oX output.xml # XML for importing into tools
nmap -oN output.txt # Human readable
Import XML into Metasploit:
msf6 > db_import /path/to/output.xml
NSE transforms Nmap from a reconnaissance tool into a lightweight vulnerability scanner. Master the built-in categories, and learn enough Lua to write targeted scripts for the specific services your engagement involves.