Over the last few days, I have been playing with WinScanX, a free command-line tool for querying Windows service information over SMB. WinScanX combines many of the essential tools used during a penetration test into a single utility. One of the more interesting features is the "-y" flag, which instructs WinScanX to save a copy of the remote registry hives for SAM, SECURITY, and SYSTEM. These three hives can be used in conjunction with Cain and Abel or creddump to dump the LANMAN/NTLM hashes, view cached credentials, and decrypt LSA secrets. All very useful pieces of data for a penetration test.
The traditional way to obtain this information is by injecting a thread into the LSASS.exe process, calling various undocumented Windows APIs, and exporting the decrypted data back out. The problem with this method is that process injection is not necessarily reliable, especially when third-party security products interfere with the injection code. Any crash in the LSASS.exe process will force the OS to halt or reboot, which is far from stealthy and generally not what you want have happen to a client's domain controller during a penetration test. The injection method is implemented by pwdump, fgcache, cachedump, and the "hashdump" command in the Metasploit Meterpreter payload.
Since imitation is the sincerest form of flattery, I looked into how WinScanX implemented the registry hive export. Using the Remote Registry service over SMB/DCERPC, WinScanX calls the Save function, instructing the service to write an exported copy of the hive to the file system. WinScanX then downloads the hive using the ADMIN$ SMB share. This is a clean way to obtain the hive data, but newer versions of Windows disable the Remote Registry service by default, requiring the user to first enable it, then dump the hive, then disable it again. I would not be surprised if future versions of WinScanX implement this method.
In the context of Metasploit, we have the advantage of direct code execution on the target system, either through an exploit, or using psexec and a valid set of credentials. Instead of going through the Remote Registry service, it might be easier to run a local command in order to grab the registry hive. The command of choice for this is "reg.exe", included with Windows XP and all newer versions of the Windows operating system (missing from NT 4.0 and Windows 2000, but available as a separate download from Microsoft).
The "reg EXPORT" command can be used to take a copy of a specific piece of the registry; the EXPORT option generates human-readable output files that are easy to parse and can be imported into a new system for testing. Metasploit already uses "reg EXPORT" in various Meterpreter scripts, including "scraper.rb" and "winenum.rb". For capturing the HKLM\SYSTEM and HKLM\SAM hives, the EXPORT command works just fine, albeit the output files can get enormous. Trying to EXPORT the HKLM\SECURITY key (as Administrator), however, results in the following error:
C:\>reg EXPORT HKLM\SECURITY security.reg ERROR: Access is denied.
The SECURITY tree is required to dump cached credentials and LSA secrets (but not password hashes) and without it, we would be missing two important pieces of data. Going back to WinScanX, we see that it uses the Save function, and reg.exe offers a SAVE command, lets try that instead of EXPORT:
C:\>reg SAVE HKLM\SECURITY security.hive The operation completed successfully.
Hoorah! Even though the Administrator user does not have permission to read the HKLM\SECURITY key, reg.exe bypasses this restriction through the SAVE command. WinScanX uses the Save function call in the Remote Registry service, which likely calls the same backend function as reg.exe in this case. It looks like we have an easy way to grab the SECURITY hive from the command-line. This doesn't turn out to be quite the case, since this behavior changes depending on the version of Windows.
Edi Strosar came up with the following table based on his testing:
Windows 2000 SP4 (admin) = access denied Windows XP SP2 (admin) = access denied Windows XP SP3 (admin) = access denied Windows 2003 R2 SP2 (admin) = works Windows Vista SP2 (UAC/admin) = works Windows 2008 SP1 (admin) = works Windows 7 (UAC/admin) = works
This is an odd case of older versions of Windows actually having tighter restrictions than newer ones. Even though Windows 2000/XP don't exhibit this behavior, these platforms have the Remote Registry service enabled by default, so WinScanX can be used to grab the SECURITY hive anyways.
Keep in mind that using the raw hive file requires a tool that understands the raw registry format (Cain and Abel / creddump). In order for Metasploit to have support for cached credentials and LSA secrets, we will need to implement a registry parser in Ruby (creddump may be a good reference implementation). In the short-term, we can reimplement Meterpreter's "hashdump" to be purely registry-based. This will require SYSKEY code to be implemented, but this should be immediately feasible based on public documentation and the Ruby OpenSSL extension.
Thanks to Edi Strosar, Carlos Perez, and Mario Vilas for their feedback on the reg.exe SAVE issue.