Scanning Windows Deeper With the
Nmap Scanning Engine
by Ron Bowes
Nov. 29, 2017 0 comments 18 minute read
Pen Testing & Audits microsoft windows nmap
Table of Contents
Introduction
Server Message Block
SMB_COM_NEGOTIATE
SMB_COM_SESSION_SETUP_ANDX
SMB_COM_TREE_CONNECT_ANDX,
SMB_COM_NT_CREATE_ANDX
Microsoft RPC
Authentication
smb-enum-users.nse
smb-enum-shares.nse
smb-enum-sessions.nse
smb-enum-processes.nse
smb-system-info.nse
smb-check-vulns.nse
smb-brute.nse
smb-pwdump.nse
Countermeasures
Example
Step 1: discovery
Step 2: Generate user list
Step 3: Brute force known user accounts
Step 4: Dump hashes and try cracking
Step 5: Try using discovered hashes
Step 6: Dump hashes and try cracking (again)
Step 7: Log into Financial
Conclusion
Introduction
Nmap, a network scanner, is among the best known security
tools, and is considered to be one of the best free security
tools in existence (Darknet, 2006). The typical use and
functionality of Nmap is beyond the scope of this paper, but
familiarity will make this paper far easier to be understood.
The book Nmap Network Scanning, which is partially available
for free, is one of the best information sources (Lyon, 2009).
All scripts and libraries referenced in this paper will be included
with Nmap 4.85, which is expected to be released in summer
of 2009; they are currently available in Nmap 4.85beta4 and
higher.
The Nmap Scripting Engine, or NSE, is an extension to Nmap
developed with several purposes in mind, including advanced
network discovery, sophisticated version detection,
vulnerability detection, backdoor detection, and vulnerability
exploitation (Lyon, 2009). After Nmap scans a group of hosts,
NSE runs scripts against each host that matches specific
criteria (for example, the host has the appropriate ports open).
These scripts, which are written in the Lua programming
language, can inspect the host in a much deeper and more
sophisticated way than Nmap alone. Since Lua is a complete
programming language, the possibilities for scripts are great.
In addition to the power of scripts, another important aspect is
the development culture. Since scripts can be written by
anyone, and Lua is a relatively simple language for
programmers to learn, it is not difficult for a programmer to
begin developing his or her own script. Due to the fairly small
team of core developers, and an active mailing list, getting
started in script development is easy.
Server Message Block
The Server Message Block (SMB) protocol, which is commonly
called the Common Internet File System (CIFS), is a protocol
used by Microsoft services (and implemented by Samba,
among others) to communicate with each other. SMB can
function directly on TCP port 445 or over NetBIOS on port 139
(Petri, 2009). Although it was originally designed as a protocol
to manage files remotely (Leach, 1998), SMB can use named
pipes and the Distributed Computing Environment/Remote
Procedure Call (DCE/RPC) system to call remote functions
(Kenneth, 1999). This opens up great possibilities for foot
printing servers.
The SMB protocol is fairly complicated, but, for the purposes of
Nmap scripts, only a small subset is used. The
implementations of it vary greatly, especially when it is used
by printers and other embedded devices. Even the
implementations in Samba and Windows are inconsistent with
each other. As a result, the Nmap library for handling SMB
connections has to be very tolerant of protocol differences, and
attempts to communicate with all implementations. For more
information on the SMB protocol, Implementing CIFS is a useful
resource (Hertel, 2003).
In any implementation of SMB, three packets are sent to
establish a session: SMB_COM_NEGOTIATE,
SMB_COM_SESSION_SETUP_ANDX, and
SMB_COM_TREE_CONNECT_ANDX (see diagram) (Leach, 1998).
In its response to all three messages, the server reveals
information about itself. If the first three packets are
successful, the client usually sends a fourth packet,
SMB_COM_NT_CREATE_ANDX, which creates or opens a file or
pipe.
SMB_COM_NEGOTIATE
The SMB_COM_NEGOTIATE packet is the first one sent by the
client, and is the client's opportunity to indicate which
protocols, flags, and options it understands. The server
responds with its preferred protocol, options, and flags, based
on the client’s list. The options and flags reveal certain
configuration options to the client, such as whether or not
message signatures are supported or required, whether or not
the server requires plaintext passwords, and whether share-
level or user-level authentication is understood. These options
are probed by the script smb-security-mode.nse. The following
is an example output against a typical configuration of
Windows:
Some of these options are revealing from a penetration
tester's perspective. For example, this server does not support
message signing; as a result, man-in-the-middle attacks are
possible. However, since message signing is not a default
option on Windows, this is not a surprising state. If share-level
security or plaintext passwords were required, however, that
would be an interesting find. Implementing CIFS has more
information about the different levels of security supported by
SMB. (Hertel, 2003).
In addition to the security information, the response to
SMB_COM_NEGOTIATE also reveals the server's time and
timezone, as well as the name of the server and its workgroup
or domain membership. Revealing the time may be useful to a
penetration tester because it is a sign of how well maintained
a server is. The name and workgroup of the server can be
helpful to a penetration tester when trying to determine the
purpose of a server or a network, leading to more targeted
attacks for a penetration tester.
The script smb-os-discovery.nse probes for the server’s name
and time. The following output is from smb-os-discovery run
against a poorly maintained Windows 2000 test server:
From the name and time alone, it can be determined that the
operating system is Windows 2000 ("RON-WIN2K-TEST"), that it
is a test machine, and that the time is off by about an hour
(the current time is 11:03, but the server returns 11:59). One
may conclude that it is a test server running on an outdated
operating system, and that it is poorly maintained or
infrequently used. This information could be valuable to a
penetration tester when choosing a target, since the chances
that this server has unpatched vulnerabilities are high. On a
large network, this can quickly give a sense of a network's
composition and purpose.
SMB_COM_SESSION_SETUP_ANDX
The SMB_COM_SESSION_SETUP_ANDX packet is sent by the
client immediately after the negotiate response is received.
The packet’s primary purpose is authentication, and contains
the client’s username, domain, and password. Unless plaintext
authentication was requested in the negotiate packet, the
password is hashed with one of Microsoft's hashing algorithms
(both Lanman and NT Lanman (NTLM) are used by default).
Recovering the password from one these hashes is supposed
to be difficult (although in practice it is usually straight
forward). Instead of sending a username and password, the
client may also establish a null (or anonymous) session by
sending a blank username and a blank password.
For the purposes of these scripts, four account types are
defined. Anonymous accounts, commonly called a “null
session,” offer little access to the system, except on Windows
2000. Guest accounts offer slightly more access, and can find
some interesting information; the guest account typically has
no password and is disabled by default on many Windows
versions. Under certain configurations, such as Windows XP’s
default settings, all user accounts, including administrators,
are treated as guests (Microsoft, 2005). User-level accounts are
common, and are able to perform most checks. User-level
accounts are defined as any account on a system that is not in
the “Administrators” group. And finally, administrator-level
accounts are accounts in the “Administrators” group.
Administrative accounts can run every test against Windows
2003 and earlier, but are essentially the same as user-level
accounts on Windows Vista and higher unless user account
control (UAC) is disabled.
The server's response to the SMB_COM_SESSION_SETUP_ANDX
packet contains a true/false value indicating whether or not
the username/password combination was accepted. If it was
accepted, which is always the case when an anonymous (null)
session is requested, the server also includes its operating
system and LAN manager version in the reply.
The smb-os-discovery.nse script will authenticate anonymously
and display the operating system information. The following
examples show the smb-os-discovery.nse script being run
against Windows 2000 and Windows 2003:
If the login fails, the session setup can be sent again, without
reconnecting. The smb-brute.nse script takes advantage of this
behaviour to run a very fast bruteforce attack against targets.
The smb-brute.nse script will be discussed in detail in a later
section.
SMB_COM_TREE_CONNECT_ANDX,
SMB_COM_NT_CREATE_ANDX
The SMB_COM_TREE_CONNECT_ANDX and
SMB_COM_NT_CREATE_ANDX packets are less interesting, and
do not reveal much useful information. The tree-connect
packet connects to a Windows share (for example, 'C$' for a
file share or 'IPC$' for making remote procedure calls). This
packet can be used to verify whether or not a share exists. If a
share exists, either "NT_STATUS_OK" or
"NT_STATUS_ACCESS_DENIED" will be returned when a
connection is attempted, and if the share does not exist then
"NT_STATUS_BAD_NETWORK_NAME" is returned.
The file-create packet creates or opens a file within the share.
The file can be an actual file like "\boot.ini" or a named pipe
like "\PIPE\srvsvc". For making Microsoft RPC calls, the 'IPC$'
share is used and an appropriate named pipe is opened.
Microsoft RPC
Microsoft RPC, or MSRPC, is Microsoft's protocol for performing
remote function calls. MSRPC is also called Distributed
Computing Environment Remote Procedure Call, or DCERPC.
For the purposes of this paper, MSRPC calls are made over a
SMB connection; while there are other interfaces for MSRPC
calls, SMB is the most common one.
Before making MSRPC calls, an appropriate pipe (or interface)
has to be opened. There are several commonly used
interfaces, and the following are used by Nmap scripts:
• SAMR ‐‐ Security account management
• LSA ‐‐ Local security authority
• SRVSVC ‐‐ Server service
• WINREG ‐‐ Windows registry
• SVCCTL ‐‐ Service control
Each of those interfaces has a number of associated functions.
For example, the SRVSVC interface contains these functions,
among others (the names used here are the names used by
Samba, not Microsoft):
• NetShareEnumAll()
• NetShareGetInfo()
• NetServerStatisticsGet()
• NetPathCanonicalize()
These functions can be called by an Nmap script, and many
will provide useful information about the server. For example,
NetShareEnumAll() returns a list of shares on a system, and
NetShareGetInfo() retrieves information on a share.
NetShareEnumAll() is used by the smb-enum-shares.nse script
to generate the following list:
Whereas NetShareGetInfo() can retrieve deeper information
about each of the shares, as demonstrated by the verbose
version of the smb-enum-shares.nse script:
The functions used for each script will be discussed when the
script itself is discussed.
Authentication
Two main types of MSRPC checks are used by the NSE scripts:
anonymous and authenticated. Anonymous checks use a null
session, whereas authenticated checks use a known user
account (a username and password). Authenticated checks can
be further broken down into three types: guest, user, and
administrator. The guest account, which usually requires no
password, can only access a minimal amount of information
(although more information than anonymous). User-level
accounts (user accounts on the system that aren't part of the
"administrators" group) can access nearly all information, but
are unable to check certain registry keys and cannot access
certain interfaces (such as SVCCTL (service control)).
Administrator-level accounts (user accounts in the
"Administrators" group) can access all functions on Windows
systems up to Windows 2003. Windows Vista and above give
administrator-level accounts the same access as a user-level
account, unless user access control (UAC) is disabled. Several
methods exist for performing authenticated scans from Nmap.
A user account and password can be given on the command
line when running the scan (this assumes that the account is
known to the penetration tester, which isn't always the case).
The smbuser and smbpass parameters are used, as shown
here:
Instead of a username and password, a username and a hash
of the user’s password can be given instead. The password
hash can be taken from "fgdump" or "pwdump6" password
dumps, decrypted from the SAM file (Erugor, 2004), dumped
with the “smb-pwdump.nse” script, or read using Meterpreter's
"priv" module (Skape, 2004). The advantage to using this
technique, commonly known as "passing the hash", is that
password hashes dumped from one server can be directly used
to access other servers, without cracking them. The hash can
be used directly by passing a "smbhash" argument instead of
"smbpass":
Third, the smb-brute.nse script can be used to bruteforce
account passwords. Those passwords will automatically be
used to perform further checks. When smb-brute.nse is run
with other smb scripts, it is guaranteed to run first. Accounts
discovered by smb-brute.nse are automatically used in all
other scripts. Here is an example of how it is used:
smb-enum-users.nse
One of the initial goals when developing the SMB suite of
scripts was user enumeration. This script is intended to
enhance and replace the functionality of enum.exe (Blake,
2003) and sid2user.exe/user2sid.exe (Gates, 2006).
Several methods exist for remotely enumerating users, and
smb-enum-users.nse implements two of them: a straight
enumeration using SAMR functions, and a bruteforce using LSA
functions. SAMR enumeration, which uses functions defined in
the Security Accounts Manager, returns all user accounts
defined by the system. LSA Bruteforcing, which uses Local
Security Authority functions, tries to guess users based on
their unique (and sequential) identifiers. By default, both are
used by the smb-enum-users.nse script. Optionally, a script
argument can disable either scan type, but there is rarely a
compelling reason for disabling this functionality.
SAMR enumeration uses a technique similar to the enum.exe
program. The QueryDisplayInfo() function returns a detailed list
of users, along with descriptions, user types, and full names.
SAMR enumeration can be performed anonymously against
Windows 2000 systems, and with a user-level account or better
on later Windows versions.
The following SAMR functions are called, in this order, to obtain
the user list:
• Connect4(): obtain a connect_handle.
• EnumDomains(): obtain a list of the domains.
• QueryDomain(): obtain the security identifier (SID) for the
domain.
• OpenDomain(): obtain a handle for each domain.
• QueryDisplayInfo(): obtain the list of users in the domain.
• Close(): close the domain handle.
• Close(): close the connect handle.
The advantage of this technique is that detailed information is
returned, including the full name and description; the
disadvantage is that it requires a user-level account on every
Windows version newer than Windows 2000.
LSA bruteforcing uses a different technique, modeled after the
user2sid and sid2user programs. LSA bruteforcing can be
performed anonymously against Windows 2000, and requires a
guest account or better on newer Windows versions. The
primary disadvantage is that it returns less information (only
the username). Additionally, due to the nature of bruteforcing,
this technique can miss accounts and it generates significantly
more traffic than SAMR enumeration.
Although LSA bruteforcing uses a brute-force check to find
accounts, it is not a brute force in the sense that it tries every
possible account name; instead, it is a brute force of the users'
RIDs. A user's RID is a value (generally 500, 501, or 1000+)
that uniquely identifies that user on a system or domain. An
LSA function is available that converts an RID (like 1000) to the
username (like "Ron"). So, the technique will essentially try
converting 1000 to a name, then 1001, 1002, and so on, until
a termination condition is reached.
The implementation used by smb-enum-users.nse breaks the
scan into groups of RIDs. If too many RIDs are chosen, packet
fragmentation occurs and slows down the check; if too few are
chosen, more traffic is generated, also slowing down the scan.
smb-enum-users.nse uses groups of 20 users, a number
chosen by trial and error. All members in each group are
checked simultaneously, and the responses are recorded (1000
- 1019, 1020 - 1039, 1040 - 1069, and so on). Normally, some
RIDs will convert to names and others will not be found, due to
deleted accounts. A completely empty group may indicate the
end of the active RIDs, but it is possible to have an empty
group with non-empty groups after it. For that reason, smb-
enum-users.nse requires a series of 10 empty groups (or 200
blank RIDs) before terminating the scan.
Before attempting this conversion, the security identifier (SID)
of the server is required. The SID is determined by doing the
reverse operation; that is, by converting a name into its
equivalent SID. So, if RID 1000 represents "Ron", then "Ron"
would convert to "[SID]-1000". The name looked up by the
script can be any user on the server, including the server's
name itself. smb-enum-users.nse uses a list of common
names:
• The computer name and domain name, returned in the
SMB_COM_NEGOTIATE packet;
• Currently logged in user from an nbstat query; and
• Default or common usernames: "administrator", "guest", and
"test".
In most cases the computer name is sufficient, but the
overhead of looking up a few extra names is insignificant. The
sequence of calls used by smb-enum-users.nse is:
• OpenPolicy2(): Gets a policy handle.
• LookupNames2(): Converts names to SID.
• LookupSids2(): Converts SIDs back to names.
• Close(): Close the policy handle.
Here is sample output for smb-enum-users.nse, using both
SAMR and LSA enumeration, running anonymously against
Windows 2000:
And here is the output with the verbose option enabled:
smb-enum-shares.nse
Enumerating file shares on a remote system is one of the
simplest scripts, and was the first one written. A single
function is used to enumerate the shares (NetShareEnumAll()
in SRVSVC) and another function is used to probe for
information about the share (NetShareGetInfo() in SRVSVC).
Additionally, a standard SMB packet,
SMB_COM_TREE_CONNECT_ANDX, is used to determine
whether or not the share is accessible anonymously by
attempting to use it.
NetShareEnumAll() will run anonymously against Windows
2000, and requires a guest account for newer Windows
versions. NetShareGetInfo(), however, requires an
administrator-level account on every version of Windows, even
Windows 2000.
If access to NetShareEnumAll() is denied, the script uses a
bruteforce check by sending a series of
SMB_COM_TREE_CONNECT_ANDX packets. A list of common
shares is used, and each one is checked. A response of
"NT_STATUS_ACCESS_DENIED" or "NT_STATUS_OK" means that
the share exists, and any other error, such as
"NT_STATUS_BAD_NETWORK_NAME", means it does not exist.
The list of shares is based on the Windows 2000 machines at
the University of California San Diego (thanks to Brandon
Enright from the Nmap team), and includes:
If any of those shares exist, they will be discovered
anonymously against any version of Windows.
Here is an example output of smb-enum-shares.nse being run
anonymously against a Windows 2000 system:
And here is the output of smb-enum-shares.nse being run
against a Windows 2000 system with administrator credentials
and verbose enabled:
smb-enum-sessions.nse
smb-enum-sessions.nse, which is based on the concept (but
not the code) of PsLoggedOn (Russinovich, 2006), attempts to
enumerate two different types of sessions:
1. Users logged in interactively, either through terminal services or
locally on the machine’s console
2. Users connected to file shares
These two enumerations are implemented completely
differently, but are kept together due to similar functionality.
Checking which users are logged in interactively is a
combination of WINREG checks and LSA lookups. First, a
WINREG function is used to enumerate the keys in the
HKEY_USERS hive, which is a list of the logged in users' SIDs.
Those SIDs are converted to names using the LookupSids2()
function, similar to how LSA bruteforcing is performed in smb-
enum-users.nse.
Checking which users are connected to file shares requires a
call to the NetSessEnum() function in SRVSVC. NetSessEnum()
can be called by the guest account on Windows 2000, and a
user-level account or higher on newer versions of Windows.
Here is the output for a sample run against Windows 2000
using the guest account:
smb-enum-processes.nse
smb-enum-processes.nse, as its name suggests, enumerates
the processes running on a remote machine. This script, which
requires administrative privileges on all versions of Windows,
reads the hidden HKEY_PERFORMANCE_DATA registry hive, and
parses the data found therein. The encoding of the data is
complicated, but the output is fairly simple (this is against
Windows 2000 with administrative credentials):
Here's the output with verbose enabled:
And finally, here’s the output with extra verbose enabled:
This script is based on the idea behind (but not the code for)
the PsList tool (Russinovich (2), 2006) from SysInternals.
smb-system-info.nse
smb-system-info.nse is a relatively simple script in comparison
to the others; it simply queries the Windows registry for a
variety of information. Windows 2000 will allow the guest user
to query for limited information, while other Windows versions
require a user account or higher. In all versions of Windows, a
more privileged account will have access to more information.
Here is the output of smb-system-info.nse running against
Windows 2000 with guest-level access:
When the script is given administrator access, it produces the
following output:
Like several other scripts, the concept behind this is from a
PsTools program, PsInfo (Russinovich, 2007).
smb-check-vulns.nse
smb-check-vulns.nse was originally designed to help
administrators (or penetration testers) find machines missing
Microsoft’s MS08-067 patch. MS08-067 was a critical
vulnerability in Windows published by Microsoft in October of
2008 (Microsoft, 2008). The script gained significant popularity
in March and April of 2009, when detection for the Conficker
worm was added (Lyon, 2009).
smb-check-vulns.nse works similarly to Nessus, sending
attack-like traffic to a port and checking the reaction. The
MS08-067 check is based on a public scanner, and uses the
NetPathCompare() function in the server service.
NetPathCompare() indirectly calls NetPathCanonicalize(), which
is the target of MS08-067. Without applying MS08-067,
NetPathCanonicalize() will accept invalid parameters (and,
potentially, crash), but after applying MS08-067,
NetPathCanonicalize() recognizes invalid parameters and
returns an error. By calling the NetPathCompare() or
NetPathCananicalize() with invalid parameters, and checking
whether or not an error is returned, the presence of the patch
can be accurately determined.
Instability is a major drawback of checks such as MS08-067;
because the traffic is similar to an attack, crashing a machine
is possible. In tests, the check for MS08-067 crashed over half
of all vulnerable systems.
Detection for the Conficker worm uses a technique based on
work by Felix Leder and Tillmann Werner (Leder & Werner,
2009). The deployment of this check in Nmap and other
network scanners was coordinated by the Conficker Working
Group. The researchers discovered that Conficker applies its
own patch to MS08-067, but that the patch was different from
Microsoft’s official patch. Instead of returning the standard
Microsoft error (“INVALID_NAME”), another error code is
returned (the number is 0x00000057, a non-standard error
code). By calling NetPathCanonicalize() with a dangerous-
looking parameter, Conficker will reveal its presence. This is
very useful to network administrators who need to scan their
networks quickly.
Here is the output from a scan against an infected machine:
Although MS08-067 has been patched, the scan has detected
that the patch was performed by Conficker, not by Microsoft.
This output is from another scan, this time the system is
vulnerable but is not infected:
smb-brute.nse
smb-brute.nse will attempt to log into a SMB account by
guessing usernames and passwords. The code and algorithms
are designed to take advantage of the SMB protocol in a
variety of ways in order to discover which users exist and
whether or not it is possible to determine their passwords.
Initially, this script uses the same techniques as smb-enum-
users.nse to determine which usernames exist on the system.
If that fails, a list of well known usernames is used. If a valid
account is discovered during the scan, that account will be
used to obtain a proper list of user accounts.
Before the bruteforce starts, an attempt is made to log into
each account with a known invalid password. In certain
configurations, the responses will reveal whether or not the
username exists on the system; if it is confirmed that the user
does not exist, it is skipped.
When a valid username/password combination is discovered, it
is displayed to the user. Additionally, the SMB module has the
opportunity to store the account. If this is the first account
discovered on the system, the account is stored; otherwise,
the account’s privileges are checked, and it’s only stored if it
has administrative privileges. This check is done by calling
GetShareInfo(), a function that can only be called by an
administrator. Once the SMB module saves this information, all
further scripts will use these credentials to perform checks; in
other words, the rest of the scan is effectively authenticated.
The major downside to smb-brute.nse is that it can lock out
accounts. This downside is somewhat mitigated by Windows'
default settings, since account lockout is disabled by default.
Even if lockout is enabled, the Administrator account can't be
locked out unless the system is specifically configured to do so.
Even so, this script can create a dangerous denial-of-service
condition. Additionally, if smb-brute.nse detects an account
lockout, it will stop scanning that host to prevent further
lockouts. When that happens, a warning is displayed in the
results, which may allow the tester to inform the proper
person. smb-brute.nse also uses a technique called a “canary
account,” where it attempts to lock out the first account
intentionally, to check if a server has lockouts configured. If it
does, the scan stops immediately.
Here is the output of a successful smb-brute.nse run:
Although the functionality of smb-brute.nse is similar to other
tools, such as thc-hydra, it isn't based on any specific tool or
implementation. The purpose of smb-brute.nse is to perform
fast checks for common passwords, not to launch a full
bruteforce. Much of its power comes from a deep
understanding of the SMB protocol.
smb-pwdump.nse
smb-pwdump.nse is a powerful script that is also invasive and
somewhat dangerous. It implements the functionality found in
pwdump6,[9] written by the Foofus group, to obtain a list of
password hashes from the remote system. Due to the potential
risks of using it, and also due to the risk of being labeled as
malware, required library files from pwdump6 (servpw.exe and
lsremora.dll) are not included in Nmap and have to be
downloaded separately.
The steps taken by the script are as follows:
• Establish a connection to the target system
• Upload servpw.exe and lsremora.dll to a file share using SMB
(currently, the
C$ share is used, but in the future it will use fgdump's method of
searching
for an open share)
• Create and start a service (servpw.exe) using SVCCTL functions
• Read and decrypt the data from the service (servpw.exe writes to
a named
pipe using Blowfish encryption, which can be read remotely ‐‐ this
encryption is used for obfuscation, not security, since the key
exchange is not
protected)
• Stop the service and remove the files
Obviously, this script is very intrusive (and requires
administrative privileges on all Windows versions). To
accomplish its goal, this script runs a SYSTEM-level service on
the remote machine, and the service injects itself into the
LSASS process to determine the password hashes. Despite the
invasiveness, one of the primary goals of this script was to
clean up thoroughly. Unless the system crashes, the service
will be removed and the files deleted.
This script was written mostly as an academic exercise, and to
highlight Nmap's growing potential as a penetration testing
tool. It compliments the smb-brute.nse script because smb-
brute.nse can find weak administrator passwords, then smb-
pwdump.nse can use those passwords to dump hashes. Those
hashes can then be cracked (either manually or automatically
– smb-pwdump.nse can integrate with Rainbow Crack) and
added to the password list for more brute forcing. The hashes
themselves can also be added to Nmap's password list, since
smb-brute.nse understands how to use hashes. Future plans
include automatically using discovered hashes against other
systems.
Countermeasures
Preventing these attacks is actually quite simple. The following
steps can be taken:
• Block access to Windows' ports (137, 139, and 445 in particular)
• Disable Windows services (for example, disabling the server
service, remote
registry service, and service control service will render these
scripts
significantly less effective)
• Use newer versions of Windows (each version of Windows gives
less
information and has less running by default)
• Disable null sessions (Microsoft), especially on Windows 2000
Example
This example penetration test will explore a sample network,
made up of four hosts. Three hosts are Windows systems of
various versions, and the final one is Linux. The goal of this
penetration test is to gain access to the Linux server using
only Nmap and Rainbow crack. In the interest of saving space,
only quick excerpts from Nmap will be shown.
Step 1: discovery
The first step is network discovery – that is, determining which
hosts are active and which operating systems they are
running.
First, the active IP addresses are determined using a standard
Nmap ping sweep (“-sP”).
Then, the smb-os-discovery.nse script is used to determine the
remote operating systems and computer names.
This output reveals that “JIM-PROD” is Windows 2003, ”JIM-
TEST” is Windows XP, and ”MARY-PROD” is Windows 2000.
Step 2: Generate user list
Next, smb-enum-users.nse is run across the network, and, in
the interest of saving space, grep is used to determine the
interesting information.
The interesting user accounts are “Administrator”, “Guest”,
“jim”, “mary”, and “test”. Those usernames are added to
usernames.txt, for use in smb-brute.nse.
Step 3: Brute force known user accounts
Next, smb-brute.nse is run with the username file generated in
the previous step. The default password file is used.
From these results, the “guest” and “test” accounts had
guessable passwords. The “guest” account can rarely perform
interesting scans, but the “test” account may have higher
access.
Step 4: Dump hashes and try cracking
Using the newly determined “test” login, run the smb-
pwdump.nse script (with Rainbow Tables) to see if “test” has
access to the password file.
The “test” account successfully dumped the password hash for
“mary”. Further, although it successfully cracked the
previously known password for “test”, it could only determine
half of the “mary” password.
Step 5: Try using discovered hashes
Next, the downloaded hashes (“administrator”, “mary”, and
“test”) are saved in a file called “password.txt” and smb-
brute.nse is re-run using the hashes instead of the default
password file.
According to these results, the “mary” password hash also
worked on 192.168.101.20.
Step 6: Dump hashes and try cracking (again)
pwdump and Rainbow Crack are now run against
192.168.101.20 with the “mary” credentials, which will
download the password database from that system if “mary”
has sufficient access.
Not only was this check able to determine the “jim” hash, the
Rainbow Crack successfully cracked the “jim” password, too:
“cornflakes”.
Step 7: Log into Financial
Using this password, a successful login is made to “Financial”.
Using nothing more than Nmap with built-in Rainbow Crack,
the penetration test was successful.
Conclusion
The Nmap scripting engine is a powerful tool for user-created
scripts. This power is demonstrated in the suite of scripts
designed to inspect Windows over the SMB protocol. Many
footprinting tasks can be performed, including finding user
accounts, open shares, and weak passwords. All these tasks
are under a common framework, and share authentication
libraries, which gives users a common and familiar interface.
Published with the express permission of the author.