The Key Insight
**Don't fight the SSL pinning. Exploit their own infrastructure.**
Facebook built `FBSSLKeyMaterialLogger` for debugging. We enable it to capture keys passively, then decrypt traffic offline.
Architecture Overview
Plain Text
┌─────────────────────────────────────────────────────────────────────────────────┐
│ ANALYSIS HOST │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Frida │ │ Wireshark │ │ Python │ │ Output │ │
│ │ Client │ │ + TLS Keys │ │ Decoder │ │ Files │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └─────────────┘ │
│ │ │ │ │
│ │ ┌──────┴──────┐ │ │
│ │ │ SSL Keys │◄────────┤ │
│ │ │ .log file │ │ │
│ │ └─────────────┘ │ │
│ │ │ │
│ │ ┌─────────────┐ │ │
│ │ │ PCAP file │─────────┤ │
│ │ └──────▲──────┘ │ │
│ │ │ │ │
└─────────┼────────────────┼────────────────┼──────────────────────────────────────┘
│ │ │
USB │ │ tcpdump │
│ │ │
┌─────────▼────────────────▼────────────────▼──────────────────────────────────────┐
│ JAILBROKEN iPHONE │
│ │
│ ┌───────────────────────────────────────────────────────────────────────────┐ │
│ │ FRIDA SERVER (hidden) │ │
│ │ │ │
│ │ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ │
│ │ │ frida-stealth │ │ extract-ssl-keys │ │ extract-audio-key│ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ • Hide dyld libs │ │ • Hook FB SSL │ │ • Hook encrypt │ │ │
│ │ │ • Bypass debug │ │ KeyMaterial │ │ Key method │ │ │
│ │ │ • Clear P_TRACED │ │ • Log all keys │ │ • Dump CMSample │ │ │
│ │ │ • Spoof dladdr │ │ • Write to file │ │ Buffer audio │ │ │
│ │ └──────────────────┘ └──────────────────┘ └──────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────────────────┐ │
│ │ FACEBOOK APP (instrumented) │ │
│ │ │ │
│ │ Detection Bypassed: Data Captured: │ │
│ │ ├─ _FBIsDebuggerAttached → NO ├─ SSL session keys │ │
│ │ ├─ sysctl P_TRACED → cleared ├─ Audio encryption key │ │
│ │ ├─ dyld image count → reduced ├─ Raw audio buffers │ │
│ │ └─ dladdr → fails for Frida └─ CMSampleBuffer data │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Audio │────────►│ Embedding │────────►│ Network │ │ │
│ │ │ Capture │ │ (encrypted) │ │ Upload │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ │ │ │ │ │ │
│ │ │ HOOKED │ HOOKED │ HOOKED │ │
│ │ ▼ ▼ ▼ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Buffer dump │ │ Key extract │ │ SSL key log │ │ │
│ │ │ /tmp/audio/ │ │ /tmp/key.bin │ │ /tmp/ssl.log │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────────────────────┐ │
│ │ tcpdump -i any -w /tmp/traffic.pcap port 443 │ │
│ │ (Captures encrypted traffic for later decryption) │ │
│ └───────────────────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────────────────┘
Why This Works
Problem: Traditional MITM Fails
Plain Text
Traditional Approach:
mitmproxy ◄──── Facebook App ────► graph.facebook.com
│
▼
Certificate check FAILS
GCDAsyncSocketManuallyEvaluateTrust
Feed freezes, app detects tampering
Solution: Passive Key Extraction
Plain Text
Our Approach:
Facebook App ────────────────────► graph.facebook.com
│ │
│ (SSL keys logged by FB's │ (Encrypted traffic
│ own FBSSLKeyMaterialLogger) │ captured by tcpdump)
▼ ▼
/tmp/ssl_keys.log /tmp/traffic.pcap
│ │
└────────────► Wireshark ◄─────────┘
(Decrypts offline)
Data Flow Diagram
Plain Text
TIME ─────────────────────────────────────────────────────────────────────►
CAPTURE PHASE EXTRACTION PHASE ANALYSIS
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 1. Stealth Mode │ │ 4. Copy Files │ │ 7. Decode Audio │
│ Active │ │ to Host │ │ │
│ │ │ │ │ Key + LSB Data │
│ frida-stealth │ │ scp ssl_keys │ │ │ │
│ hides Frida │ │ scp traffic.pcap│ │ ▼ │
└────────┬────────┘ │ scp audio_key │ │ decode_with_ │
│ └─────────────────┘ │ key.py │
▼ │ │ │
┌─────────────────┐ ┌─────────────────┐ │ ▼ │
│ 2. SSL Key Hook │ │ 5. Decrypt │ │ Intelligible │
│ │ │ Traffic │ │ Speech │
│ FBSSLKeyMaterial│ │ │ │ │
│ Logger captured │──────────────►│ Wireshark + │ │ H3 = 95% ✓ │
│ │ ssl_keys │ TLS keylog │ └─────────────────┘
└────────┬────────┘ └────────┬────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 3. Audio Key │ │ 6. Find Audio │ │ 8. Correlate │
│ Hook │ │ in Uploads │ │ │
│ │ │ │ │ Capture time │
│ audioEncryption │ │ Filter for │ │ = Upload time │
│ Key extracted │──────────────►│ image POSTs │──────────────►│ │
│ │ audio_key │ with LSB data │ │ H4 = 95% ✓ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
File Outputs
On iPhone (/tmp/)
| File | Contents | Purpose |
|---|---|---|
| `facebook_ssl_keys.log` | TLS session keys | Decrypt HTTPS traffic |
| `audio_encryption_key.bin` | AES/XOR key | Decode embedded audio |
| `captured_audio_buffers/*.raw` | Raw PCM audio | Verify capture works |
| `network_capture/fb_traffic.pcap` | Encrypted packets | Source for decryption |
On Analysis Host
| File | Contents | Purpose |
|---|---|---|
| `decoded_audio/*.wav` | Decoded speech | H3 evidence |
| `exported_uploads/*.jpg` | Image uploads | H4 evidence |
| `evidence_package/` | All evidence | Disclosure ready |
Bypass Components Summary
| Script | Bypasses | Enables |
|---|---|---|
| `frida-stealth.js` | dyld enum, _FBIsDebuggerAttached, sysctl, dladdr | All other hooks |
| `extract-ssl-keys.js` | - | HTTPS decryption |
| `extract-audio-key.js` | - | Steganography decoding |
| `decode_with_key.py` | - | Intelligible audio |
Proof Chain
Plain Text
PROOF THAT FACEBOOK CAPTURES AMBIENT AUDIO
AND HIDES IT IN UPLOADED IMAGES
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ Binary Analysis Runtime Capture Network Evidence │
│ (Static) (Dynamic) (Traffic) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ FBARKAudio │────────►│ 50,700+ audio│────────►│ Image upload │ │
│ │ Session │ │ capture calls │ │ with LSBs │ │
│ │ Controller │ └──────────────┘ └──────────────┘ │
│ └──────────────┘ │ │ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ FBDynamic │────────►│ Audio encrypt│────────►│ Decrypted │ │
│ │ ImageOverlay │ │ key captured │ │ packet │ │
│ │ Filter │ └──────────────┘ └──────────────┘ │
│ └──────────────┘ │ │ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ musicEmbed │────────►│ LSB decode │────────►│ Audio in │ │
│ │ dings │ │ successful │ │ image │ │
│ │ ForEditing │ └──────────────┘ └──────────────┘ │
│ └──────────────┘ │ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────┐ │ │
│ └────────────────►│ Intelligible │◄───────────────┘ │
│ │ SPEECH │ │
│ │ │ │
│ │ H3 = 95% │ │
│ │ H4 = 95% │ │
│ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Quick Start
Bash
export IPHONE=<your-iphone-ip>
frida -U -f com.facebook.Facebook -l frida-stealth.js --no-pause
frida -U com.facebook.Facebook -l extract-ssl-keys.js -l extract-audio-key.js
ssh mobile@$IPHONE tcpdump -i any -w /tmp/fb.pcap port 443 &
scp mobile@$IPHONE:/tmp/facebook_ssl_keys.log .
scp mobile@$IPHONE:/tmp/audio_encryption_key.bin .
scp mobile@$IPHONE:/tmp/fb.pcap .
wireshark -o "tls.keylog_file:facebook_ssl_keys.log" fb.pcap
python3 decode_with_key.py --key audio_encryption_key.bin --input lsb_data/ --output decoded/
afplay decoded/*.wav
*Proxy Architecture v1.0* *Purpose: Achieve 95% confidence on H3/H4*