Nmap can hunt down systems still running with their factory-set passwords.

Here’s a quick demo. We’ll scan a small subnet for SSH services running on port 22, and Nmap will try a common list of default credentials.

nmap -p 22 --script ssh-auth-methods,ssh-brute --script-args sshuser=admin,sshpass=admin,userdb=/path/to/your/user.lst,passdb=/path/to/your/pass.lst 192.168.1.0/24 -oN nmap_default_creds.txt

This command runs two scripts: ssh-auth-methods to identify what authentication methods are supported by the SSH server, and ssh-brute which attempts to log in using a provided username and password combination. The --script-args are crucial here:

  • sshuser=admin: This sets the username to try.
  • sshpass=admin: This sets the password to try.
  • userdb=/path/to/your/user.lst: This points to a file containing a list of usernames to attempt.
  • passdb=/path/to/your/pass.lst: This points to a file containing a list of passwords to attempt.

If you don’t have specific user/pass lists, you can often just provide common defaults directly, like sshuser=admin,sshpass=admin or sshuser=root,sshpass=password. Nmap’s built-in brute-force scripts are pretty good at trying common combinations if you don’t specify extensive lists.

The output will show you which hosts, if any, allowed access with these default credentials. For example, you might see something like:

Nmap scan report for 192.168.1.100
Host is up (0.0010s latency).

PORT   STATE SERVICE
22/tcp open  ssh
| ssh-auth-methods:
|   supported: publickey,password
|   preferred: publickey,password
|_  keys: ssh-rsa,ecdsa-sha2-nistp256,ssh-ed25519
| ssh-brute:
|   Accounts:
|     admin:admin (Success!)
|_    root:password (Success!)

Nmap done: 256 IP addresses scanned in 10.20 seconds

This tells you that on 192.168.1.100, the username admin with password admin worked, and root with password also worked.

The problem Nmap solves here is the pervasive issue of devices being deployed with default, unchanged credentials. This is common with network-attached storage (NAS) devices, routers, printers, IoT devices, and even some servers that aren’t properly hardened. These default credentials are often publicly known or easily guessable.

Internally, the ssh-brute script works by establishing an SSH connection to the target port. It then attempts to authenticate using the provided username and password pairs. If authentication is successful, it reports the working credentials. The script can be configured with lists of usernames and passwords to try, or you can specify single username/password combinations. For more complex scenarios, you can also use --script-args userdb=/path/to/users.txt,passdb=/path/to/passwords.txt to feed it extensive lists.

The ssh-auth-methods script is useful because it probes the SSH server to see which authentication mechanisms it supports (like public key, password, keyboard-interactive). This can give you clues about what might work even before brute-forcing. It also identifies the types of public keys accepted, which is useful for other SSH-related security checks.

You can control the speed and intensity of the brute-force attempt using Nmap’s timing options (-T0 to -T5). Be cautious with higher timing levels on production networks, as they can generate significant traffic and potentially trigger intrusion detection systems. A good starting point for a less aggressive scan is -T3 or -T4.

When using ssh-brute, it’s not just about the default credentials that ship with a device. It’s also about weak passwords that administrators might have set but are still easily guessable. The script can be adapted to test against lists of common weak passwords for specific services. For SSH, you can provide lists like rockyou.txt (a famous password list, though use with caution and respect privacy) or more curated lists of common default credentials for specific vendors.

The real power comes from combining ssh-brute with other Nmap scripts. For instance, if you find an open SMB port (445), you could run smb-brute with similar arguments to test for default Windows/Samba credentials. The general principle applies across many services: identify open ports, run relevant NSE scripts to test for common vulnerabilities or weak authentication.

The most surprising thing about default credential scanning is how often it still works, even in environments that are otherwise considered secure. Many organizations focus on patching known CVEs but overlook the fundamental security hygiene of changing default passwords on devices that aren’t directly exposed to the internet but are accessible within the internal network. This internal attack surface is often much larger and more vulnerable.

The ssh-brute script, by default, will try to be somewhat polite and not hammer the server too hard. However, if you want to accelerate it, you can use --script-args ssh-brute.threads=10 (or a higher number) to increase the number of simultaneous login attempts. This is where you start to get into the territory where you might be noticed by security monitoring.

The next thing you’ll likely run into after finding systems with default credentials is the challenge of managing those credentials. It’s one thing to find them, another to systematically remediate them across potentially hundreds or thousands of devices.

Want structured learning?

Take the full Nmap course →