Projects STRLCPY ekko-rs Commits 62040886
🤬
  • Bug fixes (stuck at Waiting for event)

    - Bug 1: CreateTimerQueueTimer's 6th params needed fixing
    - Bug 2: CONTEXT CONTEXT has some alignment and architectural problems in windows-sys/windows-rs
    - Bug 3: CreateTimerQueueTimer's 3rd param needed fixing (RtlCaptureContext and NtContinue) WAITORTIMERCALLBACK type.
    - Bug 4: rop chain needed to be rsp -= 8
    - Bug 5: Advapi32.dll contains SystemFunction032
    - Bug 6: stuck on "waiting for event" but no crashes
  • Loading...
  • memN0ps committed 2 years ago
    62040886
    1 parent d45cb27b
  • ■ ■ ■ ■ ■
    Cargo.toml
    skipped 15 lines
    16 16  log = "0.4.17"
    17 17  #obfstr = "0.4.3"
    18 18  ntapi = "0.4.0"
     19 +winapi = { version = "0.3.9", features = ["synchapi"] }
    19 20   
    20 21  [dependencies.windows-sys]
    21 22  version = "0.45.0"
    skipped 23 lines
  • ■ ■ ■ ■ ■ ■
    src/ekko.rs
    1  -use ntapi::winapi::um::errhandlingapi::GetLastError;
     1 +use ntapi::{winapi::um::errhandlingapi::GetLastError, ntxcapi::NtContinue};
     2 +use winapi::{um::winnt::{CONTEXT, RtlCaptureContext}, shared::ntdef::BOOLEAN};
    2 3  use std::{
    3 4   ffi::c_void,
    4 5   mem::zeroed,
    skipped 2 lines
    7 8  use windows_sys::Win32::{
    8 9   Foundation::{HANDLE, INVALID_HANDLE_VALUE, UNICODE_STRING},
    9 10   System::{
    10  - Diagnostics::Debug::{CONTEXT, IMAGE_NT_HEADERS64},
     11 + Diagnostics::Debug::{IMAGE_NT_HEADERS64},
    11 12   LibraryLoader::{GetModuleHandleA, GetProcAddress, LoadLibraryA},
    12  - Memory::{VirtualProtect, PAGE_EXECUTE_READ, PAGE_PROTECTION_FLAGS, PAGE_READWRITE},
     13 + Memory::{PAGE_EXECUTE_READ, PAGE_PROTECTION_FLAGS, PAGE_READWRITE},
    13 14   SystemServices::IMAGE_DOS_HEADER,
    14 15   Threading::{
    15  - CreateEventW, CreateTimerQueue, CreateTimerQueueTimer, DeleteTimerQueue, SetEvent,
     16 + CreateEventW, CreateTimerQueue, CreateTimerQueueTimer, DeleteTimerQueue,
    16 17   WaitForSingleObject, WT_EXECUTEINTIMERTHREAD,
    17 18   },
    18 19   WindowsProgramming::INFINITE,
    19 20   },
    20 21  };
     22 + 
     23 +pub unsafe extern "system" fn call_rtl_capture_context(param0: *mut c_void, _param1: BOOLEAN) {
     24 + RtlCaptureContext(param0.cast());
     25 +}
     26 + 
     27 +pub unsafe extern "system" fn call_nt_continue(param0: *mut c_void, _param1: BOOLEAN) {
     28 + NtContinue(param0.cast(), 0);
     29 +}
    21 30   
    22 31  pub fn ekko(sleep_time: u32) {
    23 32   // Contains processor-specific register data. The system uses CONTEXT structures to perform various internal operations.
    skipped 33 lines
    57 66   });
    58 67   }
    59 68   
    60  - let nt_continue = unsafe {
     69 + let virtualprotect = unsafe {
    61 70   GetProcAddress(
    62  - GetModuleHandleA("ntdll.dll\0".as_ptr()),
    63  - "NtContinue\0".as_ptr(),
     71 + GetModuleHandleA("kernel32.dll\0".as_ptr()),
     72 + "VirtualProtect\0".as_ptr(),
    64 73   )
    65 74   };
    66 75   
    67  - if nt_continue.is_none() {
    68  - panic!("[!] NtContinue not found");
     76 + if virtualprotect.is_none() {
     77 + panic!("[!] VirtualProtect not found");
    69 78   }
    70 79   
    71  - log::info!("[+] NtContinue: {:#x}", nt_continue.unwrap() as u64);
     80 + log::info!("[+] VirtualProtect: {:#x}", virtualprotect.unwrap() as u64);
     81 + 
    72 82   
    73 83   let sys_func032 = unsafe {
    74 84   GetProcAddress(
    75  - LoadLibraryA("cryptsp.dll\0".as_ptr()),
     85 + LoadLibraryA("Advapi32.dll\0".as_ptr()),
    76 86   "SystemFunction032\0".as_ptr(),
    77 87   )
    78 88   };
    skipped 4 lines
    83 93   
    84 94   log::info!("[+] SystemFunction032: {:#x}", sys_func032.unwrap() as u64);
    85 95   
    86  - let rtlcont = unsafe {
     96 + let setevent = unsafe {
    87 97   GetProcAddress(
    88  - GetModuleHandleA("ntdll.dll\0".as_ptr()),
    89  - "RtlCaptureContext\0".as_ptr(),
     98 + GetModuleHandleA("kernel32.dll\0".as_ptr()),
     99 + "SetEvent\0".as_ptr(),
    90 100   )
    91 101   };
    92 102   
    93  - if rtlcont.is_none() {
    94  - panic!("[!] RtlCaptureContext not found");
     103 + if setevent.is_none() {
     104 + panic!("[!] SetEvent not found");
    95 105   }
    96 106   
    97  - log::info!("[+] RtlCaptureContext: {:#x}", rtlcont.unwrap() as u64);
     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);
    98 121   
    99 122   let image_base = unsafe { GetModuleHandleA(null_mut()) };
    100 123   let dos_header = image_base as *mut IMAGE_DOS_HEADER;
    skipped 11 lines
    112 135   img.Buffer = image_base as *mut u16;
    113 136   img.Length = image_size as u16;
    114 137   img.MaximumLength = image_size as u16;
    115  - pause();
    116 138   
    117 139   log::info!("[+] Calling CreateTimerQueueTimer with ctx_thread");
    118 140   // Creates a timer-queue timer. This timer expires at the specified due time, then after every specified period. When the timer expires, the callback function is called.
    skipped 2 lines
    121 143   CreateTimerQueueTimer(
    122 144   &mut h_new_timer,
    123 145   h_timer_queue,
    124  - std::mem::transmute(rtlcont),
     146 + Some(call_rtl_capture_context),
    125 147   &ctx_thread as *const _ as *const _,
    126 148   0,
    127 149   0,
    skipped 25 lines
    153 175   log::info!("[+] Building ROP chain");
    154 176   // pub unsafe extern "system" fn VirtualProtect(lpaddress: *const c_void, dwsize: usize, flnewprotect: PAGE_PROTECTION_FLAGS, lpfloldprotect: *mut PAGE_PROTECTION_FLAGS) -> BOOL
    155 177   // https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Memory/fn.VirtualProtect.html
    156  - rop_prot_rw.Rsp = -8 as isize as u64;
    157  - rop_prot_rw.Rip = VirtualProtect as u64;
     178 + rop_prot_rw.Rsp -= 8;
     179 + rop_prot_rw.Rip = virtualprotect.unwrap() as u64;
    158 180   rop_prot_rw.Rcx = image_base as u64;
    159 181   rop_prot_rw.Rdx = image_size as u64;
    160 182   rop_prot_rw.R8 = PAGE_READWRITE as u64;
    skipped 2 lines
    163 185   
    164 186   // pub unsafe extern "system" fn SystemFunction036(randombuffer: *mut c_void, randombufferlength: u32) -> BOOLEAN
    165 187   // https://docs.rs/windows-sys/latest/windows_sys/Win32/Security/Authentication/Identity/fn.SystemFunction036.html
    166  - rop_mem_enc.Rsp = -8 as isize as u64;
     188 + rop_mem_enc.Rsp -= 8;
    167 189   rop_mem_enc.Rip = sys_func032.unwrap() as u64;
    168 190   rop_mem_enc.Rcx = &mut img as *mut UNICODE_STRING as *mut c_void as u64;
    169 191   rop_mem_enc.Rdx = key.Length as u64;
    skipped 1 lines
    171 193   
    172 194   // pub unsafe extern "system" fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WIN32_ERROR
    173 195   // https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Threading/fn.WaitForSingleObject.html
    174  - rop_delay.Rsp = -8 as isize as u64;
    175  - rop_delay.Rip = WaitForSingleObject as u64;
     196 + rop_delay.Rsp -= 8;
     197 + rop_delay.Rip = waitforsingleobject.unwrap() as u64;
    176 198   rop_delay.Rcx = -1 as isize as u64; // NtCurrentProcess
    177 199   rop_delay.Rdx = sleep_time as u64;
    178 200   dump_wait_for_single_object_context(&rop_delay);
    179 201   
    180 202   // pub unsafe extern "system" fn SystemFunction036(randombuffer: *mut c_void, randombufferlength: u32) -> BOOLEAN
    181 203   // https://docs.rs/windows-sys/latest/windows_sys/Win32/Security/Authentication/Identity/fn.SystemFunction036.html
    182  - rop_mem_dec.Rsp = -8 as isize as u64;
     204 + rop_mem_dec.Rsp -= 8;
    183 205   rop_mem_dec.Rip = sys_func032.unwrap() as u64;
    184 206   rop_mem_dec.Rcx = &mut img as *mut UNICODE_STRING as *mut c_void as u64;
    185 207   rop_mem_dec.Rdx = key.Length as u64;
    skipped 1 lines
    187 209   
    188 210   // pub unsafe extern "system" fn VirtualProtect(lpaddress: *const c_void, dwsize: usize, flnewprotect: PAGE_PROTECTION_FLAGS, lpfloldprotect: *mut PAGE_PROTECTION_FLAGS) -> BOOL
    189 211   // https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Memory/fn.VirtualProtect.html
    190  - rop_prot_rx.Rsp = -8 as isize as u64;
    191  - rop_prot_rx.Rip = VirtualProtect as u64;
     212 + rop_prot_rx.Rsp -= 8;
     213 + rop_prot_rx.Rip = virtualprotect.unwrap() as u64;
    192 214   rop_prot_rx.Rcx = image_base as u64;
    193 215   rop_prot_rx.Rdx = image_size as u64;
    194 216   rop_prot_rx.R8 = PAGE_EXECUTE_READ as u64;
    skipped 2 lines
    197 219   
    198 220   // https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Threading/fn.SetEvent.html
    199 221   // pub unsafe extern "system" fn SetEvent(hevent: HANDLE) -> BOOL
    200  - rop_set_evt.Rsp = -8 as isize as u64;
    201  - rop_set_evt.Rip = SetEvent as u64;
     222 + rop_set_evt.Rsp -= 8;
     223 + rop_set_evt.Rip = setevent.unwrap() as u64;
    202 224   rop_set_evt.Rcx = h_event as u64;
    203 225   dump_set_event_context(&rop_set_evt);
    204 226   
    skipped 5 lines
    210 232   CreateTimerQueueTimer(
    211 233   &mut h_new_timer,
    212 234   h_timer_queue,
    213  - std::mem::transmute(nt_continue),
     235 + Some(call_nt_continue),
    214 236   &rop_prot_rw as *const _ as *const _,
    215 237   100,
    216 238   0,
    skipped 11 lines
    228 250   CreateTimerQueueTimer(
    229 251   &mut h_new_timer,
    230 252   h_timer_queue,
    231  - std::mem::transmute(nt_continue),
     253 + Some(call_nt_continue),
    232 254   &rop_mem_enc as *const _ as *const _,
    233  - 100,
     255 + 200,
    234 256   0,
    235 257   WT_EXECUTEINTIMERTHREAD,
    236 258   )
    skipped 9 lines
    246 268   CreateTimerQueueTimer(
    247 269   &mut h_new_timer,
    248 270   h_timer_queue,
    249  - std::mem::transmute(nt_continue),
     271 + Some(call_nt_continue),
    250 272   &rop_delay as *const _ as *const _,
    251  - 100,
     273 + 300,
    252 274   0,
    253 275   WT_EXECUTEINTIMERTHREAD,
    254 276   )
    skipped 9 lines
    264 286   CreateTimerQueueTimer(
    265 287   &mut h_new_timer,
    266 288   h_timer_queue,
    267  - std::mem::transmute(nt_continue),
     289 + Some(call_nt_continue),
    268 290   &rop_mem_dec as *const _ as *const _,
    269  - 100,
     291 + 400,
    270 292   0,
    271 293   WT_EXECUTEINTIMERTHREAD,
    272 294   )
    skipped 9 lines
    282 304   CreateTimerQueueTimer(
    283 305   &mut h_new_timer,
    284 306   h_timer_queue,
    285  - std::mem::transmute(nt_continue),
     307 + Some(call_nt_continue),
    286 308   &rop_prot_rx as *const _ as *const _,
    287  - 100,
     309 + 500,
    288 310   0,
    289 311   WT_EXECUTEINTIMERTHREAD,
    290 312   )
    skipped 9 lines
    300 322   CreateTimerQueueTimer(
    301 323   &mut h_new_timer,
    302 324   h_timer_queue,
    303  - std::mem::transmute(nt_continue),
     325 + Some(call_nt_continue),
    304 326   &rop_set_evt as *const _ as *const _,
    305  - 100,
     327 + 600,
    306 328   0,
    307 329   WT_EXECUTEINTIMERTHREAD,
    308 330   )
    skipped 82 lines
Please wait...
Page is in error, reload to recover