--- name: loader-dropper-analysis description: > Analyze malware loaders and droppers that deliver second-stage payloads. Covers Emotet, QakBot, IcedID, SmokeLoader, BatLoader, Bumblebee, and PikaBot. Includes delivery mechanism analysis (macro documents, ISO/LNK, HTML smuggling), multi-stage payload extraction, DLL sideloading, process injection techniques, encrypted payload decryption, and campaign tracking via embedded configurations. --- # Loader & Dropper Analysis Analyze malware loaders that serve as the initial access and delivery mechanism for second-stage payloads like ransomware, infostealers, and RATs. ## Prerequisites - **Python 3.10+**: `pefile`, `oletools`, `yara-python`, `pycryptodome` - **Tools**: Ghidra/IDA Pro, x64dbg, Process Monitor, API Monitor - **Optional**: `olevba`, `oleid`, CyberChef, `binwalk` - **Environment**: Isolated VM with network monitoring and snapshot capability ## Step-by-Step Instructions ### Step 1: Identify the Delivery Mechanism Determine how the loader reaches the victim. **Analyze the delivery container:** ```bash python3 scripts/loader_analyzer.py --sample delivery_file --mode delivery --output delivery.json ``` **Common delivery vectors:** | Vector | File Types | Loader Families | |--------|-----------|-----------------| | Macro documents | .doc, .docm, .xlsm | Emotet, QakBot | | ISO/IMG containers | .iso, .img | QakBot, IcedID, Bumblebee | | LNK shortcuts | .lnk (in ZIP/ISO) | BatLoader, QakBot | | HTML smuggling | .html, .htm | QakBot, IcedID | | OneNote files | .one | QakBot, Emotet | | MSI installers | .msi | BatLoader | | JavaScript/VBS | .js, .vbs, .wsf | SmokeLoader | **Macro analysis:** ```bash # Extract and analyze VBA macros olevba malicious.doc olevba --deobf malicious.doc # Check for auto-execution triggers olevba malicious.doc | grep -iE "(AutoOpen|Auto_Open|Document_Open|Workbook_Open)" ``` **ISO/IMG container analysis:** ```bash # Mount and inspect ISO contents 7z l delivery.iso 7z x delivery.iso -o./extracted_iso/ # Check for hidden files ls -la extracted_iso/ file extracted_iso/* ``` **HTML smuggling detection:** ```bash # Look for JavaScript blob construction grep -nE "(atob|Uint8Array|Blob|createObjectURL|msSaveOrOpenBlob)" smuggle.html ``` ### Step 2: Extract the First-Stage Payload Isolate the initial loader binary from the delivery container. **From macro documents:** ```bash # Extract embedded objects oleobj malicious.doc -d extracted/ # Extract shellcode from VBA python3 scripts/loader_analyzer.py --sample malicious.doc --mode extract-macro --output stage1/ ``` **From LNK files:** ```bash # Parse LNK shortcut target and arguments python3 -c " import struct, sys with open(sys.argv[1], 'rb') as f: data = f.read() # LNK command line is typically visible in strings print([s for s in data.split(b'\x00') if b'cmd' in s.lower() or b'powershell' in s.lower()]) " malicious.lnk ``` **From ISO containers:** ```bash # The payload is typically a DLL invoked via rundll32 file extracted_iso/*.dll strings extracted_iso/*.dll | grep -i "DllRegisterServer\|DllMain\|ServiceMain" ``` ### Step 3: Analyze DLL Sideloading and Execution Many loaders abuse legitimate executables for DLL sideloading. **Identify sideloading:** ```bash python3 scripts/loader_analyzer.py --sample loader.dll --mode sideload --output sideload.json ``` **Common sideloading patterns:** | Legitimate Binary | Sideloaded DLL | Used By | |-------------------|----------------|---------| | rundll32.exe | Custom export name | Most loaders | | regsvr32.exe | DllRegisterServer export | QakBot, IcedID | | msiexec.exe | MSI package with DLL | BatLoader | | calc.exe (renamed) | WindowsCodecs.dll | Bumblebee | **DLL execution analysis:** ```bash # Check DLL exports python3 -c " import pefile pe = pefile.PE(sys.argv[1]) if hasattr(pe, 'DIRECTORY_ENTRY_EXPORT'): for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols: name = exp.name.decode() if exp.name else f'ordinal_{exp.ordinal}' print(f' {name} @ 0x{exp.address:08x}') " loader.dll # Execute in sandbox with specific export rundll32.exe loader.dll,DllRegisterServer rundll32.exe loader.dll,#1 # By ordinal ``` ### Step 4: Trace Process Injection Techniques Loaders typically inject payloads into legitimate processes. **Monitor injection with API Monitor/x64dbg:** ```bash python3 scripts/loader_analyzer.py --sample loader.exe --mode injection --output injection.json ``` **Injection techniques by family:** | Technique | APIs | Families | |-----------|------|----------| | Process hollowing | CreateProcess(SUSPENDED), NtUnmapViewOfSection, WriteProcessMemory | Emotet, QakBot | | APC injection | QueueUserAPC, NtQueueApcThread | IcedID | | Thread hijacking | SuspendThread, SetThreadContext, ResumeThread | SmokeLoader | | Direct syscalls | NtAllocateVirtualMemory, NtWriteVirtualMemory | Bumblebee, PikaBot | | Callback injection | EnumWindows, CreateTimerQueueTimer with payload | Various | **Breakpoints for injection detection:** ``` # x64dbg breakpoints bp NtAllocateVirtualMemory bp NtWriteVirtualMemory bp NtCreateThreadEx bp NtQueueApcThread bp NtMapViewOfSection bp NtResumeThread ``` **Common injection targets:** - `explorer.exe`, `svchost.exe`, `rundll32.exe` - `wermgr.exe`, `dllhost.exe`, `msiexec.exe` - Newly spawned suspended processes ### Step 5: Decrypt Embedded Payloads Extract and decrypt the second-stage payload. **Automated decryption:** ```bash python3 scripts/loader_analyzer.py --sample loader.exe --mode decrypt --output decrypted_payload.bin ``` **Common encryption schemes:** | Family | Encryption | Key Source | |--------|-----------|------------| | Emotet | AES-256 + XOR | Hardcoded key in binary | | QakBot | RC4 + XOR | Resource section key | | IcedID | Custom XOR chain | Config blob | | SmokeLoader | Multi-layer XOR | Stage-dependent | | Bumblebee | RC4 | Hardcoded string | **Manual decryption approach:** ```python from Crypto.Cipher import ARC4 def decrypt_rc4(data: bytes, key: bytes) -> bytes: """Decrypt RC4-encrypted payload.""" cipher = ARC4.new(key) return cipher.decrypt(data) # Common: payload stored in PE resource section import pefile pe = pefile.PE("loader.dll") for entry in pe.DIRECTORY_ENTRY_RESOURCE.entries: for resource in entry.directory.entries: data = pe.get_data(resource.directory.entries[0].data.struct.OffsetToData, resource.directory.entries[0].data.struct.Size) # Try decryption with known keys for key in [b"bumblebee", b"loader_key"]: decrypted = decrypt_rc4(data, key) if decrypted[:2] == b"MZ": print(f"Decrypted PE found with key: {key}") ``` ### Step 6: Analyze the C2 Communication Understand how the loader communicates with its infrastructure. **Extract C2 configuration:** ```bash python3 scripts/loader_analyzer.py --sample loader.exe --mode c2 --output c2_config.json ``` **C2 patterns by family:** | Family | Protocol | Characteristics | |--------|----------|-----------------| | Emotet | HTTP POST | Protobuf-encoded data, epoch-based C2 list rotation | | QakBot | HTTPS | Encrypted JSON, hardcoded C2 list in config | | IcedID | HTTPS | Steganography in images for config, BackConnect module | | SmokeLoader | HTTP | Encrypted POST body, multiple fallback C2s | | Bumblebee | HTTPS/WebSocket | RC4-encrypted communication | | PikaBot | HTTPS | JSON-based, anti-analysis checks before C2 contact | ### Step 7: Track Campaign and Builder Configuration Extract configuration data for campaign attribution. **Extract config:** ```bash python3 scripts/loader_analyzer.py --sample loader.exe --mode config --output campaign_config.json ``` **Configuration elements to extract:** - Campaign ID / botnet ID - Bot version number - C2 server list (with failover order) - Encryption keys - Target geographic regions (language checks) - Anti-analysis flags - Payload download URLs ### Step 8: Map the Full Delivery Chain Document the complete multi-stage execution flow. **Full chain analysis:** ```bash python3 scripts/loader_analyzer.py --sample initial_delivery --mode chain --output full_chain.json ``` **Typical delivery chain:** ``` Email → ZIP attachment → ISO/IMG container → LNK shortcut + hidden DLL → rundll32.exe loads DLL (sideloading) → DLL decrypts embedded payload → Process injection into explorer.exe → C2 beacon → downloads final payload (ransomware/stealer) ``` ## Output Format ```json { "family": "QakBot", "confidence": "high", "delivery": { "vector": "ISO container via HTML smuggling", "files": ["invoice.html", "document.iso", "shortcut.lnk", "loader.dll"] }, "stages": [ {"stage": 1, "type": "LNK shortcut", "executes": "rundll32.exe loader.dll,DllRegisterServer"}, {"stage": 2, "type": "DLL loader", "technique": "process_hollowing", "target": "wermgr.exe"}, {"stage": 3, "type": "QakBot core", "decrypted_from": "PE resource section"} ], "injection": { "technique": "process_hollowing", "target_process": "wermgr.exe", "apis": ["NtCreateSection", "NtMapViewOfSection", "NtResumeThread"] }, "c2": { "protocol": "HTTPS", "servers": ["198.51.100.10:443", "203.0.113.20:2222"], "encryption": "RC4" }, "config": { "campaign_id": "obama250", "bot_version": "404.46", "timestamp": "2024-01-15" }, "iocs": { "hashes": {}, "domains": [], "ips": ["198.51.100.10", "203.0.113.20"], "mutexes": [] }, "mitre_attack": ["T1566.001", "T1204.002", "T1574.002", "T1055.012", "T1071.001"] } ``` ## Tips - Loaders evolve quickly — delivery mechanisms shift with Microsoft's macro blocking policies - ISO/LNK replaced macros as the primary delivery vector starting in 2022 - Many loaders check system language to avoid CIS countries — test with Russian locale - Process injection often uses direct syscalls to bypass API hooks — check for `ntdll` stubs - QakBot and Emotet rotate C2 infrastructure frequently; extract configs quickly - DLL sideloading requires the legitimate EXE and malicious DLL in the same directory - Some loaders sleep for extended periods before activating — run dynamic analysis for 10+ minutes - Bumblebee and PikaBot emerged as QakBot replacements after the 2023 takedown