myph-v2~ rust shellcode loader with evasive capabilities |
| git clone https://github.com/djnnvx/myph-v2.git |
| log | files | refs | archive | README |
capabilities.rs (14144B)
1 use std::collections::HashSet; 2 3 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 4 pub enum Capability { 5 RequiresAdmin, 6 SupportsRemoteProcess, 7 SupportsDynamicResolver, 8 SupportsAMSIPatch, 9 RequiresNtdll, 10 LocalExecutionOnly, 11 RequiresProcessInjection, 12 } 13 14 impl Capability { 15 pub fn description(&self) -> &'static str { 16 match self { 17 Capability::RequiresAdmin => "Requires administrator privileges to execute", 18 Capability::SupportsRemoteProcess => "Supports injection into remote process", 19 Capability::SupportsDynamicResolver => "Supports dynamic function resolution", 20 Capability::SupportsAMSIPatch => "Compatible with AMSI patching", 21 Capability::RequiresNtdll => "Requires ntdll.dll functions", 22 Capability::LocalExecutionOnly => "Executes shellcode locally (no process injection)", 23 Capability::RequiresProcessInjection => { 24 "Requires target process for shellcode injection" 25 } 26 } 27 } 28 } 29 30 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] 31 pub enum DetectionDifficulty { 32 Low, 33 Medium, 34 MediumHigh, 35 High, 36 VeryHigh, 37 } 38 39 impl DetectionDifficulty { 40 pub fn as_str(&self) -> &'static str { 41 match self { 42 DetectionDifficulty::Low => "Low", 43 DetectionDifficulty::Medium => "Medium", 44 DetectionDifficulty::MediumHigh => "Medium-High", 45 DetectionDifficulty::High => "High", 46 DetectionDifficulty::VeryHigh => "Very High", 47 } 48 } 49 } 50 51 #[derive(Debug, Clone)] 52 pub struct TechniqueMetadata { 53 pub name: &'static str, 54 pub capabilities: HashSet<Capability>, 55 pub detection_difficulty: DetectionDifficulty, 56 pub description: &'static str, 57 } 58 59 impl TechniqueMetadata { 60 pub fn has_capability(&self, cap: Capability) -> bool { 61 self.capabilities.contains(&cap) 62 } 63 64 pub fn requires_process(&self) -> bool { 65 self.has_capability(Capability::RequiresProcessInjection) 66 } 67 68 pub fn supports_dynamic_resolver(&self) -> bool { 69 self.has_capability(Capability::SupportsDynamicResolver) 70 } 71 } 72 73 pub fn get_technique_metadata(technique_name: &str) -> Option<TechniqueMetadata> { 74 get_technique_registry().iter().find_map(|meta| { 75 if meta.name.eq_ignore_ascii_case(technique_name) { 76 Some(meta.clone()) 77 } else { 78 None 79 } 80 }) 81 } 82 83 pub fn list_all_techniques() -> Vec<TechniqueMetadata> { 84 get_technique_registry() 85 } 86 87 fn get_technique_registry() -> Vec<TechniqueMetadata> { 88 vec![ 89 TechniqueMetadata { 90 name: "crt", 91 capabilities: [ 92 Capability::SupportsRemoteProcess, 93 Capability::SupportsDynamicResolver, 94 Capability::SupportsAMSIPatch, 95 Capability::RequiresProcessInjection, 96 ] 97 .iter() 98 .copied() 99 .collect(), 100 detection_difficulty: DetectionDifficulty::Medium, 101 description: "CreateRemoteThread - Classic remote thread injection", 102 }, 103 TechniqueMetadata { 104 name: "crtx", 105 capabilities: [ 106 Capability::SupportsRemoteProcess, 107 Capability::SupportsDynamicResolver, 108 Capability::SupportsAMSIPatch, 109 Capability::RequiresProcessInjection, 110 ] 111 .iter() 112 .copied() 113 .collect(), 114 detection_difficulty: DetectionDifficulty::Medium, 115 description: "CreateRemoteThreadEx - Extended remote thread injection", 116 }, 117 TechniqueMetadata { 118 name: "create-fiber", 119 capabilities: [ 120 Capability::LocalExecutionOnly, 121 Capability::SupportsDynamicResolver, 122 Capability::SupportsAMSIPatch, 123 ] 124 .iter() 125 .copied() 126 .collect(), 127 detection_difficulty: DetectionDifficulty::MediumHigh, 128 description: "CreateFiber - Fiber-based local execution", 129 }, 130 TechniqueMetadata { 131 name: "process-hollowing", 132 capabilities: [ 133 Capability::SupportsRemoteProcess, 134 Capability::SupportsDynamicResolver, 135 Capability::SupportsAMSIPatch, 136 Capability::RequiresNtdll, 137 Capability::RequiresProcessInjection, 138 ] 139 .iter() 140 .copied() 141 .collect(), 142 detection_difficulty: DetectionDifficulty::High, 143 description: "Process Hollowing - Memory replacement technique", 144 }, 145 TechniqueMetadata { 146 name: "nt-create-thread-ex", 147 capabilities: [ 148 Capability::SupportsRemoteProcess, 149 Capability::SupportsDynamicResolver, 150 Capability::SupportsAMSIPatch, 151 Capability::RequiresNtdll, 152 Capability::RequiresProcessInjection, 153 ] 154 .iter() 155 .copied() 156 .collect(), 157 detection_difficulty: DetectionDifficulty::MediumHigh, 158 description: "NtCreateThreadEx - Native NT API thread creation", 159 }, 160 TechniqueMetadata { 161 name: "syscall", 162 capabilities: [ 163 Capability::LocalExecutionOnly, 164 Capability::SupportsDynamicResolver, 165 Capability::SupportsAMSIPatch, 166 Capability::RequiresNtdll, 167 ] 168 .iter() 169 .copied() 170 .collect(), 171 detection_difficulty: DetectionDifficulty::Medium, 172 description: "Syscall - Direct system call execution", 173 }, 174 TechniqueMetadata { 175 name: "etwp", 176 capabilities: [ 177 Capability::LocalExecutionOnly, 178 Capability::SupportsDynamicResolver, 179 Capability::SupportsAMSIPatch, 180 ] 181 .iter() 182 .copied() 183 .collect(), 184 detection_difficulty: DetectionDifficulty::High, 185 description: "Etwp - ETW thread pool-based execution", 186 }, 187 TechniqueMetadata { 188 name: "set-timer", 189 capabilities: [ 190 Capability::LocalExecutionOnly, 191 Capability::SupportsDynamicResolver, 192 Capability::SupportsAMSIPatch, 193 ] 194 .iter() 195 .copied() 196 .collect(), 197 detection_difficulty: DetectionDifficulty::High, 198 description: "SetTimer - Timer callback-based execution", 199 }, 200 TechniqueMetadata { 201 name: "enum-calendar", 202 capabilities: [ 203 Capability::LocalExecutionOnly, 204 Capability::SupportsDynamicResolver, 205 Capability::SupportsAMSIPatch, 206 ] 207 .iter() 208 .copied() 209 .collect(), 210 detection_difficulty: DetectionDifficulty::High, 211 description: "EnumCalendar - Callback-based via EnumCalendarInfoW", 212 }, 213 TechniqueMetadata { 214 name: "enum-windows", 215 capabilities: [ 216 Capability::LocalExecutionOnly, 217 Capability::SupportsDynamicResolver, 218 Capability::SupportsAMSIPatch, 219 ] 220 .iter() 221 .copied() 222 .collect(), 223 detection_difficulty: DetectionDifficulty::High, 224 description: "EnumWindows - Window enumeration callback-based execution", 225 }, 226 TechniqueMetadata { 227 name: "enum-system-locales", 228 capabilities: [ 229 Capability::LocalExecutionOnly, 230 Capability::SupportsDynamicResolver, 231 Capability::SupportsAMSIPatch, 232 ] 233 .iter() 234 .copied() 235 .collect(), 236 detection_difficulty: DetectionDifficulty::High, 237 description: "EnumSystemLocales - Locale enumeration callback-based execution", 238 }, 239 TechniqueMetadata { 240 name: "image-get-digest-stream", 241 capabilities: [ 242 Capability::LocalExecutionOnly, 243 Capability::SupportsDynamicResolver, 244 Capability::SupportsAMSIPatch, 245 ] 246 .iter() 247 .copied() 248 .collect(), 249 detection_difficulty: DetectionDifficulty::High, 250 description: "ImageGetDigestStream - Imagehlp callback-based execution", 251 }, 252 TechniqueMetadata { 253 name: "queue-user-apc", 254 capabilities: [ 255 Capability::LocalExecutionOnly, 256 Capability::SupportsDynamicResolver, 257 Capability::SupportsAMSIPatch, 258 ] 259 .iter() 260 .copied() 261 .collect(), 262 detection_difficulty: DetectionDifficulty::High, 263 description: "QueueUserAPC - APC-based local execution", 264 }, 265 TechniqueMetadata { 266 name: "fairy-law", 267 capabilities: [ 268 Capability::RequiresAdmin, 269 Capability::LocalExecutionOnly, 270 Capability::SupportsDynamicResolver, 271 Capability::SupportsAMSIPatch, 272 ] 273 .iter() 274 .copied() 275 .collect(), 276 detection_difficulty: DetectionDifficulty::VeryHigh, 277 description: "Fairy-Law - Privilege escalation via policy manipulation", 278 }, 279 TechniqueMetadata { 280 name: "module-stomping", 281 capabilities: [ 282 Capability::LocalExecutionOnly, 283 Capability::SupportsDynamicResolver, 284 Capability::SupportsAMSIPatch, 285 ] 286 .iter() 287 .copied() 288 .collect(), 289 detection_difficulty: DetectionDifficulty::VeryHigh, 290 description: "Module Stomping - DLL overwrite technique", 291 }, 292 TechniqueMetadata { 293 name: "thread-hijacking", 294 capabilities: [ 295 Capability::SupportsRemoteProcess, 296 Capability::SupportsDynamicResolver, 297 Capability::SupportsAMSIPatch, 298 Capability::RequiresProcessInjection, 299 ] 300 .iter() 301 .copied() 302 .collect(), 303 detection_difficulty: DetectionDifficulty::VeryHigh, 304 description: "Thread Hijacking - Context manipulation technique", 305 }, 306 TechniqueMetadata { 307 name: "early-bird", 308 capabilities: [ 309 Capability::SupportsRemoteProcess, 310 Capability::SupportsDynamicResolver, 311 Capability::SupportsAMSIPatch, 312 Capability::RequiresProcessInjection, 313 ] 314 .iter() 315 .copied() 316 .collect(), 317 detection_difficulty: DetectionDifficulty::VeryHigh, 318 description: "Early Bird - APC injection before main thread starts", 319 }, 320 ] 321 } 322 323 #[cfg(test)] 324 mod tests { 325 use super::*; 326 327 #[test] 328 fn test_all_techniques_registered() { 329 assert_eq!(get_technique_registry().len(), 17); 330 } 331 332 #[test] 333 fn test_get_technique_metadata_crt() { 334 let meta = get_technique_metadata("crt").unwrap(); 335 assert_eq!(meta.name, "crt"); 336 assert!(meta.has_capability(Capability::SupportsRemoteProcess)); 337 assert!(meta.has_capability(Capability::SupportsDynamicResolver)); 338 assert!(meta.requires_process()); 339 } 340 341 #[test] 342 fn test_get_technique_metadata_fairy_law() { 343 let meta = get_technique_metadata("fairy-law").unwrap(); 344 assert_eq!(meta.name, "fairy-law"); 345 assert!(meta.has_capability(Capability::RequiresAdmin)); 346 assert!(!meta.requires_process()); 347 } 348 349 #[test] 350 fn test_get_technique_metadata_case_insensitive() { 351 let meta1 = get_technique_metadata("CRT"); 352 let meta2 = get_technique_metadata("crt"); 353 let meta3 = get_technique_metadata("CrT"); 354 assert!(meta1.is_some()); 355 assert!(meta2.is_some()); 356 assert!(meta3.is_some()); 357 } 358 359 #[test] 360 fn test_get_technique_metadata_unknown() { 361 let meta = get_technique_metadata("unknown-technique"); 362 assert!(meta.is_none()); 363 } 364 365 #[test] 366 fn test_list_all_techniques() { 367 let techniques = list_all_techniques(); 368 assert_eq!(techniques.len(), 17); 369 } 370 371 #[test] 372 fn test_local_execution_techniques_dont_require_process() { 373 for meta in get_technique_registry() { 374 if meta.has_capability(Capability::LocalExecutionOnly) { 375 assert!(!meta.requires_process()); 376 } 377 } 378 } 379 380 #[test] 381 fn test_process_injection_techniques_require_process() { 382 for meta in get_technique_registry() { 383 if meta.has_capability(Capability::RequiresProcessInjection) { 384 assert!(meta.requires_process()); 385 } 386 } 387 } 388 389 #[test] 390 fn test_all_techniques_support_dynamic_resolver() { 391 for meta in get_technique_registry() { 392 assert!(meta.supports_dynamic_resolver()); 393 } 394 } 395 396 #[test] 397 fn test_all_techniques_support_amsi_patch() { 398 for meta in get_technique_registry() { 399 assert!(meta.has_capability(Capability::SupportsAMSIPatch)); 400 } 401 } 402 403 #[test] 404 fn test_capability_descriptions() { 405 assert!(!Capability::RequiresAdmin.description().is_empty()); 406 assert!(!Capability::SupportsRemoteProcess.description().is_empty()); 407 assert!(!Capability::SupportsDynamicResolver.description().is_empty()); 408 } 409 410 #[test] 411 fn test_detection_difficulty_ordering() { 412 assert!(DetectionDifficulty::Low < DetectionDifficulty::Medium); 413 assert!(DetectionDifficulty::Medium < DetectionDifficulty::MediumHigh); 414 assert!(DetectionDifficulty::MediumHigh < DetectionDifficulty::High); 415 assert!(DetectionDifficulty::High < DetectionDifficulty::VeryHigh); 416 } 417 }