Enumerating with Nmap


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.


Shpëtim Ibrani