[+] AuProcesses::RunAs
This commit is contained in:
parent
662dbac0c1
commit
f404e8960f
@ -14,5 +14,6 @@
|
|||||||
#include "StartupParameters.hpp"
|
#include "StartupParameters.hpp"
|
||||||
#include "Spawn.hpp"
|
#include "Spawn.hpp"
|
||||||
#include "OutputOf.hpp"
|
#include "OutputOf.hpp"
|
||||||
|
#include "RunAs.hpp"
|
||||||
|
|
||||||
#include "Open.hpp"
|
#include "Open.hpp"
|
54
Include/Aurora/Processes/RunAs.hpp
Normal file
54
Include/Aurora/Processes/RunAs.hpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: RunAs.hpp
|
||||||
|
Date: 2023-12-23
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::Processes
|
||||||
|
{
|
||||||
|
AUE_DEFINE(ERunAsUser, (
|
||||||
|
eRegularUser, //
|
||||||
|
eSpecifiedImpersonation, // Privileged impersonation using admin creds and stated alternative uid/username (*)
|
||||||
|
eSuperUser, // Privileged status (root, standard run-as-admin privileges, etc)
|
||||||
|
eNTAS, // NT Authority/SYSTEM (*)
|
||||||
|
eNTTI // Trusted Installer (*)
|
||||||
|
));
|
||||||
|
// (*) These APIs are somewhat spicey
|
||||||
|
|
||||||
|
// Warning: In the default configurations of Windows, spawning processes with shared handles and such as elevated processes is generally not supported.
|
||||||
|
// The Aurora Runtime is importing APIs that'll probably make old anti-virus engines mald after sometime. However, it isn't some magic le epic uac bypass.
|
||||||
|
// You still need to have privileged credentials to hand. This should be noted bc retards on reddit and orange site are probably going to complain
|
||||||
|
// "hurhur this is malware. look, its editing policies and impersonating the UAC logon prompt in process. ooOoOO spooky."
|
||||||
|
// In reality, we're just trying to emulate the behaviour of consent.exe in-process for the likes of:
|
||||||
|
// * non-service level installers with temporary the local-sys-admin-says-its-ok permissions
|
||||||
|
// * remote daemon administration (build-bot daemons with admin credits in a toml file, running as local or network users, perhaps)
|
||||||
|
// * ssh-like servers
|
||||||
|
// * initially not-administrator processes temporarily elevating themselves to remove or re-enable kernel level drivers (drivers such as: reverse engineering tools, vidya gaym anticheats, debuggers, etc)
|
||||||
|
// These APIs will be of use for live-installers where installing for global-users is optional and the base requirements don't require escalation.
|
||||||
|
// Asking for creds in process after a software demo is playable is far nicer UX, than having to wait for 10 hours for Windows to spawn a consent.exe process, just to end up losing stdin/out/err redirection.
|
||||||
|
|
||||||
|
struct RunAsDescriptor
|
||||||
|
{
|
||||||
|
AU_COPY_MOVE_DEF(RunAsDescriptor);
|
||||||
|
|
||||||
|
ERunAsUser runAs = ERunAsUser::eRegularUser;
|
||||||
|
AuOptional<int> numericUserId;
|
||||||
|
AuOptional<AuString> username;
|
||||||
|
AuOptional<AuString> password;
|
||||||
|
AuOptional<AuString> server;
|
||||||
|
AuOptional<AuString> impersonate;
|
||||||
|
AuOptional<int> impersonateNumericUserId;
|
||||||
|
bool bLoginWithProfile {};
|
||||||
|
|
||||||
|
// if this structure is partially completed;
|
||||||
|
// a dialog may be shown if running under a desktop GUI (polkit, credui, etc),
|
||||||
|
// or a command-line based command (AuConsole) may be requested.
|
||||||
|
};
|
||||||
|
|
||||||
|
AUKN_SYM void RunAs(StartupParameters &startupParameters,
|
||||||
|
RunAsDescriptor &runAs); // SECURITY @ Try to enforce moving of AuOptional<AuString> password; to hopefully purge it out of memory asap @
|
||||||
|
} // SECURITY @ Noting that AuOptional<AuString> password isn't memory safe. We should probably try to memset it after use and during move @
|
||||||
|
// REGRESSION: make runAs move-only again
|
@ -81,6 +81,7 @@ namespace Aurora::Processes
|
|||||||
LPCWSTR,
|
LPCWSTR,
|
||||||
LPSTARTUPINFOW,
|
LPSTARTUPINFOW,
|
||||||
LPPROCESS_INFORMATION> ntLikeHookCreateProcessW;
|
LPPROCESS_INFORMATION> ntLikeHookCreateProcessW;
|
||||||
|
AuConsumer<_SECURITY_ATTRIBUTES *> ntFixSharedHandleAttrs;
|
||||||
#else
|
#else
|
||||||
AuSupplierConsumer<int,
|
AuSupplierConsumer<int,
|
||||||
void *,
|
void *,
|
||||||
@ -93,10 +94,14 @@ namespace Aurora::Processes
|
|||||||
void *,
|
void *,
|
||||||
void *,
|
void *,
|
||||||
void *> ntLikeHookCreateProcessW;
|
void *> ntLikeHookCreateProcessW;
|
||||||
|
AuConsumer<void *> ntFixSharedHandleAttrs;
|
||||||
#endif
|
#endif
|
||||||
|
bool bForceNoJobParent {};
|
||||||
#endif
|
#endif
|
||||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||||
AuVoidFunc posixApplySandboxCOW;
|
AuVoidFunc posixApplySandboxCOW;
|
||||||
|
AuVoidFunc posixPCA;
|
||||||
|
AuVoidFunc posixPCB;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -168,6 +168,7 @@ namespace Aurora
|
|||||||
ADD_LOAD_LIB(User32);
|
ADD_LOAD_LIB(User32);
|
||||||
ADD_LOAD_LIB(SetupAPI);
|
ADD_LOAD_LIB(SetupAPI);
|
||||||
ADD_LOAD_LIB(Router);
|
ADD_LOAD_LIB(Router);
|
||||||
|
ADD_LOAD_LIB(CredUI);
|
||||||
|
|
||||||
#define ADD_GET_PROC(name, proc) \
|
#define ADD_GET_PROC(name, proc) \
|
||||||
if (!IsBlocked(#proc)) \
|
if (!IsBlocked(#proc)) \
|
||||||
@ -333,6 +334,30 @@ namespace Aurora
|
|||||||
ADD_GET_PROC(AdvancedApi, SetNamedSecurityInfoW)
|
ADD_GET_PROC(AdvancedApi, SetNamedSecurityInfoW)
|
||||||
ADD_GET_PROC(AdvancedApi, FreeSid)
|
ADD_GET_PROC(AdvancedApi, FreeSid)
|
||||||
|
|
||||||
|
// privilege escalation
|
||||||
|
ADD_GET_PROC(AdvancedApi, CreateProcessWithLogonW);
|
||||||
|
ADD_GET_PROC(AdvancedApi, CreateProcessAsUserW);
|
||||||
|
ADD_GET_PROC(AdvancedApi, AdjustTokenPrivileges);
|
||||||
|
ADD_GET_PROC(AdvancedApi, RevertToSelf);
|
||||||
|
ADD_GET_PROC(AdvancedApi, SetTokenInformation);
|
||||||
|
ADD_GET_PROC(AdvancedApi, GetSidSubAuthorityCount);
|
||||||
|
ADD_GET_PROC(AdvancedApi, GetSidSubAuthority);
|
||||||
|
ADD_GET_PROC(AdvancedApi, LogonUserW);
|
||||||
|
ADD_GET_PROC(AdvancedApi, OpenProcessToken);
|
||||||
|
ADD_GET_PROC(AdvancedApi, SetThreadToken);
|
||||||
|
ADD_GET_PROC(AdvancedApi, SetSecurityInfo);
|
||||||
|
ADD_GET_PROC(AdvancedApi, GetUserNameW);
|
||||||
|
ADD_GET_PROC(AdvancedApi, DuplicateTokenEx);
|
||||||
|
ADD_GET_PROC(AdvancedApi, LookupAccountSidW);
|
||||||
|
ADD_GET_PROC(AdvancedApi, GetTokenInformation);
|
||||||
|
ADD_GET_PROC(AdvancedApi, SetSecurityDescriptorDacl);
|
||||||
|
ADD_GET_PROC(AdvancedApi, InitializeSecurityDescriptor);
|
||||||
|
ADD_GET_PROC(AdvancedApi, LookupAccountNameW);
|
||||||
|
ADD_GET_PROC(AdvancedApi, LookupPrivilegeValueA);
|
||||||
|
ADD_GET_PROC(AdvancedApi, LsaOpenPolicy);
|
||||||
|
ADD_GET_PROC(AdvancedApi, LsaClose);
|
||||||
|
ADD_GET_PROC(AdvancedApi, LsaAddAccountRights);
|
||||||
|
|
||||||
ADD_GET_PROC_INTERNAL_MAP(AdvancedApi, RtlGenRandom, SystemFunction036)
|
ADD_GET_PROC_INTERNAL_MAP(AdvancedApi, RtlGenRandom, SystemFunction036)
|
||||||
|
|
||||||
ADD_GET_PROC(BCrypt, BCryptGenRandom)
|
ADD_GET_PROC(BCrypt, BCryptGenRandom)
|
||||||
@ -373,6 +398,8 @@ namespace Aurora
|
|||||||
ADD_GET_PROC(Router, WNetOpenEnumW);
|
ADD_GET_PROC(Router, WNetOpenEnumW);
|
||||||
ADD_GET_PROC(Router, WNetGetUniversalNameW);
|
ADD_GET_PROC(Router, WNetGetUniversalNameW);
|
||||||
|
|
||||||
|
ADD_GET_PROC(CredUI, CredUIPromptForWindowsCredentialsW);
|
||||||
|
ADD_GET_PROC(CredUI, CredUnPackAuthenticationBufferW);
|
||||||
|
|
||||||
if (pNtCreateKeyedEvent &&
|
if (pNtCreateKeyedEvent &&
|
||||||
Threading::Primitives::gKeyedEventHandle == INVALID_HANDLE_VALUE)
|
Threading::Primitives::gKeyedEventHandle == INVALID_HANDLE_VALUE)
|
||||||
|
@ -23,9 +23,11 @@ struct _SP_DEVINFO_DATA;
|
|||||||
struct _SP_DEVICE_INTERFACE_DATA;
|
struct _SP_DEVICE_INTERFACE_DATA;
|
||||||
struct _SP_DEVICE_INTERFACE_DETAIL_DATA_W;
|
struct _SP_DEVICE_INTERFACE_DETAIL_DATA_W;
|
||||||
struct _NETRESOURCEW;
|
struct _NETRESOURCEW;
|
||||||
|
enum _TOKEN_INFORMATION_CLASS;
|
||||||
enum _SE_OBJECT_TYPE;
|
enum _SE_OBJECT_TYPE;
|
||||||
enum _MINIDUMP_TYPE;
|
enum _MINIDUMP_TYPE;
|
||||||
enum _OBJECT_WAIT_TYPE;
|
enum _OBJECT_WAIT_TYPE;
|
||||||
|
enum _SE_OBJECT_TYPE;
|
||||||
|
|
||||||
//#if defined(AURORA_COMPILER_MSVC)
|
//#if defined(AURORA_COMPILER_MSVC)
|
||||||
struct _IP_ADAPTER_ADDRESSES_LH;
|
struct _IP_ADAPTER_ADDRESSES_LH;
|
||||||
@ -42,6 +44,21 @@ enum _OBJECT_WAIT_TYPE;
|
|||||||
#endif
|
#endif
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef UNICODE_STRING LSA_UNICODE_STRING, *PLSA_UNICODE_STRING;
|
||||||
|
typedef STRING LSA_STRING, *PLSA_STRING;
|
||||||
|
typedef OBJECT_ATTRIBUTES LSA_OBJECT_ATTRIBUTES, *PLSA_OBJECT_ATTRIBUTES;
|
||||||
|
typedef PVOID LSA_HANDLE, *PLSA_HANDLE;
|
||||||
|
|
||||||
|
struct CREDUI_INFOW
|
||||||
|
{
|
||||||
|
DWORD cbSize;
|
||||||
|
HWND hwndParent;
|
||||||
|
PCWSTR pszMessageText;
|
||||||
|
PCWSTR pszCaptionText;
|
||||||
|
HBITMAP hbmBanner;
|
||||||
|
};
|
||||||
|
|
||||||
namespace Aurora
|
namespace Aurora
|
||||||
{
|
{
|
||||||
void InitNTAddresses();
|
void InitNTAddresses();
|
||||||
@ -64,6 +81,7 @@ namespace Aurora
|
|||||||
static const wchar_t *kUser32DllName { L"User32.dll" };
|
static const wchar_t *kUser32DllName { L"User32.dll" };
|
||||||
static const wchar_t *kSetupAPIDllName { L"SETUPAPI.dll" };
|
static const wchar_t *kSetupAPIDllName { L"SETUPAPI.dll" };
|
||||||
static const wchar_t *kRouterDllName { L"MPR.dll" };
|
static const wchar_t *kRouterDllName { L"MPR.dll" };
|
||||||
|
static const wchar_t *kCredUIDllName { L"credui.dll" };
|
||||||
|
|
||||||
struct WIN32_MEMORY_RANGE_ENTRY2
|
struct WIN32_MEMORY_RANGE_ENTRY2
|
||||||
{
|
{
|
||||||
@ -665,6 +683,172 @@ namespace Aurora
|
|||||||
VOID * pSid
|
VOID * pSid
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Advanced API
|
||||||
|
// The proper dodgy APIs that'll probably get us hit by AV-engines
|
||||||
|
// The follow APIs are used for in-process privilege escalation
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pCreateProcessWithLogonW)(
|
||||||
|
LPCWSTR lpUsername,
|
||||||
|
LPCWSTR lpDomain,
|
||||||
|
LPCWSTR lpPassword,
|
||||||
|
DWORD dwLogonFlags,
|
||||||
|
LPCWSTR lpApplicationName,
|
||||||
|
LPWSTR lpCommandLine,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPVOID lpEnvironment,
|
||||||
|
LPCWSTR lpCurrentDirectory,
|
||||||
|
LPSTARTUPINFOW lpStartupInfo,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation
|
||||||
|
);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pCreateProcessAsUserW)(
|
||||||
|
HANDLE hToken,
|
||||||
|
LPCWSTR lpApplicationName,
|
||||||
|
LPWSTR lpCommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
|
BOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPVOID lpEnvironment,
|
||||||
|
LPCWSTR lpCurrentDirectory,
|
||||||
|
LPSTARTUPINFOW lpStartupInfo,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation
|
||||||
|
);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pAdjustTokenPrivileges)(
|
||||||
|
HANDLE TokenHandle,
|
||||||
|
BOOL DisableAllPrivileges,
|
||||||
|
PTOKEN_PRIVILEGES NewState,
|
||||||
|
DWORD BufferLength,
|
||||||
|
PTOKEN_PRIVILEGES PreviousState,
|
||||||
|
PDWORD ReturnLength
|
||||||
|
);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pRevertToSelf)();
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pSetTokenInformation)(
|
||||||
|
HANDLE TokenHandle,
|
||||||
|
_TOKEN_INFORMATION_CLASS TokenInformationClass,
|
||||||
|
LPVOID TokenInformation,
|
||||||
|
DWORD TokenInformationLength
|
||||||
|
);
|
||||||
|
|
||||||
|
inline PUCHAR(__stdcall *pGetSidSubAuthorityCount)(PSID pSid);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pLookupPrivilegeValueA)(
|
||||||
|
LPCSTR lpSystemName,
|
||||||
|
LPCSTR lpName,
|
||||||
|
PLUID lpLuid
|
||||||
|
);
|
||||||
|
|
||||||
|
inline PDWORD(__stdcall *pGetSidSubAuthority)(
|
||||||
|
PSID pSid,
|
||||||
|
DWORD nSubAuthority
|
||||||
|
);
|
||||||
|
|
||||||
|
inline PDWORD(__stdcall *pLogonUserW)(
|
||||||
|
LPCWSTR lpszUsername,
|
||||||
|
LPCWSTR lpszDomain,
|
||||||
|
LPCWSTR lpszPassword,
|
||||||
|
DWORD dwLogonType,
|
||||||
|
DWORD dwLogonProvider,
|
||||||
|
PHANDLE phToken
|
||||||
|
);
|
||||||
|
|
||||||
|
inline PDWORD(__stdcall *pOpenProcessToken)(
|
||||||
|
HANDLE ProcessHandle,
|
||||||
|
DWORD DesiredAccess,
|
||||||
|
PHANDLE TokenHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pSetThreadToken)(
|
||||||
|
PHANDLE Thread,
|
||||||
|
HANDLE Token
|
||||||
|
);
|
||||||
|
|
||||||
|
inline DWORD(__stdcall *pSetSecurityInfo)(
|
||||||
|
HANDLE handle,
|
||||||
|
_SE_OBJECT_TYPE ObjectType,
|
||||||
|
SECURITY_INFORMATION SecurityInfo,
|
||||||
|
PSID psidOwner,
|
||||||
|
PSID psidGroup,
|
||||||
|
PACL pDacl,
|
||||||
|
PACL pSacl
|
||||||
|
);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pGetUserNameW)(
|
||||||
|
LPWSTR lpBuffer,
|
||||||
|
LPDWORD pcbBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pDuplicateTokenEx)(
|
||||||
|
HANDLE hExistingToken,
|
||||||
|
DWORD dwDesiredAccess,
|
||||||
|
LPSECURITY_ATTRIBUTES lpTokenAttributes,
|
||||||
|
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
|
||||||
|
TOKEN_TYPE TokenType,
|
||||||
|
PHANDLE phNewToken
|
||||||
|
);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pLookupAccountSidW)(
|
||||||
|
LPCWSTR lpSystemName,
|
||||||
|
PSID Sid,
|
||||||
|
LPWSTR Name,
|
||||||
|
LPDWORD cchName,
|
||||||
|
LPWSTR ReferencedDomainName,
|
||||||
|
LPDWORD cchReferencedDomainName,
|
||||||
|
PSID_NAME_USE peUse
|
||||||
|
);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pGetTokenInformation)(
|
||||||
|
HANDLE TokenHandle,
|
||||||
|
TOKEN_INFORMATION_CLASS TokenInformationClass,
|
||||||
|
LPVOID TokenInformation,
|
||||||
|
DWORD TokenInformationLength,
|
||||||
|
PDWORD ReturnLength
|
||||||
|
);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pSetSecurityDescriptorDacl)(
|
||||||
|
PSECURITY_DESCRIPTOR pSecurityDescriptor,
|
||||||
|
BOOL bDaclPresent,
|
||||||
|
PACL pDacl,
|
||||||
|
BOOL bDaclDefaulted
|
||||||
|
);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pInitializeSecurityDescriptor)(
|
||||||
|
PSECURITY_DESCRIPTOR pSecurityDescriptor,
|
||||||
|
DWORD dwRevision
|
||||||
|
);
|
||||||
|
|
||||||
|
inline NTSTATUS(__stdcall *pLsaOpenPolicy)(
|
||||||
|
PLSA_UNICODE_STRING SystemName,
|
||||||
|
PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
|
ACCESS_MASK DesiredAccess,
|
||||||
|
PLSA_HANDLE PolicyHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
inline NTSTATUS(__stdcall *pLsaClose)(
|
||||||
|
LSA_HANDLE ObjectHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
inline NTSTATUS(__stdcall *pLsaAddAccountRights)(
|
||||||
|
LSA_HANDLE PolicyHandle,
|
||||||
|
PSID AccountSid,
|
||||||
|
PLSA_UNICODE_STRING UserRights,
|
||||||
|
ULONG CountOfRights
|
||||||
|
);
|
||||||
|
|
||||||
|
inline NTSTATUS(__stdcall *pLookupAccountNameW)(
|
||||||
|
LPCWSTR lpSystemName,
|
||||||
|
LPCWSTR lpAccountName,
|
||||||
|
PSID Sid,
|
||||||
|
LPDWORD cbSid,
|
||||||
|
LPWSTR ReferencedDomainName,
|
||||||
|
LPDWORD cchReferencedDomainName,
|
||||||
|
PSID_NAME_USE peUse
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// USER32 - the shit microsoft will probably try to phase out and remove over time
|
// USER32 - the shit microsoft will probably try to phase out and remove over time
|
||||||
// [then give up and write a win32 emulator in a memelang, probably]
|
// [then give up and write a win32 emulator in a memelang, probably]
|
||||||
|
|
||||||
@ -973,6 +1157,33 @@ namespace Aurora
|
|||||||
LPINT lpAddressLength
|
LPINT lpAddressLength
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// credui
|
||||||
|
|
||||||
|
inline INT(__stdcall *pCredUIPromptForWindowsCredentialsW)(
|
||||||
|
void * pUiInfo,
|
||||||
|
DWORD dwAuthError,
|
||||||
|
ULONG * pulAuthPackage,
|
||||||
|
LPCVOID pvInAuthBuffer,
|
||||||
|
ULONG ulInAuthBufferSize,
|
||||||
|
LPVOID * ppvOutAuthBuffer,
|
||||||
|
ULONG * pulOutAuthBufferSize,
|
||||||
|
BOOL * pfSave,
|
||||||
|
DWORD dwFlags
|
||||||
|
);
|
||||||
|
|
||||||
|
inline BOOL(__stdcall *pCredUnPackAuthenticationBufferW)(
|
||||||
|
DWORD dwFlags,
|
||||||
|
PVOID pAuthBuffer,
|
||||||
|
DWORD cbAuthBuffer,
|
||||||
|
LPWSTR pszUserName,
|
||||||
|
DWORD * pcchMaxUserName,
|
||||||
|
LPWSTR pszDomainName,
|
||||||
|
DWORD * pcchMaxDomainName,
|
||||||
|
LPWSTR pszPassword,
|
||||||
|
DWORD * pcchMaxPassword
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
inline bool gUseNativeWaitMutex {};
|
inline bool gUseNativeWaitMutex {};
|
||||||
inline bool gUseNativeWaitCondvar {};
|
inline bool gUseNativeWaitCondvar {};
|
||||||
inline bool gUseNativeWaitSemapahore {};
|
inline bool gUseNativeWaitSemapahore {};
|
||||||
|
@ -235,6 +235,12 @@ namespace Aurora::Processes
|
|||||||
return WriteFile(this->pipeStdInWrite_, in.ptr, size, &size, NULL) && size == in.length;
|
return WriteFile(this->pipeStdInWrite_, in.ptr, size, &size, NULL) && size == in.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProcessImpl::RestLeakyMem()
|
||||||
|
{
|
||||||
|
AuResetMember(this->startup_.ntLikeHookCreateProcessW);
|
||||||
|
AuResetMember(this->startup_.ntFixSharedHandleAttrs);
|
||||||
|
}
|
||||||
|
|
||||||
bool ProcessImpl::Init()
|
bool ProcessImpl::Init()
|
||||||
{
|
{
|
||||||
SECURITY_ATTRIBUTES saAttr {};
|
SECURITY_ATTRIBUTES saAttr {};
|
||||||
@ -260,6 +266,11 @@ namespace Aurora::Processes
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->startup_.ntFixSharedHandleAttrs)
|
||||||
|
{
|
||||||
|
this->startup_.ntFixSharedHandleAttrs(&saAttr);
|
||||||
|
}
|
||||||
|
|
||||||
this->exitCode_ = 0x10110100;
|
this->exitCode_ = 0x10110100;
|
||||||
if (this->startup_.fwdOut == EStreamForward::eAsyncPipe)
|
if (this->startup_.fwdOut == EStreamForward::eAsyncPipe)
|
||||||
{
|
{
|
||||||
@ -637,8 +648,7 @@ namespace Aurora::Processes
|
|||||||
uCreateFlags |= CREATE_UNICODE_ENVIRONMENT;
|
uCreateFlags |= CREATE_UNICODE_ENVIRONMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL result {};
|
DWORD result;
|
||||||
|
|
||||||
if (auto &func = this->startup_.ntLikeHookCreateProcessW)
|
if (auto &func = this->startup_.ntLikeHookCreateProcessW)
|
||||||
{
|
{
|
||||||
result = func(Locale::ConvertFromUTF8(this->startup_.process).c_str(),
|
result = func(Locale::ConvertFromUTF8(this->startup_.process).c_str(),
|
||||||
@ -667,10 +677,12 @@ namespace Aurora::Processes
|
|||||||
&this->processInfo_);
|
&this->processInfo_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->RestLeakyMem();
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
DWORD wr = GetLastError();
|
DWORD wr = GetLastError();
|
||||||
SysPushErrorGen("CreateProcess failed");
|
SysPushErrorGen("CreateProcess failed: {}", wr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -712,7 +724,8 @@ namespace Aurora::Processes
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->type_ == ESpawnType::eSpawnChildProcessWorker)
|
if (this->type_ == ESpawnType::eSpawnChildProcessWorker &&
|
||||||
|
!this->startup_.bForceNoJobParent)
|
||||||
{
|
{
|
||||||
#if defined(AURORA_PLATFORM_WIN32)
|
#if defined(AURORA_PLATFORM_WIN32)
|
||||||
AssignJobWorker(this->processInfo_.hProcess);
|
AssignJobWorker(this->processInfo_.hProcess);
|
||||||
@ -790,6 +803,7 @@ namespace Aurora::Processes
|
|||||||
|
|
||||||
if (!hi->Init())
|
if (!hi->Init())
|
||||||
{
|
{
|
||||||
|
hi->RestLeakyMem();
|
||||||
delete hi;
|
delete hi;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ namespace Aurora::Processes
|
|||||||
bool Start() override;
|
bool Start() override;
|
||||||
|
|
||||||
bool Init();
|
bool Init();
|
||||||
|
void RestLeakyMem();
|
||||||
void RelOtherHandles();
|
void RelOtherHandles();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
18
Source/Processes/AuProcessElevation.Linux.cpp
Normal file
18
Source/Processes/AuProcessElevation.Linux.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: AuProcessElevation.Linux.cpp
|
||||||
|
Date: 2023-12-26
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#include <Source/RuntimeInternal.hpp>
|
||||||
|
#include "AuProcessElevation.Linux.hpp"
|
||||||
|
|
||||||
|
namespace Aurora::Processes
|
||||||
|
{
|
||||||
|
AUKN_SYM void RunAs(StartupParameters &startupParameters,
|
||||||
|
RunAsDescriptor &runAs)
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
13
Source/Processes/AuProcessElevation.Linux.hpp
Normal file
13
Source/Processes/AuProcessElevation.Linux.hpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: AuProcessElevation.Linux.hpp
|
||||||
|
Date: 2023-12-26
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::Processes
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
997
Source/Processes/AuProcessElevation.NT.cpp
Normal file
997
Source/Processes/AuProcessElevation.NT.cpp
Normal file
@ -0,0 +1,997 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: AuProcessElevation.NT.cpp
|
||||||
|
Date: 2023-12-23
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#include <Source/RuntimeInternal.hpp>
|
||||||
|
#include "AuProcessElevation.NT.hpp"
|
||||||
|
|
||||||
|
#include <tlhelp32.h>
|
||||||
|
|
||||||
|
enum _SE_OBJECT_TYPE
|
||||||
|
{
|
||||||
|
SE_KERNEL_OBJECT = 6
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined(POLICY_ALL_ACCESS)
|
||||||
|
#define POLICY_ALL_ACCESS 0xf0fff
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Aurora::Processes
|
||||||
|
{
|
||||||
|
struct SecureRunAs
|
||||||
|
{
|
||||||
|
RunAsDescriptor desc;
|
||||||
|
AuList<int> pids {};
|
||||||
|
bool bRepeat {};
|
||||||
|
SECURITY_DESCRIPTOR sd {};
|
||||||
|
|
||||||
|
void BlankMemory()
|
||||||
|
{
|
||||||
|
if (this->desc.password)
|
||||||
|
{
|
||||||
|
AuMemset(this->desc.password.value().data(),
|
||||||
|
0,
|
||||||
|
this->desc.password.value().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE GetProcessTokenHandle()
|
||||||
|
{
|
||||||
|
static HANDLE gHandle = INVALID_HANDLE_VALUE;
|
||||||
|
static AuInitOnce gInitOnce;
|
||||||
|
|
||||||
|
if (pOpenProcessToken)
|
||||||
|
{
|
||||||
|
gInitOnce.Call([&]()
|
||||||
|
{
|
||||||
|
pOpenProcessToken(OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()),
|
||||||
|
TOKEN_ALL_ACCESS, &gHandle);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return gHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD GetTokenIntegrityLevel()
|
||||||
|
{
|
||||||
|
char buffer[1000];
|
||||||
|
TOKEN_MANDATORY_LABEL &info = *(TOKEN_MANDATORY_LABEL *)buffer;
|
||||||
|
DWORD dwLength { 1000 };
|
||||||
|
|
||||||
|
if (!pGetTokenInformation ||
|
||||||
|
!pGetSidSubAuthority ||
|
||||||
|
!pGetSidSubAuthorityCount)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pGetTokenInformation(GetProcessTokenHandle(), TokenIntegrityLevel, &info, 1000, &dwLength))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pSid = info.Label.Sid;
|
||||||
|
auto dwIntegrityLevel = *(pGetSidSubAuthority(pSid, (*(pGetSidSubAuthorityCount(pSid)) - 1U)));
|
||||||
|
|
||||||
|
if (dwIntegrityLevel == SECURITY_MANDATORY_LOW_RID)
|
||||||
|
{
|
||||||
|
return dwIntegrityLevel;
|
||||||
|
}
|
||||||
|
else if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID && dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID)
|
||||||
|
{
|
||||||
|
return SECURITY_MANDATORY_MEDIUM_RID;
|
||||||
|
}
|
||||||
|
else if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID)
|
||||||
|
{
|
||||||
|
return SECURITY_MANDATORY_HIGH_RID;
|
||||||
|
}
|
||||||
|
else if (dwIntegrityLevel >= SECURITY_MANDATORY_SYSTEM_RID)
|
||||||
|
{
|
||||||
|
return SECURITY_MANDATORY_SYSTEM_RID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SetTokenIntegrityLevel(HANDLE hToken,
|
||||||
|
DWORD dwIntegrity)
|
||||||
|
{
|
||||||
|
static const BYTE kSidPattern[6] { 0, 0, 0, 0, 0, 16 };
|
||||||
|
TOKEN_MANDATORY_LABEL tokenLabel {};
|
||||||
|
SID_IDENTIFIER_AUTHORITY sidAuth;
|
||||||
|
AuMemcpy(sidAuth.Value, kSidPattern, sizeof(sidAuth.Value));
|
||||||
|
|
||||||
|
if (!pSetTokenInformation ||
|
||||||
|
!pAllocateAndInitializeSid)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSID sid;
|
||||||
|
if (!pAllocateAndInitializeSid(&sidAuth,
|
||||||
|
1,
|
||||||
|
dwIntegrity, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
&sid))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenLabel.Label.Sid = sid;
|
||||||
|
tokenLabel.Label.Attributes = SE_GROUP_INTEGRITY;
|
||||||
|
return pSetTokenInformation(hToken,
|
||||||
|
TokenIntegrityLevel,
|
||||||
|
&tokenLabel,
|
||||||
|
sizeof(TOKEN_MANDATORY_LABEL));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsAdmn()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class EPrompt
|
||||||
|
{
|
||||||
|
eError,
|
||||||
|
eCancel,
|
||||||
|
eOK
|
||||||
|
};
|
||||||
|
|
||||||
|
static EPrompt PromptForCreds(std::wstring &wideusername,
|
||||||
|
std::wstring &widepassword,
|
||||||
|
SecureRunAs *pRunAs,
|
||||||
|
const std::wstring &wideserver)
|
||||||
|
{
|
||||||
|
LPVOID pAuthBuffer;
|
||||||
|
ULONG ulPackageLen {};
|
||||||
|
ULONG ulAuthLen {};
|
||||||
|
bool bSecond {};
|
||||||
|
CREDUI_INFOW info {};
|
||||||
|
|
||||||
|
if (!pCredUnPackAuthenticationBufferW ||
|
||||||
|
!pCredUIPromptForWindowsCredentialsW ||
|
||||||
|
!pCoTaskMemFree)
|
||||||
|
{
|
||||||
|
return EPrompt::eError;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.cbSize = sizeof(info);
|
||||||
|
info.pszCaptionText = L"User Account Control";
|
||||||
|
info.pszMessageText = L"";
|
||||||
|
|
||||||
|
AuString a { "Please log in to elevate the process to " };
|
||||||
|
if (pRunAs->desc.runAs == ERunAsUser::eSpecifiedImpersonation)
|
||||||
|
{
|
||||||
|
if (pRunAs->desc.impersonate)
|
||||||
|
{
|
||||||
|
a += pRunAs->desc.impersonate.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pRunAs->desc.runAs == ERunAsUser::eRegularUser)
|
||||||
|
{
|
||||||
|
if (wideusername.size())
|
||||||
|
{
|
||||||
|
a = fmt::format("Please log in to your account ({})", AuLocale::ConvertFromWChar(wideusername.data()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a = "Please log in to your account";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pRunAs->desc.runAs == ERunAsUser::eSuperUser)
|
||||||
|
{
|
||||||
|
a += "Administrator status";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (pRunAs->desc.runAs)
|
||||||
|
{
|
||||||
|
case ERunAsUser::eNTAS:
|
||||||
|
{
|
||||||
|
a += "NT Authority\\SYSTEM";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERunAsUser::eNTTI:
|
||||||
|
{
|
||||||
|
a += "Trusted Installer";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto tempMessageBuffer = AuLocale::ConvertFromUTF8(a);
|
||||||
|
info.pszMessageText = tempMessageBuffer.data();
|
||||||
|
|
||||||
|
HRESULT result = pCredUIPromptForWindowsCredentialsW(&info,
|
||||||
|
0,
|
||||||
|
&ulPackageLen,
|
||||||
|
{}, 0,
|
||||||
|
&pAuthBuffer, &ulAuthLen,
|
||||||
|
nullptr,
|
||||||
|
0x1);
|
||||||
|
if (result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (result == ERROR_CANCELLED)
|
||||||
|
{
|
||||||
|
return EPrompt::eCancel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return EPrompt::eError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wideusername.resize(512);
|
||||||
|
widepassword.resize(512);
|
||||||
|
DWORD dwUsernameLen = wideusername.size();
|
||||||
|
DWORD dwPasswordLen = widepassword.size();
|
||||||
|
|
||||||
|
bSecond = pCredUnPackAuthenticationBufferW(0,
|
||||||
|
pAuthBuffer, ulAuthLen,
|
||||||
|
wideusername.data(), &dwUsernameLen,
|
||||||
|
nullptr /*TODO: server*/, 0,
|
||||||
|
widepassword.data(), &dwPasswordLen);
|
||||||
|
|
||||||
|
wideusername.resize(dwUsernameLen - 1);
|
||||||
|
widepassword.resize(dwPasswordLen - 1);
|
||||||
|
|
||||||
|
AuMemset(pAuthBuffer, 0, ulAuthLen);
|
||||||
|
pCoTaskMemFree(pAuthBuffer);
|
||||||
|
|
||||||
|
if (result == ERROR_SUCCESS &&
|
||||||
|
bSecond)
|
||||||
|
{
|
||||||
|
return EPrompt::eOK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return EPrompt::eError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::wstring GetUsername()
|
||||||
|
{
|
||||||
|
wchar_t buffer[512];
|
||||||
|
DWORD dwLength = AuArraySize(buffer);
|
||||||
|
|
||||||
|
if (!pGetUserNameW)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pGetUserNameW(buffer, &dwLength))
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return { buffer, dwLength };
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool GetSidOfUser(const std::wstring &username,
|
||||||
|
AuList<AuUInt8> buffer,
|
||||||
|
PSID *ppSid)
|
||||||
|
{
|
||||||
|
static const auto kDefaultSize = 32;
|
||||||
|
buffer.resize(kDefaultSize);
|
||||||
|
bool bOk {};
|
||||||
|
|
||||||
|
if (!pLookupAccountNameW)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!bOk)
|
||||||
|
{
|
||||||
|
SID_NAME_USE eSidType;
|
||||||
|
AuList<wchar_t> dmain;
|
||||||
|
dmain.resize(2024);
|
||||||
|
|
||||||
|
DWORD dw = dmain.size();
|
||||||
|
DWORD cbSid = buffer.size();
|
||||||
|
|
||||||
|
if (pLookupAccountNameW(NULL,
|
||||||
|
username.c_str(),
|
||||||
|
(PSID)buffer.data(),
|
||||||
|
&cbSid,
|
||||||
|
dmain.data(),
|
||||||
|
&dw,
|
||||||
|
&eSidType))
|
||||||
|
{
|
||||||
|
bOk = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dwErrorCode = GetLastError();
|
||||||
|
|
||||||
|
if (dwErrorCode == ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
{
|
||||||
|
buffer.resize(cbSid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bOk)
|
||||||
|
{
|
||||||
|
*ppSid = (PSID)buffer.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
return bOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE GetToken(DWORD pid)
|
||||||
|
{
|
||||||
|
HANDLE hToken;
|
||||||
|
|
||||||
|
auto hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
|
||||||
|
if (!hProcess)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pOpenProcessToken)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pOpenProcessToken(hProcess, MAXIMUM_ALLOWED, &hToken))
|
||||||
|
{
|
||||||
|
hToken = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
|
||||||
|
return hToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GetSelfSID(std::function<void(PSID)> callback)
|
||||||
|
{
|
||||||
|
auto hToken = GetProcessTokenHandle();
|
||||||
|
|
||||||
|
if (!pGetTokenInformation)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD dwSize {};
|
||||||
|
if (!pGetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize) &&
|
||||||
|
GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuList<AuInt8> buf(dwSize, '\x00');
|
||||||
|
auto pTokenUser = (PTOKEN_USER)buf.data();
|
||||||
|
if (!pGetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(pTokenUser->User.Sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetRight(HANDLE hAdmin)
|
||||||
|
{
|
||||||
|
if (!pLsaOpenPolicy ||
|
||||||
|
!pLsaAddAccountRights ||
|
||||||
|
!pLsaClose ||
|
||||||
|
!pRevertToSelf)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pRevertToSelf();
|
||||||
|
|
||||||
|
GetSelfSID([=](PSID pSelf)
|
||||||
|
{
|
||||||
|
if (pSetThreadToken)
|
||||||
|
{
|
||||||
|
pSetThreadToken(NULL, hAdmin);
|
||||||
|
}
|
||||||
|
|
||||||
|
LSA_OBJECT_ATTRIBUTES attr {};
|
||||||
|
LSA_HANDLE hHandle;
|
||||||
|
|
||||||
|
if (pLsaOpenPolicy(NULL, &attr, POLICY_ALL_ACCESS, &hHandle) == 0)
|
||||||
|
{
|
||||||
|
LSA_UNICODE_STRING unistr;
|
||||||
|
unistr.Buffer = (PWSTR)L"SeAssignPrimaryTokenPrivilege";
|
||||||
|
unistr.Length = 29 * 2;
|
||||||
|
unistr.MaximumLength = 29 * 2;
|
||||||
|
|
||||||
|
if (pLsaAddAccountRights(hHandle,
|
||||||
|
pSelf,
|
||||||
|
&unistr,
|
||||||
|
1) == 0)
|
||||||
|
{
|
||||||
|
this->bRepeat = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pLsaClose(hHandle);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static AuString GetProcessUserName(DWORD pid)
|
||||||
|
{
|
||||||
|
AuString username;
|
||||||
|
wchar_t lpName[MAX_PATH];
|
||||||
|
wchar_t lpDomain[MAX_PATH];
|
||||||
|
DWORD dwNameSize { MAX_PATH };
|
||||||
|
DWORD dwDomainSize { MAX_PATH };
|
||||||
|
SID_NAME_USE SidType;
|
||||||
|
|
||||||
|
if (!pLookupAccountSidW ||
|
||||||
|
!pOpenProcessToken ||
|
||||||
|
!pGetTokenInformation)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
|
||||||
|
if (!hProcess)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE hToken {};
|
||||||
|
if (!pOpenProcessToken(hProcess, TOKEN_QUERY, &hToken))
|
||||||
|
{
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD dwSize {};
|
||||||
|
if (!pGetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize) &&
|
||||||
|
GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
{
|
||||||
|
CloseHandle(hToken);
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
AuList<AuInt8> buf(dwSize, '\x00');
|
||||||
|
auto pTokenUser = (PTOKEN_USER)buf.data();
|
||||||
|
if (!pGetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize))
|
||||||
|
{
|
||||||
|
CloseHandle(hToken);
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pLookupAccountSidW(NULL, pTokenUser->User.Sid, lpName, &dwNameSize, lpDomain, &dwDomainSize, &SidType))
|
||||||
|
{
|
||||||
|
CloseHandle(hToken);
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
username = AuLocale::ConvertFromWChar(lpDomain);
|
||||||
|
username += "/";
|
||||||
|
username += AuLocale::ConvertFromWChar(lpName);
|
||||||
|
|
||||||
|
CloseHandle(hToken);
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CachePids()
|
||||||
|
{
|
||||||
|
HANDLE hProcSnap;
|
||||||
|
PROCESSENTRY32 pe32;
|
||||||
|
|
||||||
|
if (this->pids.size())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
|
pe32.dwSize = sizeof(PROCESSENTRY32);
|
||||||
|
|
||||||
|
if (!Process32First(hProcSnap, &pe32))
|
||||||
|
{
|
||||||
|
CloseHandle(hProcSnap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (Process32Next(hProcSnap, &pe32))
|
||||||
|
{
|
||||||
|
if (AuToLower(GetProcessUserName(pe32.th32ProcessID)) == "nt authority/system")
|
||||||
|
{
|
||||||
|
this->pids.push_back(pe32.th32ProcessID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hProcSnap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool EnableTokenPrivilege(HANDLE hToken,
|
||||||
|
const char *lpName)
|
||||||
|
{
|
||||||
|
LUID luidValue { };
|
||||||
|
TOKEN_PRIVILEGES tokenPrivileges;
|
||||||
|
|
||||||
|
if (!pLookupPrivilegeValueA ||
|
||||||
|
!pAdjustTokenPrivileges)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pLookupPrivilegeValueA(NULL,
|
||||||
|
lpName,
|
||||||
|
&luidValue))
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenPrivileges.PrivilegeCount = 1;
|
||||||
|
tokenPrivileges.Privileges[0].Luid = luidValue;
|
||||||
|
tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
return pAdjustTokenPrivileges(hToken,
|
||||||
|
FALSE,
|
||||||
|
&tokenPrivileges,
|
||||||
|
sizeof(tokenPrivileges),
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddGenericElPerms(HANDLE hHandle)
|
||||||
|
{
|
||||||
|
EnableTokenPrivilege(hHandle, SE_DEBUG_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_CREATE_TOKEN_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_INCREASE_QUOTA_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_ASSIGNPRIMARYTOKEN_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_TCB_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_IMPERSONATE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddAllTokenPrivileges(HANDLE hHandle)
|
||||||
|
{
|
||||||
|
EnableTokenPrivilege(hHandle, SE_CREATE_TOKEN_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_ASSIGNPRIMARYTOKEN_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_LOCK_MEMORY_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_INCREASE_QUOTA_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_UNSOLICITED_INPUT_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_MACHINE_ACCOUNT_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_TCB_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_SECURITY_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_TAKE_OWNERSHIP_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_LOAD_DRIVER_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_SYSTEM_PROFILE_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_SYSTEMTIME_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_PROF_SINGLE_PROCESS_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_INC_BASE_PRIORITY_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_CREATE_PAGEFILE_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_CREATE_PERMANENT_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_BACKUP_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_RESTORE_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_SHUTDOWN_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_DEBUG_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_AUDIT_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_SYSTEM_ENVIRONMENT_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_CHANGE_NOTIFY_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_REMOTE_SHUTDOWN_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_UNDOCK_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_SYNC_AGENT_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_ENABLE_DELEGATION_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_MANAGE_VOLUME_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_IMPERSONATE_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_CREATE_GLOBAL_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_TRUSTED_CREDMAN_ACCESS_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_RELABEL_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_INC_WORKING_SET_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_TIME_ZONE_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_CREATE_SYMBOLIC_LINK_NAME);
|
||||||
|
EnableTokenPrivilege(hHandle, SE_DELEGATE_SESSION_USER_IMPERSONATE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TrySpawn(AuFunction<bool(HANDLE)> trySpawn, HANDLE hAdminToken)
|
||||||
|
{
|
||||||
|
CachePids();
|
||||||
|
|
||||||
|
if (!pSetThreadToken ||
|
||||||
|
!pRevertToSelf)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hAdminToken)
|
||||||
|
{
|
||||||
|
AddGenericElPerms(hAdminToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &pid : pids)
|
||||||
|
{
|
||||||
|
HANDLE hToken = GetToken(pid);
|
||||||
|
if (!hToken)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddGenericElPerms(hToken);
|
||||||
|
|
||||||
|
pSetThreadToken(NULL, hToken);
|
||||||
|
|
||||||
|
auto bSuccess = trySpawn(hToken);
|
||||||
|
|
||||||
|
if (hAdminToken)
|
||||||
|
{
|
||||||
|
pSetThreadToken(NULL, hAdminToken);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pRevertToSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hToken);
|
||||||
|
|
||||||
|
if (bSuccess)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool GetCurrentSessionId(DWORD &dwSessionId)
|
||||||
|
{
|
||||||
|
DWORD dwLength {};
|
||||||
|
return pGetTokenInformation &&
|
||||||
|
pGetTokenInformation(GetProcessTokenHandle(),
|
||||||
|
TokenSessionId,
|
||||||
|
&dwSessionId,
|
||||||
|
sizeof(DWORD),
|
||||||
|
&dwLength);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL Exec(LPCWSTR lpApplicationName,
|
||||||
|
LPWSTR lpCommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
|
BOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPVOID lpEnvironment,
|
||||||
|
LPCWSTR lpCurrentDirectory,
|
||||||
|
LPSTARTUPINFOW lpStartupInfo,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation)
|
||||||
|
{
|
||||||
|
DWORD dwSesssionId;
|
||||||
|
GetCurrentSessionId(dwSesssionId);
|
||||||
|
|
||||||
|
std::wstring widepassword;
|
||||||
|
std::wstring wideusername;
|
||||||
|
std::wstring wideserver;
|
||||||
|
DWORD dwResult {};
|
||||||
|
bool bResult {};
|
||||||
|
wchar_t *pWideServer {};
|
||||||
|
bool bRequiresUnprivAuth { true };
|
||||||
|
bool bUseUsualTokenLogin { false };
|
||||||
|
bool bRetToSelf { false };
|
||||||
|
bool bEsclToAdmin { false };
|
||||||
|
bool bDoAdmnTokenLookup { false };
|
||||||
|
bool bIsSpecialAccount { false };
|
||||||
|
bool bPrompting { false };
|
||||||
|
HANDLE hBestToken { INVALID_HANDLE_VALUE };
|
||||||
|
DWORD dwLoginFlags { LOGON_NETCREDENTIALS_ONLY };
|
||||||
|
|
||||||
|
dwCreationFlags |= CREATE_BREAKAWAY_FROM_JOB |
|
||||||
|
CREATE_DEFAULT_ERROR_MODE |
|
||||||
|
CREATE_NEW_CONSOLE |
|
||||||
|
CREATE_NEW_PROCESS_GROUP;
|
||||||
|
|
||||||
|
if (this->desc.bLoginWithProfile)
|
||||||
|
{
|
||||||
|
static wchar_t lpDesktop[] = L"WinSta0\\Default";
|
||||||
|
|
||||||
|
dwLoginFlags = LOGON_WITH_PROFILE;
|
||||||
|
lpStartupInfo->lpDesktop = lpDesktop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (this->desc.username)
|
||||||
|
{
|
||||||
|
wideusername = AuLocale::ConvertFromUTF8(this->desc.username.value().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->desc.password)
|
||||||
|
{
|
||||||
|
widepassword = AuLocale::ConvertFromUTF8(this->desc.password.value().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->desc.server)
|
||||||
|
{
|
||||||
|
wideserver = AuLocale::ConvertFromUTF8(this->desc.server.value().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (widepassword.empty() ||
|
||||||
|
wideusername.empty())
|
||||||
|
{
|
||||||
|
EPrompt status;
|
||||||
|
|
||||||
|
if (wideusername.empty())
|
||||||
|
{
|
||||||
|
wideusername = GetUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
bPrompting = true;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
status = PromptForCreds(wideusername, widepassword, this, wideserver);
|
||||||
|
|
||||||
|
if (status == EPrompt::eCancel)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == EPrompt::eError)
|
||||||
|
{
|
||||||
|
SysPushErrorGeneric("Generic logon prompt failure");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (wideusername.empty() &&
|
||||||
|
status == EPrompt::eOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wideserver.empty() ||
|
||||||
|
wideserver == L"." ||
|
||||||
|
wideserver == L"localhost")
|
||||||
|
{
|
||||||
|
wideserver = L".";
|
||||||
|
pWideServer = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pWideServer = wideserver.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsAdmn())
|
||||||
|
{
|
||||||
|
bRequiresUnprivAuth = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wideusername.empty())
|
||||||
|
{
|
||||||
|
SysPushErrorPermissionError("Missing Username");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bRequiresUnprivAuth)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (!pLogonUserW(wideusername.c_str(),
|
||||||
|
pWideServer,
|
||||||
|
widepassword.c_str(),
|
||||||
|
LOGON32_LOGON_NETWORK_CLEARTEXT,
|
||||||
|
LOGON32_PROVIDER_DEFAULT,
|
||||||
|
&hBestToken))
|
||||||
|
{
|
||||||
|
auto dwErrorCode = GetLastError();
|
||||||
|
|
||||||
|
if (dwErrorCode == 1327)
|
||||||
|
{
|
||||||
|
SysPushErrorPermissionError("You must have a password or modify COMPUTER\\HKLM\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\LimitBlankPasswordUse=1");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dwErrorCode == 1326)
|
||||||
|
{
|
||||||
|
if (bPrompting)
|
||||||
|
{
|
||||||
|
auto status = PromptForCreds(wideusername, widepassword, this, wideserver);
|
||||||
|
|
||||||
|
if (status == EPrompt::eCancel ||
|
||||||
|
wideusername.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == EPrompt::eError)
|
||||||
|
{
|
||||||
|
SysPushErrorGeneric("Generic logon prompt failure");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SysPushErrorPermissionError("Invalid username or password. This event has been logged.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SysPushErrorGeneric("Unable to login");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (this->desc.runAs != ERunAsUser::eRegularUser)
|
||||||
|
{
|
||||||
|
bEsclToAdmin = true;
|
||||||
|
|
||||||
|
if (this->desc.runAs != ERunAsUser::eSuperUser)
|
||||||
|
{
|
||||||
|
bDoAdmnTokenLookup = true;
|
||||||
|
bIsSpecialAccount = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (bPrompting);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bDoAdmnTokenLookup = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bEsclToAdmin)
|
||||||
|
{
|
||||||
|
if (!SetTokenIntegrityLevel(hBestToken,
|
||||||
|
GetTokenIntegrityLevel()))
|
||||||
|
{
|
||||||
|
SysPushErrorPermissionError("Unable to elevate");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSetSecurityInfo((HANDLE)-1,
|
||||||
|
SE_KERNEL_OBJECT,
|
||||||
|
DACL_SECURITY_INFORMATION,
|
||||||
|
{}, {}, {}, {}) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SysPushErrorPermissionError("Unable to elevate");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bRetToSelf = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD dwErrorCode {};
|
||||||
|
if (bIsSpecialAccount)
|
||||||
|
{
|
||||||
|
EnableTokenPrivilege(GetProcessTokenHandle(), SE_DEBUG_NAME);
|
||||||
|
|
||||||
|
CachePids();
|
||||||
|
|
||||||
|
SetRight(hBestToken);
|
||||||
|
|
||||||
|
if (this->bRepeat)
|
||||||
|
{
|
||||||
|
CloseHandle(hBestToken);
|
||||||
|
|
||||||
|
if (!pLogonUserW(wideusername.c_str(),
|
||||||
|
pWideServer,
|
||||||
|
widepassword.c_str(),
|
||||||
|
LOGON32_LOGON_NETWORK_CLEARTEXT,
|
||||||
|
LOGON32_PROVIDER_DEFAULT,
|
||||||
|
&hBestToken))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!SetTokenIntegrityLevel(hBestToken,
|
||||||
|
GetTokenIntegrityLevel()))
|
||||||
|
{
|
||||||
|
SysPushErrorPermissionError("Unable to elevate");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TrySpawn([&](HANDLE h) -> bool
|
||||||
|
{
|
||||||
|
HANDLE hToken2;
|
||||||
|
if (!pDuplicateTokenEx(h,
|
||||||
|
MAXIMUM_ALLOWED,
|
||||||
|
NULL,
|
||||||
|
SecurityImpersonation,
|
||||||
|
TokenPrimary,
|
||||||
|
&hToken2))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)pSetTokenInformation(hToken2, TokenSessionId, &dwSesssionId, sizeof(dwSesssionId));
|
||||||
|
|
||||||
|
pSetThreadToken(NULL, hToken2);
|
||||||
|
AddAllTokenPrivileges(hToken2);
|
||||||
|
|
||||||
|
pSetThreadToken(NULL, hBestToken);
|
||||||
|
bResult = pCreateProcessAsUserW(hToken2,
|
||||||
|
lpApplicationName,
|
||||||
|
lpCommandLine,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
TRUE,
|
||||||
|
dwCreationFlags,
|
||||||
|
lpEnvironment,
|
||||||
|
lpCurrentDirectory,
|
||||||
|
lpStartupInfo,
|
||||||
|
lpProcessInformation);
|
||||||
|
dwErrorCode = GetLastError();
|
||||||
|
CloseHandle(hToken2);
|
||||||
|
return bResult;
|
||||||
|
}, NULL);
|
||||||
|
|
||||||
|
bUseUsualTokenLogin = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (bUseUsualTokenLogin)
|
||||||
|
{
|
||||||
|
// Moved
|
||||||
|
if (!bResult)
|
||||||
|
{
|
||||||
|
SetLastError(dwErrorCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pSetThreadToken(NULL, hBestToken);
|
||||||
|
AddAllTokenPrivileges(hBestToken);
|
||||||
|
bResult = pCreateProcessWithLogonW(wideusername.c_str(),
|
||||||
|
wideserver.data(),
|
||||||
|
widepassword.c_str(),
|
||||||
|
dwLoginFlags,
|
||||||
|
lpApplicationName,
|
||||||
|
lpCommandLine,
|
||||||
|
dwCreationFlags,
|
||||||
|
lpEnvironment,
|
||||||
|
lpCurrentDirectory,
|
||||||
|
lpStartupInfo,
|
||||||
|
lpProcessInformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bRetToSelf)
|
||||||
|
{
|
||||||
|
pRevertToSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
AuWin32CloseHandle(hBestToken);
|
||||||
|
|
||||||
|
if (!bResult)
|
||||||
|
{
|
||||||
|
SysPushErrorGeneric("Couldn't spawn elevated process");
|
||||||
|
}
|
||||||
|
|
||||||
|
return bResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixSharedAttrs(SECURITY_ATTRIBUTES *pAttrs)
|
||||||
|
{
|
||||||
|
if (pInitializeSecurityDescriptor &&
|
||||||
|
pSetSecurityDescriptorDacl)
|
||||||
|
{
|
||||||
|
// let everybody on the system read our shared pipes (the easiest way to fixup inter-privileged ipc)
|
||||||
|
pAttrs->lpSecurityDescriptor = &this->sd;
|
||||||
|
pInitializeSecurityDescriptor(&this->sd, SECURITY_DESCRIPTOR_REVISION);
|
||||||
|
pSetSecurityDescriptorDacl(&this->sd, TRUE, NULL, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AUKN_SYM void RunAs(StartupParameters &startupParameters,
|
||||||
|
RunAsDescriptor &runAs)
|
||||||
|
{
|
||||||
|
auto pThat = AuMakeSharedThrow<SecureRunAs>();
|
||||||
|
pThat->desc = AuMove(runAs);
|
||||||
|
startupParameters.bForceNoJobParent = true;
|
||||||
|
startupParameters.ntLikeHookCreateProcessW = std::bind(&SecureRunAs::Exec, pThat,
|
||||||
|
std::placeholders::_1, std::placeholders::_2,
|
||||||
|
std::placeholders::_3, std::placeholders::_4,
|
||||||
|
std::placeholders::_5, std::placeholders::_6,
|
||||||
|
std::placeholders::_7, std::placeholders::_8,
|
||||||
|
std::placeholders::_9, std::placeholders::_10);
|
||||||
|
startupParameters.ntFixSharedHandleAttrs = std::bind(&SecureRunAs::FixSharedAttrs, pThat,
|
||||||
|
std::placeholders::_1);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
13
Source/Processes/AuProcessElevation.NT.hpp
Normal file
13
Source/Processes/AuProcessElevation.NT.hpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/***
|
||||||
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||||
|
|
||||||
|
File: AuProcessElevation.NT.hpp
|
||||||
|
Date: 2023-12-23
|
||||||
|
Author: Reece
|
||||||
|
***/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::Processes
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user