LAB-15Easy
C2 Configuration Extraction
Extract the command-and-control configuration from a sample's strings.
10 min4 prerequisites6 tools
Investigate
Hints
Hint 1
The domain, port, and path together define the C2 endpoint.
Hint 2
Port 443 means HTTPS.
Hint 3
InternetConnectW takes host + port.
Submit Findings
Solution
C2 Configuration Extraction — Solution
The C2 config is fully hardcoded:
- Domain:
c2.example.com - Port:
443(HTTPS) - Path:
beacon.php - API:
InternetConnectW(WinINet HTTP)
Full endpoint: https://c2.example.com:443/beacon.php
Methodology: find the network API, then the values it consumes (host, port, path) — those are the C2 IOCs.
Prerequisites
- m3-command-and-control
- sa1-strings-metadata
- WinINet API (InternetOpen, InternetConnect, HttpOpenRequest, HttpSendRequest)
- Common C2 protocols (HTTP/S, DNS, custom TCP)
Methodology
Investigation Methodology
1. Identify Network APIs
Search imports or strings for:
- WinINet:
InternetOpen,InternetConnect,HttpOpenRequest,HttpSendRequest,InternetReadFile - Winsock:
WSASocket,connect,send,recv,WSAConnect - WinHTTP:
WinHttpOpen,WinHttpConnect,WinHttpOpenRequest,WinHttpSendRequest - Custom: Raw TCP/UDP, DNS tunnels, HTTPS via Schannel
2. Trace Data Flow to API Calls
In Ghidra/decompiler:
- Find call to
InternetConnectW - Trace arguments backward:
lpszServerName(host/domain) string referencenServerPort(port) constant or variable- Context:
InternetOpen->InternetConnect->HttpOpenRequest->HttpSendRequest
3. Extract Configuration Elements
| Element | Source | Example |
|---|---|---|
| Domain/IP | String referenced by InternetConnectW arg 1 |
c2.example.com |
| Port | InternetConnectW arg 2 |
443 |
| Path/URI | HttpOpenRequest arg 3 (lpszObjectName) |
/beacon.php |
| User-Agent | HttpOpenRequest arg 4 |
Mozilla/5.0... |
| Headers | HttpAddRequestHeaders buffers |
Authorization: Bearer... |
| Protocol | Port (80=HTTP, 443=HTTPS) or INTERNET_FLAG_SECURE |
HTTPS |
4. Handle Obfuscation
- Stack strings: Built character-by-character on stack
- XOR/ADD encoded: Decoded at runtime before API call
- Resource-embedded: Stored in
.rsrc, loaded viaFindResource/LoadResource - DGA: Domain generated algorithmically
5. Build Full Endpoint
Protocol: HTTPS (port 443), Domain: c2.example.com, Path: /beacon.php. Full: https://c2.example.com:443/beacon.php
6. Pivot for Intelligence
- Passive DNS / WHOIS on domain
- SSL certificate analysis (JA3 fingerprint)
- Historical resolutions (VirusTotal, SecurityTrails)
- C2 panel identification (path patterns)
- Infrastructure clustering
Common Pitfalls
- Only checking imports — missing dynamically resolved APIs (`GetProcAddress`)
- Assuming port 80/443 — malware uses non-standard ports (8080, 8443, 6666)
- Missing the path — `HttpOpenRequest` `lpszObjectName` is separate from domain
- Overlooking User-Agent and headers — valuable for detection signatures
- Not checking for multiple C2s (fallback domains, domain lists)
Tools
- Ghidra (Decompiler, Cross-references, Defined Strings)
- Binary Ninja (Data flow analysis)
- FLOSS (obfuscated string extraction)
- Wireshark / PCAP analysis (dynamic)
- Malcat / PE-bear (quick string + import scan)
- YARA rules for C2 config patterns
References
- Lesson M3: Command and Control
- Lesson SA1: Strings & Metadata
- Microsoft Docs: WinINet API Reference
- MITRE ATT&CK: T1071.001 (Web Protocols)
- Mandiant: C2 Infrastructure Analysis
Extensions & Challenges
- Extract config from a real sample with encoded strings (XOR, RC4)
- Write a Ghidra script to auto-extract WinINet C2 configs
- Research: DNS tunneling C2 — how to detect via strings?
- Analyze a sample with Domain Generation Algorithm (DGA)
- Build a C2 config extractor for common frameworks (Cobalt Strike, Sliver, Mythic)