PostHole
Compose Login
You are browsing eu.zone1 in read-only mode. Log in to participate.
rss-bridge 2024-07-03T17:07:10+00:00

Dumping LSA secrets: a story about task decorrelation

While doing an internal assessment, I was able to compromise multiple computers and servers but wasn’t able to dump the LSA secrets because of a particular EDR being installed and pretty aggressive against me.
In this blog post we’ll see how this EDR was blocking me and why it is still possible to dump these secrets exploiting decorrelation attacks! As a bonus, I’ll show you a fancy way of retrieving the Windows boot key without having to dump the SYSTEM hive.


While doing an internal assessment, I was able to compromise multiple computers and servers but wasn’t able to dump the LSA secrets because of a particular EDR being installed and pretty aggressive against me.

In this blog post we’ll see how this EDR was blocking me and why it is still possible to dump these secrets exploiting decorrelation attacks! As a bonus, I’ll show you a fancy way of retrieving the Windows boot key without having to dump the SYSTEM hive.

I/ How does LSA secrets dumping work

LSA secrets is a specific place in Windows in which secrets are stored. Originally it was used to store cached domain records but was expanded to store all kinds of secrets like, for example, passwords of services running via an Active Directory account (yeah I’m thinking of you MSSQL):

During internal assessments, when you compromise a server, you will want to access these secrets. To do so, you can use one of the many tools out there, for example NetExec:

nxc smb dc.whiteflag.local -u Administrateur -p Defte@WF --lsa

Usually you also dump the SAM database which contains the NT hash of local accounts:

Dumping this information looks simple but under the hood quite a few things happened. First, NetExec had to dump the three following registry hives:

  • HKLM\SAM: contains the NT hashes of the local accounts
  • HKLM\SECURITY: contains the LSA secrets
  • HKLM\SYSTEM: contains information needed to decrypt both the SAM database and the LSA secrets

Taking a look at the code, we can see that NetExec is saving the registry hives to the disk. The interesting code is located in the file nxc/protocols/smb.py:

SECURITYFileName=self.remote_ops.saveSECURITY() calls the secretsdump library from Impacket which is going to save the registry hive into the Temp directory:

Internally, on the Windows host a call to the RegSaveKeyExW WinAPI function will be made:

LSTATUS RegSaveKeyExW(
[in]           HKEY                        hKey,
[in]           LPCWSTR                     lpFile,
[in, optional] const LPSECURITY_ATTRIBUTES lpSecurityAttributes,
[in]           DWORD                       Flags

This will allow saving the key to a file. Note that it is possible to dump the hives using the reg.exe binary, but ultimately it will also call the RegSaveKeyExW function.

II/ From the blueteam perspective

From a blue team perspective, there are quite a few IOCs that could be flagged and blocked when dumping LSA secrets using NetExec:

1. Enabling the Remote Registry service:

2. Connecting to the remote registry via RPC.

3. Saving multiple hives which are sensitive (SAM, SECURITY and SYSTEM). The hives are dumped to files, using an 8 character random string with a terminating .tmp extension in the Temp directory.

4. The files are downloaded remotely.

Correlating this information, EDRs can block LSA secrets dumping. This EDR was able to block me remotely (which is not surprising), but it also prevented me from dumping the LSA secrets locally using the usual reg save commands:

reg save HKLM\SAM SAM
reg save HKLM\Security SECURITY
reg save HKLM\SYSTEM SYSTEM

As far as I understood it, the EDR flagged me in two different ways:

1. It statically flagged the reg save command. When the reg.exe binary was called, the driver probably received a notification and since the argument list contained the keywords “save HKLM\SAM”, it was denied by the EDR. (If you wanna know how an EDR could do this, I wrote a lengthy blog post on how EDRs work and how you can write your own here).

2. It was also able to prevent me from saving the hives even when I hide the command line which means that the access to the HKLM\{SAM, SECURITY, SYSTEM} hives are protected and/or the RegSaveKey function is hooked.

III/ The bypass technique

Interestingly enough, there is one functionality that is not blocked: reg export.

Which means I was able to retrieve the content of the SAM, SECURITY and SYSTEM hives without triggering the EDR. However, reg export results are not like reg save results. Reg export files are text files which contain the registry keys and their values. For example, if we take a look at the export of the SAM hive, we’ll have the following result:

We have the values we are looking for, but if you pass these files to secretsdump, it will crash:

The reason is that secretsdump is expecting a specific file format which you will only get via reg save, a file format that contains the keys and a lot of metadata that reg export results doesn’t provide.

At this point, my idea was simple. If I have got the reg export results in a text format, I can just import them in a Windows VM I own then reg save them and run secretsdump. So I wrote a PowerShell script to do that:

# reg export file results
$files = @(
"z:\HIVETEST\DC\sam.reg",
"z:\HIVETEST\DC\system.reg",
"z:\HIVETEST\DC\security.reg"

# Replacing the HKLM\ to HKCU\HELLO so that I do not overwrite VM's hives
Write-Output "Switching HKLM\ to HKCU\HELLO in .reg files"
foreach ($filePath in $files) {
$content = Get-Content -Path $filePath -Raw -Encoding Unicode
$replacement = [char[]] "HKEY_CURRENT_USER\HELLO" -join ''
$updatedContent = $content -replace "HKEY_LOCAL_MACHINE", $replacement
Set-Content -Path $filePath -Value $updatedContent -Encoding Unicode
Write-Output "`tUpdated file: $filePath"

# Import .reg files in my VM hives
Write-Output "Importing modified .reg files in HKCU\HELLO"
reg import z:\HIVETEST\DC\sam.reg
reg import z:\HIVETEST\DC\system.reg
reg import z:\HIVETEST\DC\security.reg

# Reg save the hives so that I get correctly formatted hive files
Write-Output "Reg saving back to .hive"
reg save HKEY_CURRENT_USER\HELLO\SAM Z:\HIVETEST\DC\SAM.hive
reg save HKEY_CURRENT_USER\HELLO\SECURITY Z:\HIVETEST\DC\SECURITY.hive
reg save HKEY_CURRENT_USER\HELLO\SYSTEM Z:\HIVETEST\DC\SYSTEM.hive

Write-Output "Removing temporary HKCU\HELLO hives"
reg delete HKEY_CURRENT_USER\HELLO /f

Run the script:

And it works, I was able to import the hives into HKCU\HELLO\:

Which means I was able to dump the hives via reg save as well:

And now if I run secretsdump:

It fails… Activating the debug option, we will see that it fails retrieving the boot key:

Taking a look at the code of secretsdump we can see that the getBootKey function’s content is the following:

To compute the boot key, secretsdump queries 4 keys:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\GBG
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Data
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\JD
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Skew1

It then decodes their values, concatenates them into a 32 bit string and permutes the string which, in the end, gives us the boot key. This boot key will then be used to decrypt things stored in the SAM and SECURITY hives which means that we need to get this key.

Looking at the reg export results we can see that we indeed have the keys:

And I naively thought that these were the values used to compute the boot key until I found out, after digging in the secretsdump code that it was not. Indeed, if we take a look again at the getBootKey function we will see that it does not do a getValue() call but a getClass() call:

ans = winreg.getClass('\\%s\\Control\\Lsa\\%s' % (currentControlSet, key))

Question is, how do you get it? Well if you have a reg save result you will have the keys, their values and all the metadata around these keys including the class value. If you have a reg export result, you will only have the key and its value. So it’s kind of a game over… Unless you are able to retrieve these class values all by yourself!

[...]


Original source

Reply