Berkner Tech

Post Index

Nmap for Embedded and IoT Pen Testing: A Field Guide If you cannot see what a device is exposing, you cannot secure it. Nmap is the first tool I reach for on almost every embedded engagement. It settles the question you have to answer before anything else: what is this thing actually listening on? Here is how I use it against connected products, along with the things that catch people who learned nmap on cloud servers and then bring those habits to hardware. The reconnaissance pipeline. Broad sweep first, careful probing last. Why Nmap Still Matters on Embedded Targets A connected product is just a host on a network: a thermostat, a vehicle gateway, a smart lock controller, a PLC. It has an IP stack, it has services, and every one of those services is attack surface. Nmap maps that surface quickly. The difference with embedded is that the host on the other end is often a microcontroller with a few hundred kilobytes of RAM and a TCP stack that was never stress tested. Scan it the way you would scan a Linux server and you can knock it over. That is its own kind of finding, but rarely the one you set out to produce. Step 0: Install and Confirm Scope Nmap ships in every package manager: # Debian, Ubuntu, Kali sudo apt install nmap # macOS brew install nmap # confirm the install nmap –version Example output Nmap version 7.95 ( https://nmap.org ) Platform: x86_64-pc-linux-gnu Compiled with: liblua-5.4.6 openssl-3.0.13 libssh2-1.11.0 zlib-1.3 Available nsock engines: epoll poll select Before a single packet goes out, get the scope in writing. Which IPs, which subnets, what hours, and a clear acknowledgement that a fragile device might reboot or hang. On embedded work that last point is not boilerplate. It is the difference between a finding and an incident. Step 1: Host Discovery Start by finding what is alive. A ping sweep across the subnet with no port scan: # -sn = ping scan, no ports nmap -sn 192.168.1.0/24 Example output Starting Nmap 7.95 ( https://nmap.org ) at 2026-06-01 09:14 EDT Nmap scan report for 192.168.1.1 Host is up (0.0012s latency). Nmap scan report for 192.168.1.50 Host is up (0.0089s latency). Nmap done: 256 IP addresses (2 hosts up) scanned in 2.74 seconds Here is the embedded gotcha. Plenty of devices do not answer ICMP echo. A lean stack may ignore ping entirely, or a firewall in front of it drops the request, and nmap then writes the host off as down and never scans it. If you know the device is there, skip discovery and force the scan with -Pn: # treat the host as online; scan it regardless of ping nmap -Pn 192.168.1.50 Example output Starting Nmap 7.95 ( https://nmap.org ) at 2026-06-01 09:16 EDT Nmap scan report for 192.168.1.50 Host is up (0.0091s latency). Not shown: 997 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 8443/tcp open https-alt Nmap done: 1 IP address (1 host up) scanned in 1.83 seconds Step 2: Port Scanning With the SYN Scan The default workhorse is the TCP SYN scan (-sS). It sends a SYN, watches the reply, and never completes the handshake, which makes it fast and relatively gentle. It needs root: # SYN scan, all 65,535 TCP ports sudo nmap -sS -p- 192.168.1.50 Example output Starting Nmap 7.95 ( https://nmap.org ) at 2026-06-01 09:20 EDT Nmap scan report for 192.168.1.50 Host is up (0.0090s latency). Not shown: 65531 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 8443/tcp open https-alt 9999/tcp open abyss Nmap done: 1 IP address (1 host up) scanned in 78.12 seconds That -p- matters more on embedded than almost anywhere else. Note the port the full sweep caught that a default scan would miss: 9999. Vendors like to park services on non-standard ports, such as a debug shell on 9999, a proprietary management protocol on 50000, or a forgotten web interface on 8443. The default scan only checks the top 1,000 ports and walks right past them. Scan the full range first, then narrow. Three states, three very different lines in your report. Reading the States Correctly An open port is live attack surface, and that is where the work is. A closed port means the device is up but nothing is listening on that number. The state that trips people up is filtered. Nmap got no usable reply, which usually means something is dropping the probe rather than that the port is dead. On embedded gear, filtered often just means the device’s thin stack did not answer the way nmap expected, so the right move is a different probe or slower timing rather than a shrug. Step 3: Service and Version Detection Knowing port 8080 is open tells you almost nothing. Knowing it is a GoAhead 2.5 embedded web server tells you which CVEs to pull. That is what -sV does: # probe open ports to fingerprint the service and version nmap -sV 192.168.1.50 # push harder when banners are stubborn (0-9, 9 is most aggressive) nmap -sV –version-intensity 9 192.168.1.50 Example output PORT STATE SERVICE VERSION 22/tcp open ssh Dropbear sshd 2020.81 (protocol 2.0) 80/tcp open http GoAhead WebServer 2.5.0 8443/tcp open ssl/https GoAhead WebServer 2.5.0 9999/tcp open telnet BusyBox telnetd Service Info: Device: embedded Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 12.47 seconds Embedded services often hand back terse or non-standard banners, so version detection will not always land cleanly. Even a partial fingerprint combined with the open-port pattern is frequently enough to identify the firmware family. One command, four decisions, including the one that keeps the device alive. Step 4: The Nmap Scripting Engine (NSE) NSE is where nmap stops describing and starts probing. The -sC flag runs the default script set, which covers safe, useful enumeration such as TLS configuration, HTTP titles, and default-credential checks: # default scripts