--- name: ctf-malware description: Malware and network analysis techniques for CTF challenges. Use when analyzing obfuscated scripts, malicious packages, custom protocols, or C2 traffic. user-invocable: false allowed-tools: ["Bash", "Read", "Write", "Edit", "Glob", "Grep", "Task", "WebFetch", "WebSearch"] --- # CTF Malware & Network Analysis ## Obfuscated Scripts - Replace `eval`/`bash` with `echo` to print underlying code - Extract base64/hex blobs and analyze with `file` - Common deobfuscation chain: base64 decode → gzip decode → reverse → base64 decode ## Debian Package Analysis ```bash ar -x package.deb # Unpack debian package tar -xf control.tar.xz # Check control files # Look for postinst scripts that execute payloads ``` ## Custom Crypto Protocols - Stream ciphers may share keystream state for both directions - Concatenate ALL payloads chronologically before decryption - Look for hardcoded keys in `.rodata` - **ChaCha20 keystream extraction:** Send large nullbytes payload (0 XOR anything = anything) - Alternative: Pipe ciphertext from pcap directly into the binary ## PCAP Analysis ```bash tshark -r file.pcap -Y "tcp.stream eq X" -T fields -e tcp.payload ``` Look for C2 communication patterns on unusual ports (e.g., port 21 not for FTP). ## Hex-Encoded Payloads - Convert hex to bytes, try common transformations: subtract 1, XOR with key ## JavaScript Deobfuscation ```javascript // Replace eval with console.log eval = console.log; // Then run the obfuscated code // Common patterns unescape() // URL decoding String.fromCharCode() // Char codes atob() // Base64 ``` ## PowerShell Analysis ```powershell # Common obfuscation -enc / -EncodedCommand # Base64 encoded IEX / Invoke-Expression # Eval equivalent [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($encoded)) ``` ## PE Analysis ```bash peframe malware.exe # Quick triage pe-sieve # Runtime analysis pestudio # Static analysis (Windows) ``` ## Sandbox Evasion Checks Look for: - VM detection (VMware, VirtualBox artifacts) - Debugger detection (IsDebuggerPresent) - Timing checks (sleep acceleration) - Environment checks (username, computername) - File/registry checks for analysis tools ## Network Indicators ```bash # Extract IPs/domains strings malware | grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' strings malware | grep -E '[a-zA-Z0-9.-]+\.(com|net|org|io)' # DNS queries tshark -r capture.pcap -Y "dns.qry.name" -T fields -e dns.qry.name | sort -u ``` ## C2 Traffic Patterns - Beaconing: regular intervals - Domain generation algorithms (DGA) - Encoded/encrypted payloads - HTTP(S) with custom headers - DNS tunneling ## Junk Code Detection **Pattern:** Obfuscation adds meaningless instructions around real code **Identification:** - NOP sleds, push/pop pairs that cancel - Arithmetic that results in zero/identity - Dead writes (register written but never read before next write) - Unconditional jumps to next instruction **Filtering technique:** ```python # Identify real calls by looking for patterns # junk, junk, junk, CALL target, junk, junk # Extract call targets, ignore surrounding noise def extract_real_calls(disassembly): calls = [] for instr in disassembly: if instr.mnemonic == 'call' and not is_junk_target(instr.operand): calls.append(instr) return calls ``` ## .NET DNS-based C2 **Pattern:** Deobfuscated .NET malware with DNS C2 **Analysis with dnSpy:** 1. Find network functions (TcpClient, DnsClient, etc.) 2. Identify encoding/encryption wrappers 3. Look for command dispatch (switch on opcode) **AsmResolver for programmatic analysis:** ```csharp using AsmResolver.DotNet; var module = ModuleDefinition.FromFile("malware.dll"); foreach (var type in module.GetAllTypes()) { foreach (var method in type.Methods) { // Analyze method body } } ``` ## AES-CBC in Malware **Common key derivation:** - MD5/SHA256 of hardcoded string - Derived from timestamp or PID - Password-based (PBKDF2) **Analysis approach:** ```python from Crypto.Cipher import AES from Crypto.Util.Padding import unpad import hashlib # Common pattern: key = MD5(password) password = b"hardcoded_password" key = hashlib.md5(password).digest() # IV often first 16 bytes of ciphertext iv = ciphertext[:16] ct = ciphertext[16:] cipher = AES.new(key, AES.MODE_CBC, iv) plaintext = unpad(cipher.decrypt(ct), 16) ``` ## Password Rotation in C2 **Pattern:** C2 uses rotating passwords based on time/sequence **Analysis:** 1. Find password generation function 2. Identify rotation trigger (time-based, message count) 3. Sync your decryptor with the rotation ```python def get_current_password(timestamp): # Password changes every hour hour_bucket = timestamp // 3600 return hashlib.sha256(f"seed_{hour_bucket}".encode()).digest() ``` ## Malware Configuration Extraction **Common storage locations:** - .data section (hardcoded) - Resources (PE resources, .NET resources) - Registry keys written at install - Encrypted config file dropped to disk **Extraction tools:** ```bash # PE resources wrestool -x -t 10 malware.exe -o config.bin # .NET resources monodis --mresources malware.exe # Strings in .rdata/.data objdump -s -j .rdata malware.exe ``` ## Identifying Encryption Algorithms **By constants:** - AES: `0x637c777b`, `0x63636363` (S-box) - ChaCha20: `expand 32-byte k` or `0x61707865` - RC4: Sequential S-box initialization - TEA/XTEA: `0x9E3779B9` (golden ratio) **By structure:** - Block cipher: Fixed-size blocks, padding - Stream cipher: Byte-by-byte, no padding - Hash: Mixing functions, rounds, constants ## .NET Malware Analysis (C2 Extraction) **Tools:** ILSpy, dnSpy, dotPeek **LimeRAT C2 extraction (Whisper Of The Pain):** 1. Open .NET binary in dnSpy 2. Find configuration class with Base64 encoded string 3. Identify decryption method (typically AES-256-ECB with derived key) 4. Key derivation: MD5 of hardcoded string → first 15 + full 16 bytes + null = 32-byte key 5. Decrypt: Base64 decode → AES-ECB decrypt → reveals C2 IP/domain ```python from Crypto.Cipher import AES import hashlib, base64 key_source = '${8\',`d0}n,~@J;oZ"9a' md5 = hashlib.md5(key_source.encode()).hexdigest() # Key = md5[:30] + md5 + '\x00' (32 bytes total as hex → 16 bytes binary) key = bytes.fromhex(md5[:30] + md5 + '00')[:32] cipher = AES.new(key, AES.MODE_ECB) plaintext = cipher.decrypt(base64.b64decode(encrypted_b64)) ``` ## Telegram Bot API for Evidence Recovery **Pattern (Stomaker):** Malware uses Telegram bot to exfiltrate stolen data. **Recover exfiltrated data via bot token:** ```python # If you have the bot API token from malware source: import requests TOKEN = "bot_token_here" # Get updates (message history) r = requests.get(f"https://api.telegram.org/bot{TOKEN}/getUpdates") # Download files sent to bot file_id = "..." r = requests.get(f"https://api.telegram.org/bot{TOKEN}/getFile?file_id={file_id}") file_path = r.json()['result']['file_path'] requests.get(f"https://api.telegram.org/file/bot{TOKEN}/{file_path}") ``` ## RC4-Encrypted WebSocket C2 Traffic **Pattern (Tampered Seal):** Malware uses WSS over non-standard port with RC4 encryption. **Decryption workflow:** 1. Identify C2 port from malware source (not standard 443) 2. Remap port with `tcprewrite` so Wireshark decodes TLS 3. Add RSA key for TLS decryption → reveals WebSocket frames 4. Find RC4 key hardcoded in malware binary 5. Decrypt each WebSocket payload with RC4 via CyberChef **Malware communication patterns:** - Registration message: hostname, OS, username, privileges - Exfiltration: screenshots, keylog data, file contents - Commands: reverse shell, file download, process list ## PyInstaller + PyArmor Unpacking ```bash # Step 1: Extract PyInstaller archive python pyinstxtractor.py malware.exe # Look for main .pyc file in extracted directory # Step 2: If PyArmor-protected, use unpacker # github.com/Svenskithesource/PyArmor-Unpacker # Three methods available; choose based on PyArmor version # Step 3: Clean up deobfuscated source # Remove fake/dead-code functions (confusion code) # Identify core encryption/exfiltration logic ```