Building Custom NSE and Discovery Scripts

This is the third in a series of NetAlly Blogs related to Nmap and CyberScope®. For those not familiar with Nmap and Nmap Scripting Engine (NSE), the content presented could be relatively complex. Given this, we suggest you also attend the two NetAlly webinars where Blake will discuss the information on NSE presented here and then demonstrate the scripts running on CyberScope.

In the ever-changing landscape of cybersecurity, having powerful tools like the CyberScope at your disposal is crucial to safeguarding your networks. As we have seen in our previous blog posts, the CyberScope can run Nmap, a popular and versatile network scanning utility. Nmap becomes even more potent when coupled with NSE. By creating your custom NSE script, you can tailor Nmap to meet your specific security needs, automate tasks, and obtain valuable insights from your network scans. In this step-by-step tutorial, we’ll guide you through the process of developing your custom NSE script, empowering you to unlock the full potential of Nmap. The NSE script we will be building can be ran by anyone and doesn’t require access to any paid services. We encourage you to follow along from your computer and perform the steps in order.


  • Laptop or desktop capable of running Nmap.
  • Basic familiarity with Nmap usage and commands.
  • A working knowledge of the Lua programming language (though not mandatory). Here is a link to the official Lua Programming language.

Step 1: Define the Objective
Begin by identifying the goal of your custom NSE script. Do you want to detect vulnerabilities, gather specific information, or perform a specialized network discovery? Clarifying the objective will guide your script development and ensure you stay focused on creating a valuable tool. Your NSE script doesn’t need to be a jack-of-all-trades, build many scripts instead of one big one. For our example scripts, the objective is going to be to obtain additional WAN IP information during an AutoTest. We want to add the Autonomous System Number (ASN), ASN Organization, and Location information for the WAN IP. This information can be helpful in determining Internet routes being used as well as which geographically distributed cloud service your traffic would be sent when leveraging services like AWS, Netflix, Office 365, etc.

Clarifying the objective will guide your script development and ensure you stay focused on creating a valuable tool.

Step 2: Set Up the Environment
Ensure that Nmap is installed on your system. You can download the latest version from the Nmap official website. Additionally, choose a text editor or integrated development environment (IDE) that supports Lua scripting. Popular choices include VSCode, Sublime Text, or even a simple text editor like Notepad++.

Step 3: Study Existing NSE Scripts (Optional)
Before diving into your script, explore the vast collection of existing NSE scripts available in the Nmap script library. Analyzing these scripts will provide valuable insights into best practices, script structures, and the usage of Nmap APIs. Learning from others can save you time and help you avoid common pitfalls. A wide selection of NSE scripts is pre-installed with Nmap. You can find them in the C:\Program Files\Nmap\ directory on Windows or /usr/share/local/nmap and /usr/share/nmap/ on non-Windows based systems.

Step 4: Script Development
A. Define Script Arguments and Dependencies:

  • Identify and include NSE libraries or dependencies required for your script (if any).
  • Add a brief description of its purpose and usage.
  • Enter the author information, license usage details, and categories for script.
  • Declare any script arguments that allow users to customize the scan according to their needs. In our case we don’t have any arguments.
----- FORMAT WITH <CODE> -----
local http = require "http"
local json = require "json"
local oops = require "oops"
local stdnse = require "stdnse"
local table = require "table"

description = [[
Tries to identify information regarding the detected WAN IP of the network from which script is ran. 

This script relies on the <code></code> information and takes no parameters.

-- @usage
-- nmap --script ip-info-ipapi
-- @output
-- | IP:
-- | Network:
-- | ORG: ISP-#
-- |_Location: Minneapolis, Minnesota, US
author = "Blake Krone <"
license = "Same as Nmap--See"
categories = {"discovery","external","safe"}

---- END FORMAT -----

B. Writing the Script Body:

  • Initialize script variables and process the user-defined arguments (if applicable).
  • Define when the script components should be ran: prerule, hostrule(), portrule(), postrule()
  • Implement the logic for the scan, data retrieval, and reporting.
  • Utilize Nmap APIs such as nmap.scan(), nmap.get_port_state(), etc., to gather network information. In our case, we are performing a basic http.get() which is the same as when you go to a website in your browser.
  • Handle potential errors and exceptions gracefully.
---- CODE ----
prerule = function()
  return true

-- No limit on requests. A free registration for an API key is a prerequisite
local ipapi = function()
  local output = {} -- This is where we store the output from the script
  local response = http.get("", 443, "/json") -- Perform the request to the ipapi service
  local stat, data = oops.raise(
    "Unable to parse response", -- If we have an error, raise and report as such.
    json.parse(response.body)) -- Otherwise we parse the response body as JSON
  if not stat then
    return stat, data

  table.insert(output, ("IP: %s"):format(data.ip)) -- Add the IP information to the output table
  table.insert(output, ("Network: %s"):format( -- Add the Subnet / Network information to the output table
  table.insert(output, ("ASN: %s"):format(data.asn)) -- Add the ASN information to the output table
  table.insert(output, ("ORG: %s"):format( -- Add the ASN Organization information to the output table
  table.insert(output, ("Location: %s, %s, %s"):format(,data.region, -- Add the location information to the output table
  if(data.in_eu) then
    table.insert(output, ("EU Member State")) -- If the location is an EU Member State, add that information to the output table
  return true, output -- Return true as the script completed successfully with the output table data

action = function()
  return oops.output(ipapi()) -- Run the ipapi lookup function, return output or error
---- END ----

C. Testing and Debugging:

  • Test your script on different target systems to ensure its functionality and accuracy.
  • Use print statements or debug output to troubleshoot any issues that arise.
  • Consider running your script with the “-d” option to enable NSE debugging.
Uploading your script to CyberScope to test is easy. First upload to Link-Live, then push the scripts to the organizations CyberScope units.
Uploading your script to CyberScope to test is easy. First upload to Link-Live, then push the scripts to the organization’s CyberScope units.

Step 5: Optimize Efficiency
As your script evolves, it’s essential to optimize its performance to handle large-scale scans effectively. Consider parallelization and threading techniques to improve speed and resource usage. You can also implement caching mechanisms to reduce redundant scans and enhance overall efficiency.

Step 6: Add Documentation and Metadata
Documentation is crucial for users who may want to utilize your script. Include comments within your script to explain its purpose, functions, and any notable implementation details. Additionally, define metadata such as the author’s name, script version, license, and any dependencies required.

Step 7: Security and Ethical Considerations
Responsible scanning is a core principle in cybersecurity. Before deploying your script, ensure it adheres to ethical guidelines and legal considerations. Always seek proper authorization before scanning or probing any network.

Before deploying your script, ensure it adheres to ethical guidelines and legal considerations.

Step 8: Sharing and Deployment
Once your script is complete and tested, consider sharing it with the Nmap community. You can contribute your script to the Nmap script library or share it on platforms like GitHub. Providing clear instructions for users to install and use your script will make it more accessible to others.

Congratulations! You’ve successfully crafted your custom Nmap Scripting Engine script, unlocking new possibilities for your Nmap scans. Embrace the power of NSE to adapt Nmap to your unique security requirements and contribute to the thriving Nmap community by sharing your creations.

Remember to approach scanning ethically and responsibly, ensuring the safety and integrity of the networks you interact with. With your new script in hand, you’re now better equipped to bolster your network defenses and stay ahead of potential threats in the ever-evolving cybersecurity landscape. For those interested or more advanced users, we recommend looking at the official help guide found here for additional information. Happy scripting!

Author Bio –
Mobility Consultant

Blake Krone is an independent Mobility Consultant and developer. His primary focus is providing solutions for the next generation of devices and business use cases for many Fortune 500 companies and startups. He has developed training materials and presentations through his experience deploying some of the largest single-site networks, sharing the knowledge and insights gained. When he isn’t designing and deploying networks, he builds data analysis tools and tests client devices and tools.

More Posts