1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-04-24 10:09:49 +02:00

Revert "fix free() process.execute wchars"

This reverts commit be443779ff492b73eac988f77a42f71ece6ff277.
This commit is contained in:
Ashley Donaldson 2023-06-15 08:13:44 +10:00
parent 1ead8a024d
commit 830b4f801a

@ -29,6 +29,12 @@ typedef BOOL (WINAPI* INITIALIZEPROCTHREADATTRIBUTELIST) (
PSIZE_T lpSize PSIZE_T lpSize
); );
typedef struct _STARTUPINFOEXA
{
STARTUPINFOA StartupInfo;
LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
} STARTUPINFOEXA, *LPSTARTUPINFOEXA;
const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000; const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000;
/* /*
@ -114,16 +120,13 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
Tlv inMemoryData; Tlv inMemoryData;
BOOL doInMemory = FALSE; BOOL doInMemory = FALSE;
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
STARTUPINFOW si; STARTUPINFOEXA si;
LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
HANDLE in[2], out[2]; HANDLE in[2], out[2];
PCHAR path, arguments, commandLine = NULL; PCHAR path, arguments, commandLine = NULL;
wchar_t *commandLine_w = NULL;
PCHAR cpDesktop = NULL;
wchar_t *cpDesktop_w = NULL;
DWORD flags = 0, createFlags = 0, ppid = 0; DWORD flags = 0, createFlags = 0, ppid = 0;
BOOL inherit = FALSE; BOOL inherit = FALSE;
HANDLE token, pToken; HANDLE token, pToken;
char * cpDesktop = NULL;
DWORD session = 0; DWORD session = 0;
LPVOID pEnvironment = NULL; LPVOID pEnvironment = NULL;
LPFNCREATEENVIRONMENTBLOCK lpfnCreateEnvironmentBlock = NULL; LPFNCREATEENVIRONMENTBLOCK lpfnCreateEnvironmentBlock = NULL;
@ -135,9 +138,10 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
// Initialize the startup information // Initialize the startup information
memset( &pi, 0, sizeof(PROCESS_INFORMATION) ); memset( &pi, 0, sizeof(PROCESS_INFORMATION) );
memset( &si, 0, sizeof(STARTUPINFOW) ); memset( &si, 0, sizeof(STARTUPINFOEXA) );
si.cb = sizeof(STARTUPINFOW);
lpAttributeList = NULL; si.StartupInfo.cb = sizeof(STARTUPINFO);
si.lpAttributeList = NULL;
// Initialize pipe handles // Initialize pipe handles
in[0] = NULL; in[0] = NULL;
@ -166,26 +170,24 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
} }
if (flags & PROCESS_EXECUTE_FLAG_DESKTOP) if (flags & PROCESS_EXECUTE_FLAG_DESKTOP)
{
do
{ {
cpDesktop = (char *)malloc(512); cpDesktop = (char *)malloc(512);
if (!cpDesktop) if (!cpDesktop)
{
result = ERROR_NOT_ENOUGH_MEMORY;
break; break;
}
memset(cpDesktop, 0, 512); memset(cpDesktop, 0, 512);
met_api->lock.acquire(remote->lock); met_api->lock.acquire(remote->lock);
_snprintf(cpDesktop, 512, "%s\\%s", remote->curr_station_name, remote->curr_desktop_name); _snprintf(cpDesktop, 512, "%s\\%s", remote->curr_station_name, remote->curr_desktop_name);
met_api->lock.release(remote->lock); met_api->lock.release(remote->lock);
if (!(cpDesktop_w = met_api->string.utf8_to_wchar(cpDesktop))) si.StartupInfo.lpDesktop = cpDesktop;
{
result = ERROR_NOT_ENOUGH_MEMORY; } while (0);
break;
}
si.lpDesktop = cpDesktop_w;
} }
// If the remote endpoint provided arguments, combine them with the // If the remote endpoint provided arguments, combine them with the
@ -211,11 +213,6 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
result = ERROR_INVALID_PARAMETER; result = ERROR_INVALID_PARAMETER;
break; break;
} }
if (!(commandLine_w = met_api->string.utf8_to_wchar(commandLine)))
{
result = ERROR_NOT_ENOUGH_MEMORY;
break;
}
// If the channelized flag is set, create a pipe for stdin/stdout/stderr // If the channelized flag is set, create a pipe for stdin/stdout/stderr
// such that input can be directed to and from the remote endpoint // such that input can be directed to and from the remote endpoint
@ -266,10 +263,10 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
} }
// Initialize the startup info to use the pipe handles // Initialize the startup info to use the pipe handles
si.dwFlags |= STARTF_USESTDHANDLES; si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
si.hStdInput = in[0]; si.StartupInfo.hStdInput = in[0];
si.hStdOutput = out[1]; si.StartupInfo.hStdOutput = out[1];
si.hStdError = out[1]; si.StartupInfo.hStdError = out[1];
inherit = TRUE; inherit = TRUE;
createFlags |= CREATE_NEW_CONSOLE; createFlags |= CREATE_NEW_CONSOLE;
@ -285,8 +282,8 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
// If the hidden flag is set, create the process hidden // If the hidden flag is set, create the process hidden
if (flags & PROCESS_EXECUTE_FLAG_HIDDEN) if (flags & PROCESS_EXECUTE_FLAG_HIDDEN)
{ {
si.dwFlags |= STARTF_USESHOWWINDOW; si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE; si.StartupInfo.wShowWindow = SW_HIDE;
createFlags |= CREATE_NO_WINDOW; createFlags |= CREATE_NO_WINDOW;
} }
@ -312,8 +309,8 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
) { ) {
size_t len = 0; size_t len = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &len); InitializeProcThreadAttributeList(NULL, 1, 0, &len);
lpAttributeList = malloc(len); si.lpAttributeList = malloc(len);
if (!InitializeProcThreadAttributeList(lpAttributeList, 1, 0, &len)) { if (!InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &len)) {
printf("[execute] InitializeProcThreadAttributeList: [%d]\n", GetLastError()); printf("[execute] InitializeProcThreadAttributeList: [%d]\n", GetLastError());
result = GetLastError(); result = GetLastError();
break; break;
@ -321,7 +318,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
dprintf("[execute] InitializeProcThreadAttributeList\n"); dprintf("[execute] InitializeProcThreadAttributeList\n");
if (!UpdateProcThreadAttribute(lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &handle, sizeof(HANDLE), 0, 0)) { if (!UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &handle, sizeof(HANDLE), 0, 0)) {
printf("[execute] UpdateProcThreadAttribute: [%d]\n", GetLastError()); printf("[execute] UpdateProcThreadAttribute: [%d]\n", GetLastError());
result = GetLastError(); result = GetLastError();
break; break;
@ -330,6 +327,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
dprintf("[execute] UpdateProcThreadAttribute\n"); dprintf("[execute] UpdateProcThreadAttribute\n");
createFlags |= EXTENDED_STARTUPINFO_PRESENT; createFlags |= EXTENDED_STARTUPINFO_PRESENT;
si.StartupInfo.cb = sizeof(STARTUPINFOEXA);
FreeLibrary(hKernel32Lib); FreeLibrary(hKernel32Lib);
} }
@ -383,10 +381,15 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
} }
// Try to execute the process with duplicated token // Try to execute the process with duplicated token
if (!CreateProcessAsUserW(pToken, NULL, commandLine_w, NULL, NULL, inherit, createFlags, pEnvironment, NULL, &si, &pi)) wchar_t *commandLine_w = met_api->string.utf8_to_wchar(commandLine);
if (!CreateProcessAsUserW(pToken, NULL, commandLine_w, NULL, NULL, inherit, createFlags, pEnvironment, NULL, (LPSTARTUPINFOW)&si, &pi))
{ {
LPCREATEPROCESSWITHTOKENW pCreateProcessWithTokenW = NULL; LPCREATEPROCESSWITHTOKENW pCreateProcessWithTokenW = NULL;
HANDLE hAdvapi32 = NULL; HANDLE hAdvapi32 = NULL;
wchar_t * wcmdline = NULL;
wchar_t * wdesktop = NULL;
size_t size = 0;
free(commandLine_w);
result = GetLastError(); result = GetLastError();
// sf: If we hit an ERROR_PRIVILEGE_NOT_HELD failure we can fall back to CreateProcessWithTokenW but this is only // sf: If we hit an ERROR_PRIVILEGE_NOT_HELD failure we can fall back to CreateProcessWithTokenW but this is only
@ -400,12 +403,35 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
{ {
break; break;
} }
pCreateProcessWithTokenW = (LPCREATEPROCESSWITHTOKENW)GetProcAddress(hAdvapi32, "CreateProcessWithTokenW"); pCreateProcessWithTokenW = (LPCREATEPROCESSWITHTOKENW)GetProcAddress(hAdvapi32, "CreateProcessWithTokenW");
if (!pCreateProcessWithTokenW) if (!pCreateProcessWithTokenW)
{ {
break; break;
} }
if (!pCreateProcessWithTokenW(pToken, LOGON_NETCREDENTIALS_ONLY, NULL, commandLine_w, createFlags, pEnvironment, NULL, &si, &pi))
// convert the multibyte inputs to wide strings (No CreateProcessWithTokenA available unfortunatly)...
size = mbstowcs(NULL, commandLine, 0);
if (size == (size_t)-1)
{
break;
}
wcmdline = (wchar_t *)malloc((size + 1) * sizeof(wchar_t));
mbstowcs(wcmdline, commandLine, size);
if (si.StartupInfo.lpDesktop)
{
size = mbstowcs(NULL, (char *)si.StartupInfo.lpDesktop, 0);
if (size != (size_t)-1)
{
wdesktop = (wchar_t *)malloc((size + 1) * sizeof(wchar_t));
mbstowcs(wdesktop, (char *)si.StartupInfo.lpDesktop, size);
si.StartupInfo.lpDesktop = (LPSTR)wdesktop;
}
}
if (!pCreateProcessWithTokenW(pToken, LOGON_NETCREDENTIALS_ONLY, NULL, wcmdline, createFlags, pEnvironment, NULL, (LPSTARTUPINFOW)&si, &pi))
{ {
result = GetLastError(); result = GetLastError();
dprintf("[execute] failed to create the new process via CreateProcessWithTokenW 0x%.8x", result); dprintf("[execute] failed to create the new process via CreateProcessWithTokenW 0x%.8x", result);
@ -420,6 +446,9 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
{ {
FreeLibrary(hAdvapi32); FreeLibrary(hAdvapi32);
} }
SAFE_FREE(wdesktop);
SAFE_FREE(wcmdline);
} }
else else
{ {
@ -456,8 +485,10 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
if (session_id(GetCurrentProcessId()) == session || !hWtsapi32) if (session_id(GetCurrentProcessId()) == session || !hWtsapi32)
{ {
if (!CreateProcessW(NULL, commandLine_w, NULL, NULL, inherit, createFlags, NULL, NULL, &si, &pi)) wchar_t *commandLine_w = met_api->string.utf8_to_wchar(commandLine);
if (!CreateProcessW(NULL, commandLine_w, NULL, NULL, inherit, createFlags, NULL, NULL, (LPSTARTUPINFOW)&si, &pi))
{ {
free(commandLine_w);
BREAK_ON_ERROR("[PROCESS] execute in self session: CreateProcessW failed"); BREAK_ON_ERROR("[PROCESS] execute in self session: CreateProcessW failed");
} }
} }
@ -473,8 +504,10 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
{ {
BREAK_ON_ERROR("[PROCESS] execute in session: WTSQueryUserToken failed"); BREAK_ON_ERROR("[PROCESS] execute in session: WTSQueryUserToken failed");
} }
if (!CreateProcessAsUserW(hToken, NULL, commandLine_w, NULL, NULL, inherit, createFlags, NULL, NULL, &si, &pi)) wchar_t *commandLine_w = met_api->string.utf8_to_wchar(commandLine);
if (!CreateProcessAsUserW(hToken, NULL, commandLine_w, NULL, NULL, inherit, createFlags, NULL, NULL, (LPSTARTUPINFOW)&si, &pi))
{ {
free(commandLine_w);
BREAK_ON_ERROR("[PROCESS] execute in session: CreateProcessAsUser failed"); BREAK_ON_ERROR("[PROCESS] execute in session: CreateProcessAsUser failed");
} }
} }
@ -501,9 +534,11 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
else else
{ {
// Try to execute the process // Try to execute the process
if (!CreateProcessW(NULL, commandLine_w, NULL, NULL, inherit, createFlags, NULL, NULL, &si, &pi)) wchar_t *commandLine_w = met_api->string.utf8_to_wchar(commandLine);
if (!CreateProcessW(NULL, commandLine_w, NULL, NULL, inherit, createFlags, NULL, NULL, (LPSTARTUPINFOW)&si, &pi))
{ {
result = GetLastError(); result = GetLastError();
free(commandLine_w);
break; break;
} }
} }
@ -574,24 +609,14 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
free(commandLine); free(commandLine);
} }
if (commandLine_w)
{
free(commandLine_w);
}
if (cpDesktop) if (cpDesktop)
{ {
free(cpDesktop); free(cpDesktop);
} }
if (cpDesktop_w) if (si.lpAttributeList)
{ {
free(cpDesktop_w); free(si.lpAttributeList);
}
if (lpAttributeList)
{
free(lpAttributeList);
} }
met_api->packet.transmit_response(result, remote, response); met_api->packet.transmit_response(result, remote, response);