SECURITY RESEARCH, TOOLS |

Giving an LLM command line access to Nmap

Working with Nmap on a daily basis, I’ve often wondered what it might look like to give a Large Language Model (LLM) direct access to the Nmap command line. Would it be useful or just a complicated way to run scripts?

This week, Simon Willison released an update to his excellent command-line tool llm that made it easy to try this out. With support for structured tool use, I decided to test an Nmap integration and see what a SOTA LLM could do when allowed to control one of our favourite security scanners.

Using llm tool use with nmap

Getting Started

Gathering the llm documentation, I fed it and a short description into one of the state of the art code models. It wasn’t long before I had a working prototype that could call out to Nmap, run specific scripts, and report the results.

llm-tools-nmap.py

github.com/peter-hackertarget

Warning: As with any LLM usage, be cautious. Unexpected results or command execution errors can and will happen. When an LLM has shell access, risks multiply. I only tested this in isolated environments - do not blindly let an AI loose on your prod systems.

Why Not Just Script It?

This was the question I kept coming back to. Why use an LLM at all, when Bash and Python can do a good job of automating and processing Nmap scans?

For experienced users who already know their way around Nmap and its options, an LLM probably adds very little. You’re not going to type scan webservers into a chatbot when you already know to run nmap -sV -p 80,443 10.0.0.0/24.

But if you scale things up - what if the llm had access to 10 or 20 tools (local and API's), along with the context to choose the right one. Things get more interesting. Instead of working out command line arguments you can focus on analysing the findings. The LLM figures out the correct command line, selects relevant tools / API's, and parses the results into something readable.

Potential Advantages

  • Command selection: The LLM chooses appropriate flags for Nmap based on your intent.
  • Script usage: It can automatically apply relevant NSE scripts without you needing to know them all.
  • Result analysis: The LLM can digest long scan output and return only the key information you need.

A Real Example

Here’s what it looks like in action.

asmith@thematrix:~$ llm --functions llm-tools-nmap.py "what services are running on 192.168.8.3. 
gather as much information as you can and identify any security issues 
or items of interest to a security analyst"

Here is the full response from Gemini Flash.

Okay, I can help with that. I will perform a comprehensive Nmap scan on 192.168.8.3 using the `-A` option, which includes OS detection, version detection, script scanning (default scripts), and traceroute. This should provide a good overview of running services and potentially highlight security-relevant information.

This scan might take a few minutes depending on the network conditions and the target's response.

Okay, I have completed the comprehensive Nmap scan on 192.168.8.3. Here is a summary of the findings:

**Open Ports and Services:**

* **Port 22/tcp:** Running **OpenSSH 8.9p1 Ubuntu 3ubuntu0.13** (protocol 2.0). SSH host keys (ECDSA and ED25519) were also identified.
* **Port 80/tcp:** Running an **http service** identified as a **Golang net/http server**.
* **Port 443/tcp:** Running an **ssl/http service** also identified as a **Golang net/http server**.
* **Port 8080/tcp:** Running an **http service** identified as **CherryPy httpd 18.9.0**.
* **Port 8093/tcp:** Running an **http service** identified as **nginx**, with the http title "noVNC".

**Operating System:**

* The scan detected the operating system as **Linux**.

**Items of Interest to a Security Analyst:**

1. **noVNC Service on Port 8093:** The presence of `noVNC` indicates a web-based VNC client providing remote access. This is a significant security concern. Access to this port should be strictly controlled and secured with strong authentication and potentially network-level restrictions (like firewalls or VPNs) to prevent unauthorized remote control of the system.
2. **Development SSL Certificate:** The SSL certificate on port 443 is identified as a "mkcert development certificate". While this is common in development environments (especially with tools like ddev, as suggested by the Subject Alternative Names like `*.ddev.local`, `*.ddev.site`), using such certificates in a production setting is inappropriate and untrusted by public Certificate Authorities.
3. **Software Versions:** Specific versions of services like **OpenSSH 8.9p1** and **CherryPy httpd 18.9.0** were identified. A security analyst should check these versions against public vulnerability databases (like CVEs) to see if any known exploits or weaknesses exist for these specific versions.
4. **Generic HTTP Titles:** Ports 80, 443, and 8080 all returned "Site doesn't have a title". While not a direct security vulnerability, this suggests a lack of specific configuration on these web servers.

In summary, the scan revealed several open services, including SSH, multiple web servers, and notably a noVNC instance. The noVNC service and the use of a development SSL certificate are the most prominent security-related findings that warrant further investigation and potential hardening. You should review the configurations of the services running, especially the access controls for noVNC and the appropriate use of SSL certificates.

Notice how Gemini has correctly identified the VNC service as a potential issue. In other testing Gemini called functions multiple times in one task, identifying the local IP address, then using Nmap twice. Launching Nmap once to perform the port scan and a second time to run an NSE script.

Keep in mind that with the llm command line you can include the --td argument so the full tool (Nmap) output is included in the response. There is also the built-in option of llm logs, a handy option that will show the full logs including Full Prompt and Response.

Working with Local Models

As llm provides easy access to models running in ollama, quickly testing other models is very convenient.

llm models

This command will show all models accessible by the tool. Including those running on ollama.

llm -m qwen3:4b --functions llm-nmap.py "add your prompt here"

I tested a number of local models with tool calling capabilities including qwen3:4b, llama3.2 and devstral. While I had some success with devstral successfully running an Nmap function, the others seemed to struggle getting results. It may be the way the functions are structured or my prompt, but in this quick experiment Google's Gemini Flash blew the local models away with its ability to not only call the functions but work through a process calling multiple functions as required in an impressive loop.

Where to Next?

This was a small experiment, but it opens the door to some interesting workflows. You could use similar tools / plugins / functions to:

  • Run additional scans based on discovered results.
  • Chain output from Nmap into other network recon tools such as HTTP fuzzing on web endpoints.
  • Build a chat interface for internal teams to perform security auditing and other system level checks.
  • Deploy Metasploit and let the robots loose! Please go exploit this host and drop a meterpreter! See warning above before trying this...
  • Manage a C2, hey Deepseek please check on Cobalt Strike beacons and implants for new activity. Once again not recommended but an interesting scenario to consider.
Deploying Metasploit with Deepseek

The experiment reminded me that tool use with LLMs is not about automation for its own sake, and more about increasing productivity through accessibility and speed. It won’t replace security analysts this week but it might just save you time, especially when juggling multiple tools.

Want to try it yourself? Check out Simon Willison’s llm project and plug in your own tools. Just don’t forget to sandbox it.