Dumping LSASS in 2023

Picture this: You’re hosting a cybersecurity party, guarding your sensitive information like a bouncer at an exclusive club. But lurking in the shadows is a sneaky party crasher named LSASS dumping. In this blog post, we’ll expose this uninvited guest, explore their shenanigans, and equip you with witty cybersecurity practices to kick them out of your system for good.

  • LSASS Dumping: Unmasking the Memory raider LSASS (Local Security Authority Subsystem Service) plays a crucial role in keeping your Windows operating system secure. It holds the keys to the kingdom, housing user credentials and other sensitive data in its memory. LSASS dumping is like a thief swiping that treasure, extracting valuable information from the compromised system.
  • The Consequences of LSASS dumping can have severe implications. Once the party crasher succeeds, they gain access to user credentials, opening the door to unauthorized accounts, network hopping, and potential data breaches. LSASS dumping techniques are evolving fast, so staying informed is crucial.
  • LSASS Dumping Techniques Revealed:
    • Process Dumping: Attackers use tools like Mimikatz, ProcDump, and Dumpert to snapshot the LSASS process and steal its memory.
    • Credential Harvesting: employing malicious software or crafty techniques to snatch plaintext credentials or hashes from LSASS memory, ready to exploit them later.
  • Outsmarting the Gatecrashers:
    • Patching and Updates: Keep systems and software up to date with the latest security patches, making it harder for known LSASS dumping techniques to succeed.
    • Endpoint Protection: Let’s call in the bouncers! Implement robust endpoint protection solutions armed with anti-malware, intrusion detection systems, and behavioral analysis tools to detect and evict LSASS dumpers.
    • Privileged Access Management: Strict access controls are like VIP lists for your system. Limit user privileges and minimize the impact of LSASS dumpers who manage to sneak in.
    • User Education and Awareness: Teach your partygoers the moves! Regularly educate employees on password strength, spotting phishing attempts, and practicing solid cybersecurity habits.
    • Monitoring and Detection: Be the Sherlock Holmes of your system! Set up vigilant monitoring solutions that spot suspicious activity like repeated failed authentication attempts or LSASS behaving strangely.

But Windooze blocks this right?

Sort of… Well it tries.

  1. Windows Defender: Armed with advanced threat detection capabilities LOL… Windows Defender acts as a sentry, constantly scanning for suspicious activities that could indicate an LSASS dumping attempt.
  2. Behavioral Analysis: Windows Defender keeps a watchful eye on LSASS behavior, looking for any deviations from the norm. It leverages behavioral analysis techniques to identify abnormal LSASS activities that might indicate an ongoing dumping attempt. By monitoring LSASS interactions with system processes and memory, Windows Defender can quickly raise the alarm and take preventive measures.
  3. Real-Time Monitoring: Defender operates in real-time, constantly monitoring system activities as they unfold. This allows it to detect LSASS dumping attempts in their early stages, ensuring a rapid response to thwart the attackers. Whether it’s process dumping or credential harvesting, Windows Defender is prepared to intervene, shutting down the unauthorized party before it gains access to your sensitive data.
  4. Signature-Based Detection: Recognizing Known Troublemakers To stay one step ahead, Windows Defender maintains a robust database of signatures associated with known LSASS dumping techniques. When a suspicious file or activity matches a known signature, Windows Defender springs into action, swiftly blocking and neutralizing the threat. Regular updates ensure that Windows Defender is armed with the latest intelligence to fend off even the sneakiest LSASS dumpers.
  5. Enhanced Threat Intelligence: A Collective Defense Windows Defender benefits from Microsoft’s expansive threat intelligence network. Through the power of cloud-based analysis, Windows Defender gains access to real-time information about emerging LSASS dumping techniques, allowing it to proactively identify and mitigate threats. By harnessing the collective knowledge and experience of the cybersecurity community, Windows Defender strengthens its defenses and keeps you one step ahead of the attackers.
  6. Customizable Security Policies: Tailoring Defense to Your Needs Windows Defender provides flexible security policies, allowing you to fine-tune its behavior based on your specific requirements. You can configure it to be more vigilant in monitoring LSASS activities, adjust sensitivity levels for behavioral analysis, and customize response actions. This flexibility empowers you to strike a balance between security and system performance, ensuring a tailored defense against LSASS dumpers

Pass me the tools.

These tools often exploit vulnerabilities or weaknesses in the Windows operating system to extract the LSASS memory. Some commonly known tools that have been used for LSASS dumping include Mimikatz, ProcDump, Dumpert etc.

Mimikatz, for instance, is a well-known open-source tool that was initially created as a legitimate security tool for testing and diagnosing Windows authentication mechanisms. Unfortunately, it has been abused by attackers for malicious purposes, including LSASS dumping. Mimikatz can extract plaintext passwords, hashes, and other sensitive information from the LSASS memory, leveraging various techniques like process injection or hooking.

ProcDump, developed by Microsoft, is a legitimate tool designed for diagnostic purposes. It can be used to create process memory dumps, including the LSASS process, for troubleshooting system issues. However, attackers can misuse ProcDump to create memory snapshots of LSASS and subsequently analyze the dumped memory for extracting valuable information.

Dumpert is another tool that has been known to facilitate the dumping of LSASS memory. It operates by injecting a dynamic link library (DLL) into the LSASS process, which allows it to capture and extract sensitive information from the memory.

As of May 2023 all these tools are detected making it very difficult to actually dump LSASS let alone doing it whist remaining hidden.

A custom solution has got to be the answer?

Custom solutions can indeed provide an advantage by bypassing traditional detection methods that rely on known signatures or behavioral patterns. If a solution is entirely novel and unseen before, it may be challenging for static or heuristic detection techniques to identify it.

What does it take to create a custom solution?


Faced with an issue on excersise tasked with dumping LSASS, all tools are now getting flagged, unable to dump LSASS, the target was Win 11 pro with latest patches and security updates. The box was protected by windows defender. How do we go about making a tool that works?

Firstly we need to understand what happens under the hood with LSASS

When Windows systems start up, LSASS is launched as a system service. It runs in the background and interacts with other system components to perform its security functions. LSASS operates within the context of the Local Security Authority (LSA) subsystem, which manages security policies and authentication processes.

LSASS consists of several key components and data structures:

  1. LSASS Process: LSASS runs as a dedicated process with a unique process identifier (PID). It has its own memory space, which includes executable code, data structures, and dynamically allocated memory.
  2. Security Packages: LSASS interacts with security packages to handle authentication mechanisms. Security packages provide support for various authentication protocols such as NTLM (NT LAN Manager) and Kerberos. These packages are loaded into LSASS’s memory space and are responsible for validating user credentials and establishing secure sessions.
  3. Security Accounts Manager (SAM) Database: LSASS manages the SAM database, which stores user account information, including usernames, password hashes, group memberships, and security policies. The SAM database is a crucial target for attackers seeking to extract sensitive information.
  4. LSA Secrets: LSASS also manages LSA Secrets, which store sensitive data such as passwords and encryption keys used by the operating system and applications. LSA Secrets are typically encrypted and stored securely within LSASS’s memory.

It is worth noting that Microsoft has ‘tried…’ to implement security measures to protect LSASS from unauthorized access and memory manipulation. These measures include Address Space Layout Randomization (ASLR), Data Execution Prevention (DEP), and Credential Guard, which help mitigate the risk of LSASS memory exploitation.

Taking a dump 💩 ?

The MiniDump API Set is a set of Windows APIs that allow developers to create memory dump files, known as minidumps, for a specific process. These minidump files capture a snapshot of the process’s memory, and can be invaluable for debugging purposes, forensic analysis, and security research 😉

The MiniDump API Set provides a range of options to customize the content and level of detail included in the minidump file. This flexibility enables developers and security researchers to focus on specific memory regions of interest.

Here’s a high-level overview of how the MiniDump API Set works:

  1. Obtaining a Handle to the Target Process: To dump the memory of a specific process, including LSASS, the first step is to obtain a handle to that process using the OpenProcess API. This function takes parameters such as the process identifier (PID) and desired access rights to establish a connection with the target process.
  2. Creating the Minidump: Once a handle to the target process is acquired, the MiniDumpWriteDump API is used to create the minidump file. This API requires several parameters, including the handle to the target process, a file handle or file path to save the minidump, and various options to specify the content and format of the dump.
  3. Selecting Dump Type and Content: The MiniDumpWriteDump API allows the selection of different dump types, such as MiniDumpNormal, MiniDumpWithFullMemory, or MiniDumpWithHandleData, depending on the desired level of detail and the specific requirements of the analysis. Additionally, the API provides options to include or exclude specific memory regions, modules, or threads from the minidump.
DWORD lsass_PID = 0;
HANDLE lsass_proc_Handle  = NULL; 
lsass_file = CreateFile(L"lsass.dmp", GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
lsass_proc_Handle = OpenProcess(PROCESS_ALL_ACCESS, 0, lsassPID);
Dumped = MiniDumpWriteDump(lsass_proc_Handle , lsass_PID , outFile, MiniDumpWithFullMemory, NULL, NULL, NULL);
  1. DWORD lsass_PID = 0;: This line declares a variable lsass_PID of type DWORD (Double Word), which will be used to store the process identifier (PID) of the LSASS process.
  2. HANDLE lsass_proc_Handle = NULL;: Here, a variable lsass_proc_Handle of type HANDLE is declared and initialized to NULL. It will be used to store a handle to the LSASS process.
  3. lsass_file = CreateFile(L"lsass.dmp", GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);: This line creates a file named “lsass.dmp” using the CreateFile function. The file will be used to store the minidump. The GENERIC_ALL parameter specifies that the file can be opened with all possible access rights. CREATE_ALWAYS indicates that if the file already exists, it will be overwritten. FILE_ATTRIBUTE_NORMAL sets the file attributes to their default values.
  4. lsass_proc_Handle = OpenProcess(PROCESS_ALL_ACCESS, 0, lsassPID);: The OpenProcess function attempts to open a handle to the LSASS process. It takes the PROCESS_ALL_ACCESS flag as the desired access rights, indicating that the handle will have full access to the process. The lsassPID variable represents the process identifier (PID) of the LSASS process, allowing the function to target the correct process.
  5. Dumped = MiniDumpWriteDump(lsass_proc_Handle, lsass_PID, outFile, MiniDumpWithFullMemory, NULL, NULL, NULL);: This line invokes the MiniDumpWriteDump function to create the minidump file. It takes several parameters:
    • lsass_proc_Handle: The handle to the LSASS process obtained in step 4.
    • lsass_PID: The process identifier (PID) of the LSASS process.
    • outFile: The file handle or file path specifying where the minidump file will be written.
    • MiniDumpWithFullMemory: This parameter specifies the type of minidump to create. In this case, MiniDumpWithFullMemory indicates that the dump should include the full memory contents of the LSASS process.
    • The remaining three parameters (NULL, NULL, NULL) are optional and set to NULL in this example.

These are the core functions required to dump LSASS, lets put it into a script…

#include <windows.h>
#include <stdio.h>
#include <Dbghelp.h>

#pragma comment(lib, "Dbghelp.lib")

int main(int argc, char* argv[]) {
    DWORD pid;
    HANDLE hProcess;
    MINIDUMP_EXCEPTION_INFORMATION exceptionParam;
    BOOL ret;

    if (argc != 2) {
        printf("Usage: memdump <pid>\n");
        return 1;
    }

    pid = atoi(argv[1]);
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);

    if (hProcess == NULL) {
        printf("Could not open process %d: %d\n", pid, GetLastError());
        return 1;
    }

    HANDLE hFile = CreateFile("memdump.dmp", GENERIC_READ | GENERIC_WRITE, 
        0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if(hFile == INVALID_HANDLE_VALUE) {
        printf("Failed to create dump file: %d\n", GetLastError());
        return 1;
    }

    exceptionParam.ThreadId = GetCurrentThreadId();
    exceptionParam.ExceptionPointers = NULL;
    exceptionParam.ClientPointers = FALSE;

    ret = MiniDumpWriteDump(hProcess, pid, hFile, MiniDumpWithFullMemory, &exceptionParam, NULL, NULL);
    
    if (!ret) {
        printf("MiniDumpWriteDump failed: %d\n", GetLastError());
        return 1;
    }

    printf("Memory dump written to memdump.dmp\n");

    CloseHandle(hFile);
    CloseHandle(hProcess);

    return 0;
}

This program is designed to create a memory dump of a target process specified by its PID. It is specifically designed to remain undetected by Windows because it does not perform any malicious activities…

So what happens if we use it to dump LSASS?

it throws error code = 5 this appears when the user does not have sufficient permission to access the requested file, location or resource.

So lets elevate to admin and try again?

it throws error code = 5 this appears when the user does not have sufficient permission to access the requested file, location or resource.

What about nt autority /system?

It works, it actually just dumped LSASS! Unfortunatly windows recognises the memory dump file it created and snatches it back off us 🙁

So what have we learnt so far?

  • We must be running as system? but why?
  • It is still possible to create a program that will dump LSASS without being detected.
  • The actuall output dump file for the LSASS process is detected.

SYSTEM but why?

Lets first check the difference in privilege between admin and system

ADMIN
SYSTEM

System has great powers….

By default, users can debug only processes that they own.

SeDebugPrivilege, also known as the “Debug Programs” privilege, is a security privilege in the Windows operating system that grants a user or process the ability to debug and monitor other processes on the system. This privilege provides elevated access rights and allows the user or process to bypass certain security restrictions that would otherwise prevent debugging activities.

When a user or process is granted the SeDebugPrivilege, it gains additional permissions beyond what a standard user or process would have. These permissions include the ability to:

  1. Attach a debugger to running processes: With SeDebugPrivilege, a user or process can attach a debugger to another process and monitor its execution, inspect memory, set breakpoints, and trace program execution.
  2. Access and modify memory of other processes: SeDebugPrivilege allows reading and writing to the memory space of other processes, including sensitive areas that are typically protected.
  3. Control thread execution: This privilege enables a user or process to suspend, resume, and manipulate the threads of other processes, potentially altering their behavior.
  4. Obtain additional information about processes: With SeDebugPrivilege, a user or process can access detailed information about other processes, including their handles, security attributes, and module information.

How can we have the power of system without being system?

One of two ways… Abusing Token Privileges, or some sort of LOLBIN

  • Abusing Token Privileges – easily detected, but effective, if we set SeDebugPrivilege we have all the powers… But we leave behind a path that is easily followed.
  • Lolbin? How about powershell… By default powershell as admin has this SeDebugPrivilege enabled. Lets not ask why, i guess its in the name “PowerShell”
Powershell as ADMIN

The final boss.

So that only leaves us with one final problem The actuall output dump file for the LSASS process being detected when it hits the disk.

Easy right? you just have to execute in memory, encode the output before writing to the file?
Whist sort of correct, MiniDumpWriteDump has some complications when it comes to not touching disk.


The MiniDumpWriteDump function is designed to write the memory dump to a file, not directly to memory. It takes a file handle or a file path as one of its parameters to specify where the minidump file should be written.

Lets take an alternative approach and try to modify the behavior of the MiniDumpWriteDump function. This might involve using additional programming techniques to manage memory buffers and storing the dump data within those buffers rather than writing it to a file directly.

Lets take another look at the MiniDumpWriteDump function.

[in] CallbackParam A pointer to MINIDUMP_CALLBACK_INFORMATION structure that specifies a callback routine which is to receive extended minidump information. If the value of this parameter is NULL, no callbacks are performed.

https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/nf-minidumpapiset-minidumpwritedump

The PMINIDUMP_CALLBACK_INFORMATION parameter in the MiniDumpWriteDump function is used to specify a callback function that can be invoked during the minidump generation process. It allows you to provide additional custom handling or processing logic while the minidump is being created.

The purpose of the callback function is to allow you to intercept and handle specific events or operations during the minidump creation. For example, you can use the callback to filter or modify the data being included in the minidump, provide progress updates, or perform additional actions related to the minidump generation process.

Within the callback function, you can access the relevant information about the progress and state of the minidump generation through the provided parameters. These parameters include the callback type, the current operation being performed, and any associated data or context.

Lets make a function that does this.

In high-level terms, the minidumpCallback function is a callback function used during the minidump creation process. It is called at different stages of the process to handle specific events or operations. In this case, the function is responsible for copying the minidump data into a buffer called dumpBuffer and tracking the number of bytes read from the minidump.

At a low-level, here’s a breakdown of how the minidumpCallback function and the dumpBuffer work:

  1. minidumpCallback Function:
    • The minidumpCallback function is defined with the required parameters (callbackParam, callbackInput, and callbackOutput) as specified by the MINIDUMP_CALLBACK_ROUTINE type.
    • The function receives input information through the callbackInput parameter, which contains details about the current callback event, such as the callback type (callbackInput->CallbackType) and the minidump data to be processed.
    • The callbackOutput parameter is used to provide output information, including the status of the callback operation (callbackOutput->Status).
    • Inside the function, a switch statement is used to handle different callback types. In this case, it specifically handles the IoWriteAllCallback type.
    • For IoWriteAllCallback, the function extracts the minidump data (callbackInput->Io.Buffer) and its size (callbackInput->Io.BufferBytes).
    • The function calculates the destination location in the dumpBuffer by adding the offset of the minidump data to the base address of the buffer.
    • Using RtlCopyMemory, the function then copies the minidump data from the source to the destination in the dumpBuffer.
    • It also updates the bytesRead variable to keep track of the number of bytes read from the minidump.
    • Additionally, the function can perform any necessary processing or actions related to the minidump data, such as logging, analyzing, or manipulating it.
    • Finally, the function returns TRUE to indicate successful execution.
  2. dumpBuffer:
    • The dumpBuffer is a buffer allocated using HeapAlloc that serves as a memory storage area to hold the minidump data.
    • The HEAP_ZERO_MEMORY flag ensures that the buffer is initially filled with zeros.
    • The size of the buffer is specified as 1024 * 1024 * 75, which represents 75 megabytes of memory.
    • The dumpBuffer is used to store the minidump data during the IoWriteAllCallback event in the minidumpCallback function.
    • After the minidump creation process, the dumpBuffer contains the LSASS memory dump that can be further processed or analyzed.

Can we write it to disk yet?

No, writing the minidump to disk at this point would still be detectable, as it would resemble the traditional approach. However, by leveraging the callback function and obtaining the minidump data as a stream instead of writing it directly to disk, we gain the ability to manipulate and encode the data before storing it. This allows us to add an extra layer of obfuscation and make it harder for traditional scanning techniques to identify and analyze the dumped data. By encoding the data before writing it to disk, we can enhance its stealthiness and further evade detection mechanisms.

Armed with prior knowledge of how easily it is to hide from defender, I chose to skip complex algorithms and intricate encoding methods. Instead, I opted for a simple XOR cipher.

In simple terms, an XOR cipher is a method of encrypting or encoding data using a bitwise operation called XOR (exclusive OR). XOR takes two binary values and compares them bit by bit. If the bits are the same, the result is 0. If the bits are different, the result is 1.

To apply an XOR cipher, we take the original data and XOR it with a secret key. The secret key is a binary value used as a pattern for the XOR operation. By performing this XOR operation, the data gets transformed into a new encrypted form.

When someone wants to decrypt the data, they perform the XOR operation again using the same secret key. XORing the encrypted data with the secret key reverses the encryption process and reveals the original data.

The XOR cipher is considered simple because it involves straightforward operations and doesn’t require complex mathematical computations. However, it’s important to note that XOR encryption alone may not provide strong security. It is often used as a basic building block within more advanced encryption algorithms to enhance their security and complexity.

    if (isDumped)
    {
        printf("\n[+] lsass dumped into memory 0x%p\n", dumpBuffer);
        HANDLE outFile = CreateFile(L"memdump.dmp", GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

        BYTE key = 0xAB; // You can change this key to anything you want
        BYTE* encryptedDumpBuffer = new BYTE[bytesRead];
        BYTE* byteDumpBuffer = static_cast<BYTE*>(dumpBuffer);

        for (DWORD i = 0; i < bytesRead; i++)
        {
            encryptedDumpBuffer[i] = byteDumpBuffer[i] ^ key;
        }

        if (WriteFile(outFile, encryptedDumpBuffer, bytesRead, &bytesWritten, NULL))
        {
            printf("\n[+] lsass dumped from 0x%p to memdump.dmp\n", dumpBuffer, bytesWritten);
            printf("[+] ph0tonz\n");
        }

        delete[] encryptedDumpBuffer; // free the memory after using it
    }

Lets located lsass and try and dump it to disk with out simple cipher.

We then pass this pid as an argument to the tool we created in a admin powershell prompt memdump.exe 608

Excellent, thats lsass dumped to disk, defender doesnt batt an eyelid, its still sleeping.

Decrypting

We now need a method of decrypting the xor ciphered memorydump. Its as simple as a couple lines of python

key = 0xAB  # Same key used for encryption

# Open the encrypted file and read the contents
with open('memdump.dmp', 'rb') as encrypted_file:
    encrypted_data = encrypted_file.read()

# Perform XOR operation to each byte in the data
decrypted_data = bytes([b ^ key for b in encrypted_data])

# Write the decrypted data to a new file
with open('lsass_decrypted.dmp', 'wb') as decrypted_file:
    decrypted_file.write(decrypted_data)


We now have a decrypted lsass dump that we can use with automated tools such as pypykatz

PyPykatz leverages the power of Python to interface with the LSASS process and perform various operations, including credential extraction, mimikatz-like functionality, and password cracking. It provides an abstraction layer for interacting with the Windows LSASS process, making it easier to access and analyze sensitive information stored in memory.

pypykatz lsa minidump lsass_decrypted.dmp

Booom, keys to the kingdom.

The complete source code for this tool will be released on github 07/06/2023
https://github.com/warren2i/memdump