Exploring the Nmap scripting module

Posted date 20/02/2025
Author
INCIBE (INCIBE)
Binary code 0 and 1

One of the most significant innovations in Nmap is the Nmap Scripting Engine (NSE), a component that allows users to run scripts to perform much more complex and detailed tasks than a simple network scan. NSE extends its functionalities to include vulnerability audits, malware detection, and custom penetration testing. This tool, written in the Lua scripting  language, allows users to add additional functionality to their scans, automating much of the work needed to identify and address security threats.

 

Categories of scripts in Nmap

NSE scripts are grouped into fixed categories that reflect their purpose. Each category is assigned by the developers based on the script's approach:

  • Auth: focused on handling credentials and authentication, these scripts evaluate the security of services, such as FTP, SSH or HTTP, testing username and password combinations. They are especially useful in audits to verify the robustness of authentication policies.

  • Broadcast: Use broadcast queries to discover hosts and services on a local network without requiring specific IPs. They are effective in mass detection of devices and services in corporate environments.

  • Brute: They execute brute force attacks to test credentials using predefined lists. Their main function is to identify accounts with weak passwords, which is essential in penetration testing, although they require caution and authorization.

  • Befault: Considered safe and useful for most scans, they offer additional information about detected services without intrusive actions. They run automatically with Nmap  's -sC option.

  • Discovery: Used to gather additional information about the target, such as listing services, users, or shares, facilitating deeper recognition of the network.

  • Two: They perform tests to simulate denial-of-service attacks, exhausting resources, or exploiting vulnerabilities. They are useful for testing the robustness of the system against attacks but should be used with extreme caution.

  • Exploit: They take advantage of known vulnerabilities in systems or applications to verify if they can be exploited. They are used in penetration tests, always in controlled and permissioned environments, as they can compromise the security of the system.

  • External: They interact with databases and public services external to the target system, such as WHOIS queries or geolocation, to obtain additional information without directly affecting the target's services.

  • Fuzzer: Sends random or malformed data to services to detect flaws or vulnerabilities in their implementation. Although effective at detecting errors, their use can cause instability, so they should be executed with caution.

  • Intrusive: They perform aggressive actions that could affect the stability of the system or be detected as malicious by security systems. It is crucial to have authorization before using them, as they can disrupt services.

  • Malware: Designed to detect the presence of malware or behaviors associated with malicious software. These scripts help identify active infections or compromises in security audits.

  • SAFE: Considered non-intrusive and secure, they collect basic information without altering the system or generating alerts in security systems, making them ideal for initial scans.

  • Version: Improve the detection of service versions through specific queries, helping to accurately identify running software, which is key to finding vulnerabilities related to specific versions.

  • Vuln: check if the target's services are exposed to known and documented vulnerabilities, such as Heartbleed or Shellshock, being essential in security audits to detect risks.

 NSE script categories  are not exclusive: this means that a script can belong to multiple categories at the same time. Nmap developers can assign multiple tags to a script to indicate that it has multiple purposes. It is possible to get all scripts that belong to a category by using the help command. For example, to view all those in the Discovery category:

nmap --script-help "category:discovery"

 

Creating custom scripts  

 

To develop scripts, it is essential to know the basic structure and the libraries available to take advantage of the full potential of NSE. These elements organize the script and allow Nmap to run it efficiently.

The script begins with a description that explains its purpose and what it intends to achieve. This field is important for users to quickly understand the function of the script. Immediately after, the author field indicates who created the script, providing a clear reference to its origin. In addition, the license under which it is distributed is specified, which is generally the same license as Nmap, ensuring legal consistency.

As we have seen, each script is also classified into one or more categories. In addition, scripts import libraries that are essential for their operation using the required command, which allows you to use Nmap and Lua-specific dependencies, such as httpnmap, or shortport.

The execution rule is key to defining when the script is executed. Depending on the objective, it can be a  portrule, which specifies whether to run on a specific port, or on  hosts, to run based on the host's characteristics.

The main function of the script is defined in the action section. This is the most important part of the script, where the logic that performs the main actions is developed, such as sending an HTTP request, performing a scan, or analyzing the system response.

In some cases, scripts  can accept additional arguments that allow users to customize their behavior at execution time. These arguments are specified in the script and passed through the --script-args option  when Nmap is executed.

Below is an example of a  custom script to check if the HTTP TRACE method  is enabled on a web server, this is important from a security perspective because this method can be exploited to perform attacks such as Cross-Site Tracing (XST), which can compromise the privacy and security of users.

-- Description: Explains what the script does.

description = [[

  Check if the HTTP TRACE method is enabled on a web server. 

  The user can specify a custom path to test.

]]

 

-- Author: Name of the script creator.

author = "Your Name <youremail.email@example.com>"

 

-- License: Defines under which license the script is distributed.

license = "Same as Nmap--See https://nmap.org/book/man-legal.html"

 

-- Categories: Sorting the script into one or more categories.

categories = {"default", "discovery", "safe"}

 

-- Essential Libraries: Import the functions needed for the script.

local http = require "http"

local shortport = require "shortport"

 

-- Additional argument: Allows the user to specify the URL.

local url = nmap.registry.args["http-trace.url"] or "/"

 

-- Portrule: Defines when the script is executed, in this case on HTTP ports.

portrule = shortport.http

 

-- Main function: Script logic. Check if the TRACE method is enabled.

action = function(host, port)

  -- Send HTTP request to the specified URL or root if one is not given.

  local response = http.get(host, port, url)

 

  -- Check if the answer is valid.

  if response and response.status == 200 then

    -- Check if the "Allow" header includes TRACE.

    if response.header["Allow"] and response.header["Allow"]:find("TRACE") then

      return "HTTP TRACE is enabled in " .. url

    else

      return "HTTP TRACE not enabled in " .. url

    end

  else

    return "Could not get a response from the server for the URL: " .. url

  end

end 

 

To scan a “www.example.com” domain and check if the HTTP TRACE method is enabled in the /login path, the command would be:

nmap --script http-trace.nse --script-args http-trace.url="/login" -p 80,443 www.example.com

In order for Nmap to recognize your custom scripts, you need to place them in the Nmap scripts directory  . This directory varies depending on the operating system you use. For example, in Linux the default is /usr/share/nmap/scripts/.

In the following image you can visualize the workflow of a script.

Script Execution Flow

-Script Execution Flow –   

Best practices and security considerations

It is important to implement measures that ensure the security and efficiency of the script, especially when it comes to intrusive tasks, parameter control, and credential handling.

  • Intrusive scripts and parameter control: Scripts that can significantly affect the system, such as brute force attacks or DoS tests, should be classified as intrusive to warn users about their impact. It is also essential to limit the number of authentication attempts or adjust the time between requests to avoid system overload or script misuse. Allowing the user to control these parameters adds flexibility and security in their execution.

  • Use of environment variables or files for credentials:  instead of encoding credentials directly into the script, it is better to use environment variables or read credentials from an external file. This avoids exposing sensitive information to the source code and reduces the risk of leaks or unauthorized access. Lua allows you to access environment variables with os.getenv() or read files securely to retrieve the necessary information, without having to store it in the script.

  • Proper handling of errors and exceptions: Implementing proper handling of errors and exceptions is critical to avoid unexpected failures and ensure that the script works properly. Providing clear messages when something goes wrong also improves the user experience.

  • Resource cleanup and management: Ensure that all resources used by the script, such as network connections or temporary files, are properly released at the end of execution. This prevents performance and stability issues in the system. To ensure that resources are always freed, even if an error occurs during script execution, you can use a protection block with pcall (protected call). This ensures that cleanup operations, such as closing files or sockets, are carried out, even if an error occurs.

 

Conclusion

Thanks to NSE, it is possible to identify vulnerabilities more efficiently and strengthen the security of networks and systems. However, it is important to interpret the results of scripts with caution, as they can sometimes generate false positives. For this reason, it is advisable to complement the use of Nmap with other tools and perform manual analysis to obtain a complete view of the situation.

 

Moreover, it is crucial to use Nmap and NSE within legal and ethical limits. Scanning networks without proper consent can have serious legal repercussions. Therefore, it is always necessary to have authorization to carry out audits or penetration tests on networks and systems.