Nmap is not only the best port-scanning tool out there, but also a very good service-level enumeration tool with support for customized scripts and hundreds of publicly available scripts ready to use out of the box. This is possible through the Nmap Scripting Engine (NSE), Nmap’s most powerful feature that gives its users the ability to write their own scripts and use Nmap for more than just port scanning.
NSE Scripts
Nmap’s pre-installed scripts can be found at /usr/share/nmap/scripts
. Script names are assigned prefixes according to which service they are meant for - making it easier to search for service-specific scripts:
root@server:/usr/share/nmap/scripts# ls ssh-*
ssh-auth-methods.nse
ssh-brute.nse
ssh-hostkey.nse
ssh-publickey-acceptance.nse
ssh-run.nse
SSH Enumeration
SSH (Secure Shell) is a widely used remote access protocol present in almost any network, making it a very important service to enumerate. Nmap ships with multiple ready-to-use SSH enumeration scripts that aid in identifying authentication methods, grabbing SSH host keys, checking if certain public keys are accepted, detecting SSHv1 servers and running brute-force attacks.
Authentication methods
SSH servers by default allow both key-based and password-based authentication, but the latter is commonly considered insecure and may be disabled as an effort towards security hardening. A system administrator managing multiple SSH servers might be interested in ensuring that no SSH server in the network is accepting password-based authentication.
This is where the ssh-auth-methods
script comes in. It communicates with the SSH server directly to identify supported authentication methods:
nmap --script ssh-auth-methods 192.168.6.134
The supported authentication methods will be returned:
| ssh-auth-methods:
| Supported authentication methods:
| publickey
|_ password
Brute-force
Nmap is also equipped with a basic SSH brute-force script that uses username and password wordlists, and tries the combinations against an SSH server. Keep in mind however that this script is not optimized or recommended for brute-force attacks, and may not work as well as fully-fledged brute-force tools.
As with any other tool, specifying username and password wordlists is recommended:
nmap --script ssh-brute --script-args userdb=usernames.txt,passdb=passwords.txt 192.168.6.134
The script will try the credentials and return any match:
| ssh-brute:
| Accounts:
| root:letmein - Valid credentials
SNMP Enumeration
SNMP (Simple Network Management Protocol) is a network management protocol used to remotely monitor or manage a system - making SNMP servers a common target as they can be used to extract a wide range of information from the system.
SNMP uses community strings for authentication, which are communicated in plaintext in SNMP versions 1 and 2. Moreover, SNMP does not have a defense mechanism against brute-force attacks - making it easier for an attacker to find a community string.
Nmap includes various scripts for enumerating SNMP services:
root@server:/usr/share/nmap/scripts# ls snmp-*
snmp-brute.nse
snmp-hh3c-logins.nse
snmp-info.nse
snmp-interfaces.nse
snmp-ios-config.nse
snmp-netstat.nse
snmp-processes.nse
snmp-sysdescr.nse
snmp-win32-services.nse
snmp-win32-shares.nse
snmp-win32-software.nse
snmp-win32-users.nse
Brute-force community strings
SNMP servers may be configured to accept any number of community strings, each of which may be assigned different permissions and restrictions on what information can be accessed. Community strings are either read-only or read-write, public
being read-only and private
being read-write in most default installations.
The snmp-brute
script is used to brute-force community strings. For better results it can be paired with a wordlist retrieved from SecLists that contains common SNMP community strings:
nmap -p 161 -sU --script snmp-brute --script-args snmp-brute.communitiesdb=./SecLists/Discovery/SNMP/common-snmp-community-strings.txt 192.168.6.2
Valid community strings will be returned:
PORT STATE SERVICE
| snmp-brute:
| public - Valid credentials
|_ private - Valid credentials
|_ Secret - Valid credentials
Going further
Once a valid community string is found, we can dive deeper into the enumeration scripts and extract information about the target’s network interfaces, network connections and processes - which is essentially very important information looked for during the reconnaissance phase.
Let’s start by querying network interfaces from the SNMP server, which is done with the snmp-interfaces
script. Keep in mind that by default the public
community string is used for queries, but a different one may be specified via the --script-args
parameter:
nmap -p 161 -sU --script snmp-interfaces --script-args creds.snmp=Secret 192.168.6.2
This reveals all the network interfaces and assigned IP addresses:
| snmp-interfaces:
| eth0
| IP address: 192.168.6.2 Netmask: 255.255.255.0
| MAC address: 52:54:00:bb:8e:bf (QEMU virtual NIC)
| Type: ethernetCsmacd Speed: 0 Kbps
| Status: up
|_ Traffic stats: 53.08 Kb sent, 605.08 Kb received
Similarly, we can use the snmp-netstat
script to query all active network connections:
root@desktop:~# nmap -p 161 -sU --script snmp-netstat --script-args creds.snmp=Secret 192.168.6.2
| snmp-netstat:
| TCP 0.0.0.0:22 0.0.0.0:0
| TCP 10.77.25.1:9728 0.0.0.0:0
| TCP 127.0.0.1:42965 0.0.0.0:0
| TCP 127.0.0.53:53 0.0.0.0:0
| TCP 172.17.0.1:50250 172.17.0.2:22
| TCP 192.168.6.2:22 192.168.6.254:58802
| UDP 0.0.0.0:161 *:*
|_ UDP 127.0.0.53:53 *:*
Apart from network connections, it’s also possible to reveal all processes running in the target server via the snmp-processes
script:
root@desktop:~# nmap -p 161 -sU --script snmp-processes --script-args creds.snmp=Secret 192.168.6.2
| snmp-proc
| 1:
| Name: System Idle Process
| 4:
| Name: System
| 256:
| Name: smss.exe
| Path: \SystemRoot\System32\
[output omitted]
More information can be accessed if the SNMP server is running on a windows environment:
- Services - snmp-win32-services.nse
- File shares - snmp-win32-shares.nse
- Installed software - snmp-win32-software.nse
- Users - snmp-win32-users.nse
SMB Enumeration
SMB (Server Message Block) is a communication protocol for sharing files, printers and serial ports over a network. The protocol was primarily developed and designed for Windows environments, but is also used to share files between Windows and Linux/Unix environments thanks to the Samba project.
SMB comes with a big history of vulnerabilities, making it a primary target and quite dangerous if left insecure, either due to unpatched vulnerabilities or misconfigurations. To give you an idea, the WannaCry ransomware exploited a vulnerability affecting SMB in Windows.
Nmap includes over 30 ready-to-use SMB scripts that offer service-level enumeration and vulnerability scanning, which can help identify potential misconfigurations and/or vulnerabilities.
Security Mode
An SMB server may be configured to accept only one of two security levels, which differ in how a user is authenticated:
- User-level authentication - classic username and password authentication
- Share-level authentication - anonymous account is used to log in, after which the password is given
On top of the chosen security level, additional security measures such as message signing and challenge/response passwords can be configured:
- Challenge/response passwords - any type of password can be used for authentication
- Message signing - all messages exchanged between the client and the server must be signed
Different configurations of security levels are called security modes.
The general security configuration of an SMB server can be retrieved with the smb-security-mode
script:
nmap --script smb-security-mode <target>
The script queries the SMB server and shows which security measures are configured:
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
From the above output, we can see that user-level authentication is used with support for challenge/response passwords.
User Enumeration
System users can be enumerated through SMB with the smb-enum-users
script:
nmap --script smb-enum-users <target>
Valid user RIDs are retrieved and converted to names with the help of an internal function, after which more information about the user is given:
| smb-enum-users:
| SERVER\admin (RID: 1000)
| Full name: Davey
| Description: I manage thee
| Flags: Normal user account
| SERVER\david (RID: 1001)
| Full name: David
| Description: Software engineer
| Flags: Normal user account
| SERVER\john (RID: 1002)
| Full name: John
| Description: Intern
|_ Flags: Normal user account
Depending on the SMB server, this may either list all system users or only users that have access to the SMB server.
Brute-force
Credentials of SMB users can be brute-forced with the smb-brute
script:
nmap --script smb-brute --script-args smbtype=v2 <target>
The authentication type used by this script is not always compatible with what the target SMB server supports. For this reason, another authentication type was specified via the smbtype script argument.
| smb-brute:
| david:monkey => Valid credentials
|_ john:john => Valid credentials
Enumerating & Listing Shares
Available file shares can be enumerated with the smb-enum-shares
script:
nmap --script smb-enum-shares <target>
By default, the script uses guest permissions to list only publicly available shares - private shares will be left out as they are not accessible with guest permissions.
| smb-enum-shares:
| account_used: guest
| \\192.168.6.2\IPC$:
| Type: STYPE_IPC_HIDDEN
| Comment: IPC Service (server server (Samba, Ubuntu))
| Users: 1
| Max Users: <unlimited>
| Path: C:\tmp
| Anonymous access: READ/WRITE
| Current user access: READ/WRITE
| \\192.168.6.2\print$:
| Type: STYPE_DISKTREE
| Comment: Printer Drivers
| Users: 0
| Max Users: <unlimited>
| Path: C:\var\lib\samba\printers
| Anonymous access: <none>
| Current user access: <none>
| \\192.168.6.2\employees:
| Type: STYPE_DISKTREE
| Comment:
| Users: 0
| Max Users: <unlimited>
| Path: C:\samba\public_share
| Anonymous access: READ/WRITE
|_ Current user access: READ/WRITE
The script can be paired with smb-ls
script for automatic listing of all enumerated shares:
nmap --script smb-enum-shares,smb-ls <target>
All available shares identified by the smb-enum-shares
script will be passed on to the smb-ls
script, and then listed:
| smb-enum-shares:
| account_used: guest
| \\192.168.6.2\employees:
| Type: STYPE_DISKTREE
| Comment:
| Users: 0
| Max Users: <unlimited>
| Path: C:\samba\public_share
| Anonymous access: READ/WRITE
|_ Current user access: READ/WRITE
| smb-ls: Volume \\192.168.6.2\employees
| SIZE TIME FILENAME
| <DIR> 2020-02-25 14:36:12 .
| <DIR> 2020-02-21 14:46:20 ..
| 57310 2020-02-21 14:46:20 company_clients.csv
|_
NFS Enumeration
NFS (Network File System) is a network file sharing protocol that gives servers the capability to export and share file systems, which can then be mounted and locally accessed by permitted clients. A table of all exports is kept in /etc/exports
, along with whitelisted IP address(es) and access control lists.
Nmap ships with three out-of-the-box NFS enumeration scripts:
root@server:/usr/share/nmap/scripts# ls nfs-*
nfs-ls.nse
nfs-showmount.nse
nfs-statfs.nse
Enumerating Shares (Exports)
Retrieving all configured exports is pretty simple and can be done with the nfs-showmount
script:
nmap --script nfs-showmount <target>
The script retrieves all exports and whitelisted IP addresses:
| nfs-showmount:
| /var/nfs/public 192.168.1.1/24
|_ /var/nfs/Jack-confidential 192.168.1.67
This is similar to showmount -e <host>
which shows exactly the same information:
root@desktop:~# showmount -e server
Export list for server:
/var/nfs/public 192.168.1.1/24
/var/nfs/Jack-confidential 192.168.1.67
Listing Shares
The nfs-ls
script is useful for getting an overview of file contents without manually mounting and accessing a remote share:
nmap --script nfs-ls <target>
When executed, all files in the share’s parent directory and permitted access rights are shown:
| nfs-ls: Volume /var/nfs/public
| access: Read Lookup Modify Extend Delete NoExecute
| PERMISSION UID GID SIZE TIME FILENAME
| rwxr-xr-x 65534 65534 4096 2020-05-05T11:25:58 .
| rwxr-xr-x 0 0 4096 2020-05-05T11:25:58 ..
| rw-r--r-- 0 0 90 2020-05-05T11:25:58 README.md
| rwxr-xr-x 0 0 4096 2020-05-05T11:25:58 files
Keep in mind that the nfs-ls
script is only meant for a general overview of a share’s contents and doesn’t have features such as recursive listing implemented. However, it’s fairly easy to manually mount a share and take a look around:
sudo mkdir -p /nfs/public
sudo mount server:/var/nfs/public /nfs/public
That’s all it takes to mount a share locally - you can now head to /nfs/public
in your machine and browse the file share.
Conclusion
The Nmap Scripting Engine offers advanced service-level enumeration and takes it one step further by allowing for customized scripts, which may be written from scratch to meet personal demands. Hundreds of enumeration scripts for common services are included out of the box - which may be utilized by anyone interested in testing the security of their network services.