myph-v2~ rust shellcode loader with evasive capabilities |
| git clone https://github.com/djnnvx/myph-v2.git |
| log | files | refs | archive | README |
aes_cipher.rs (6056B)
1 use super::Encryptor; 2 use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyIvInit}; 3 use aes::Aes128; 4 use rand::Rng; 5 use sha2::{Digest, Sha256}; 6 7 type Aes128CbcEnc = cbc::Encryptor<Aes128>; 8 #[allow(dead_code)] 9 type Aes128CbcDec = cbc::Decryptor<Aes128>; 10 11 /// AES-128 cipher implementation with CBC mode 12 pub struct AesEncryptor { 13 key: [u8; 16], 14 } 15 16 impl AesEncryptor { 17 /// Creates a new AES encryptor with the given key 18 /// Uses SHA-256 to derive a proper 16-byte key from the input 19 pub fn new(key: &str) -> Self { 20 let mut hasher = Sha256::new(); 21 hasher.update(key.as_bytes()); 22 let hash = hasher.finalize(); 23 24 // Take first 16 bytes of hash for AES-128 25 let mut key_bytes = [0u8; 16]; 26 key_bytes.copy_from_slice(&hash[..16]); 27 28 println!( 29 "[AES] Derived key from input (SHA-256): {:02x?}", 30 &key_bytes[..8] 31 ); 32 33 Self { key: key_bytes } 34 } 35 } 36 37 impl Encryptor for AesEncryptor { 38 fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> { 39 // Generate random IV 40 let mut rng = rand::thread_rng(); 41 let mut iv = [0u8; 16]; 42 rng.fill(&mut iv); 43 44 println!( 45 "[AES] Generated random IV for encryption: {:02x?}", 46 &iv[..8] 47 ); 48 49 let cipher = Aes128CbcEnc::new(&self.key.into(), &iv.into()); 50 let ciphertext = cipher.encrypt_padded_vec_mut::<Pkcs7>(data); 51 52 // Prepend IV to ciphertext 53 let mut result = iv.to_vec(); 54 result.extend_from_slice(&ciphertext); 55 56 Ok(result) 57 } 58 59 fn decrypt(&self, data: &[u8]) -> Result<Vec<u8>, String> { 60 if data.len() < 16 { 61 return Err("Ciphertext too short to contain IV".to_string()); 62 } 63 64 // Extract IV from beginning of data 65 let iv: [u8; 16] = data[..16].try_into().unwrap(); 66 let ciphertext = &data[16..]; 67 68 println!("[AES] Extracted IV for decryption: {:02x?}", &iv[..8]); 69 70 let cipher = Aes128CbcDec::new(&self.key.into(), &iv.into()); 71 cipher 72 .decrypt_padded_vec_mut::<Pkcs7>(ciphertext) 73 .map_err(|e| format!("Decryption error: {:?}", e)) 74 } 75 76 fn key_size(&self) -> usize { 77 16 // AES-128 uses 16-byte keys 78 } 79 80 fn algorithm_name(&self) -> &'static str { 81 "AES-128-CBC" 82 } 83 84 fn uses_iv(&self) -> bool { 85 true 86 } 87 88 fn generate_decrypt_code(&self) -> &'static str { 89 r#"/// Decrypts AES-128 CBC encrypted data using the provided key 90 /// 91 /// Returns `Ok(Vec<u8>)` with decrypted data if successful, otherwise returns an error. 92 pub fn decrypt_aes(data: &[u8], key: &[u8]) -> Result<Vec<u8>, String> { 93 use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, KeyIvInit}; 94 use aes::Aes128; 95 96 if data.len() < 16 { 97 return Err("Ciphertext too short to contain IV".to_string()); 98 } 99 100 if key.len() != 16 { 101 return Err("Key must be 16 bytes for AES-128".to_string()); 102 } 103 104 let iv: [u8; 16] = data[..16].try_into().unwrap(); 105 let ciphertext = &data[16..]; 106 107 let key_array: [u8; 16] = key.try_into().map_err(|_| "Invalid key length".to_string())?; 108 109 type Aes128CbcDec = cbc::Decryptor<Aes128>; 110 let cipher = Aes128CbcDec::new(&key_array.into(), &iv.into()); 111 cipher 112 .decrypt_padded_vec_mut::<Pkcs7>(ciphertext) 113 .map_err(|e| format!("Decryption error: {:?}", e)) 114 }"# 115 } 116 117 fn required_dependencies(&self) -> Vec<(&'static str, &'static str)> { 118 vec![("aes", "0.8"), ("cbc", "0.1")] 119 } 120 } 121 122 #[cfg(test)] 123 mod tests { 124 use super::*; 125 126 #[test] 127 fn test_aes_encrypt_decrypt() { 128 let encryptor = AesEncryptor::new("my-secret-key-123"); 129 let plaintext = b"Hello, World!"; 130 131 let encrypted = encryptor.encrypt(plaintext).unwrap(); 132 assert_ne!(encrypted, plaintext); 133 134 let decrypted = encryptor.decrypt(&encrypted).unwrap(); 135 assert_eq!(decrypted, plaintext); 136 } 137 138 #[test] 139 fn test_aes_different_keys() { 140 let encryptor1 = AesEncryptor::new("key1"); 141 let encryptor2 = AesEncryptor::new("key2"); 142 let plaintext = b"Test data"; 143 144 let encrypted1 = encryptor1.encrypt(plaintext).unwrap(); 145 let encrypted2 = encryptor2.encrypt(plaintext).unwrap(); 146 147 assert_ne!(encrypted1, encrypted2); 148 } 149 150 #[test] 151 fn test_aes_empty_data() { 152 let encryptor = AesEncryptor::new("key"); 153 let empty: &[u8] = &[]; 154 155 let encrypted = encryptor.encrypt(empty).unwrap(); 156 // AES with padding will have at least one block 157 assert!(encrypted.len() >= 16); 158 159 let decrypted = encryptor.decrypt(&encrypted).unwrap(); 160 assert_eq!(decrypted.len(), 0); 161 } 162 163 #[test] 164 fn test_aes_wrong_key_decryption() { 165 let encryptor1 = AesEncryptor::new("correct-key"); 166 let encryptor2 = AesEncryptor::new("wrong-key"); 167 let plaintext = b"Secret message"; 168 169 let encrypted = encryptor1.encrypt(plaintext).unwrap(); 170 let result = encryptor2.decrypt(&encrypted); 171 172 // Decryption with wrong key should fail or produce garbage 173 assert!(result.is_err() || result.unwrap() != plaintext); 174 } 175 176 #[test] 177 fn test_aes_long_data() { 178 let encryptor = AesEncryptor::new("secret-key"); 179 let plaintext = 180 b"This is a much longer message that exceeds the AES block size of 16 bytes"; 181 182 let encrypted = encryptor.encrypt(plaintext).unwrap(); 183 assert_ne!(encrypted, plaintext); 184 185 let decrypted = encryptor.decrypt(&encrypted).unwrap(); 186 assert_eq!(decrypted, plaintext); 187 } 188 189 #[test] 190 fn test_aes_binary_data() { 191 let encryptor = AesEncryptor::new("key"); 192 let plaintext: Vec<u8> = (0..=255).collect(); 193 194 let encrypted = encryptor.encrypt(&plaintext).unwrap(); 195 assert_ne!(encrypted, plaintext); 196 197 let decrypted = encryptor.decrypt(&encrypted).unwrap(); 198 assert_eq!(decrypted, plaintext); 199 } 200 }