The Lowdown on SMB
This is the first post in a series on some of the fun you can have with SMB. We’re going to cover the basics, such as why SMB and how to avoid Kerberos. Future posts are going to talk about different ways you can exploit SMB, and one way where most of the work is already done for you (thanks Windows!).
I started this post with a bunch of fun techniques for attacking NTLM I wanted to write about. As I was organizing my thoughts I realized that they all attacked SMB. This seemed a little strange, since there are all sorts of protocols on a Windows network, so I did some digging and came up with a solid $0.02.
1. It’s Everywhere
You cannot have a Window domain without SMB. As such, all the Windows OSes support it and it’s always enabled. If you’re running Windows, you’re running SMB.
2. UNC Paths Use SMB
There aren’t a lot of WMI queries lying around waiting to get co-opted, but UNC paths (
\\SERVER\share) are everywhere. Some are practically begging to be hijacked.
3. It’s Got Some Fun Features
The previous two points would be pretty useless if it wasn’t for SMB’s feature set. Where SMB gets really interesting is DCE/RPC. DCE/RPC provides a way for one computer to execute commands on another.
The gold standard for code execution using SMB is PSExec, made by the godly Mark Russinovich. Rapid7, the makers of Metasploit, have brought weaponized SMB to the masses with several modules and do a great job of explaining how it works:
The PSExec utility requires a few things on the remote system: the Server Message Block (SMB) service must be available and reachable (e.g. not blocked by firewall); File and Print Sharing must be enabled; and Simple File Sharing must be disabled.
The Admin$ share must be available and accessible. It is a hidden SMB share that maps to the Windows directory is intended for software deployments. The credentials supplied to the PSExec utility must have permissions to access the Admin$ share.
PSExec has a Windows Service image inside of its executable. It takes this service and deploys it to the Admin$ share on the remote machine. It then uses the DCE/RPC interface over SMB to access the Windows Service Control Manager API. It turns on the PSExec service on the remote machine. The PSExec service then creates a named pipe that can be used to send commands to the system.
A named pipe is just a fancy way of saying “a thing that the server and client can have a conversation over”. When we’re talking about exploitation using SMB, the service that gets uploaded and registered is your foothold on the machine.
An SMB & RPC Example
Here’s a breakdown of how Impacket’s SMBExec works:
[email protected]:/opt/impacket-git$ smbexec.py -debug administrator:"[email protected]"@192.168.1.100 Impacket v0.9.16-dev - Copyright 2002-2016 Core Security Technologies [+] StringBinding ncacn_np:192.168.1.100[\pipe\svcctl] [+] Executing %COMSPEC% /Q /c echo cd ^> \\127.0.0.1\C$\__output 2^>^&1 > %TEMP%\execute.bat & %COMSPEC% /Q /c %TEMP%\execute.bat & del %TEMP%\execute.bat [!] Launching semi-interactive shell - Careful what you execute C:\Windows\system32>whoami [+] Executing %COMSPEC% /Q /c echo whoami ^> \\127.0.0.1\C$\__output 2^>^&1 > %TEMP%\execute.bat & %COMSPEC% /Q /c %TEMP%\execute.bat & del %TEMP%\execute.bat nt authority\system C:\Windows\system32>
Watching this in Wireshark, we see:
- A service named
BTOBTOgets created on our target system, dropping a shiny event 7045 into the Event Log.
- The service gets started which runs our command:
%COMSPEC% /Q /c echo....
- The results of your command are echoed back to the listener along the named pipe.
- The service gets deleted.
If we unpack that ugly %COMSPEC% line, what we see is this:
- Your command, in this case
cd, gets echoed to the __output file stored in the root of C:.
- The contents of __output,
cdare then piped into
execute.batis then run, the results are sent along the named pipe, and
Where SMB gets really good is when it’s combined with NTLM, because unless you enable SMB signing, the client doesn’t verify that the server is actually the server. This is pretty much ideal for man-in-the-middle (MitM) attacks.
Contrast this with Kerberos which was built for sketchy networks full of people trying to MitM its lovelies and bakes in mutual authentication all over the damn place, and NTLM is a shoo-in when you’re planning evil.
So all we need to do is somehow insert ourselves into the middle of an SMB session that’s using NTLM authentication and we have a way to hijack authentication and then execute code. Huzzah!
We know that all domain members running an operating system released since 2000 are going to prefer Kerberos v5 authentication, so how exactly does NTLM enter the picture?
If you’ll recall, Kerberos can’t be used under several conditions:
- Authenticating against a pre-NT 4.0 server
- Accessing a domain resource via IP
- Accessing a resource on a non-domain member
- Accessing a resource on a computer that does not support Kerberos (Windows 3.11, Windows 95, etc.)
So if we can either get a client to authenticate to a system outside of the domain, or authenticate to a domain member using IP instead of hostname, or access system that doesn’t support Kerberos, we’re not going to have to deal with Kerberos and instead will be tangling with NTLM (yay!).
SMB is ubiquitous, allows for remote execution of code using DCE/RPC and can be combined with a Kerberos bypass to gain authenticated remote code execution on a remote machine (more on this later).