Kategorie: Hardware / Prozessorarchitektur
1. Beschreibung
CPU-Fingerprinting misst Charakteristiken des Prozessors und der Plattform, die über JavaScript und WebAssembly offengelegt werden. Diese Signale leiten sich ab von:
- Gleitkomma-Einheit (FPU)-Verhalten
- CPU-Befehlssatzerweiterungen (SIMD, AES-NI, AVX, BMI, POPCNT)
- Cache-Hierarchie und Timing
performance.now()-Auflösung (Hardware-Timer)- WebAssembly-Ausführungsgeschwindigkeit (relativer Benchmark)
2. Vektoren
2.1 Mathe-/FPU-Fingerprinting
// Gleitkomma-Präzisionsunterschiede
function mathFingerprint() {
const inputs = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
return inputs.map(x => {
// Operationen, die Präzisionsunterschiede aufdecken
return Math.sin(x) * Math.cos(x) + Math.tan(x) - Math.asin(x) * Math.atan(x)
}).join(',')
}
// Unterschiedliche CPUs erzeugen leicht unterschiedliche Ergebnisse
Entropie: ~4-6 Bits
Stabilität: Sehr hoch – CPU-FPU-Verhalten ist festgelegt
Mechanismus: Die IEEE-754-Konformität variiert geringfügig zwischen CPU-Herstellern und -Modellen. Fused Multiply-Add (FMA)-Befehle erzeugen andere Ergebnisse als separate Multiply+Add-Operationen.
2.2 WebAssembly-Feature-Erkennung
// Wasm-Modul, das CPU-Feature-Unterstützung testet
const wasmCode = new Uint8Array([
0x00, 0x61, 0x73, 0x6d, // magic
0x01, 0x00, 0x00, 0x00, // version
// ... SIMD-, AES-NI-Erkennung via Wasm-Befehle
])
const module = await WebAssembly.instantiate(wasmCode)
const result = module.instance.exports.test()
Erkennbare Features:
- SIMD (128-Bit-Vektorbefehle)
- Vorzeichenerweiterungsoperationen
- Veränderliche Globals
- Bulk-Memory-Operationen
- Referenztypen
- Tail Calls
- Festbreiten-SIMD
Entropie: ~8-12 Bits (welche Features unterstützt werden)
Stabilität: Sehr hoch – CPU-Features sind festgelegt
2.3 Performance.now()-Auflösung
// Timer-Auflösung messen
const t1 = performance.now()
const t2 = performance.now()
const resolution = t2 - t1 // Minimal messbares Intervall
Entropie: ~2-3 Bits
Stabilität: Moderat – OS und Browser können die Auflösung ändern
2.4 WebAssembly-Benchmarking
// Relativer CPU-Geschwindigkeits-Benchmark
const start = performance.now()
// CPU-intensiven Wasm-Code ausführen
const elapsed = performance.now() - start
// Relative Geschwindigkeit ist identifizierend
Entropie: ~4-8 Bits
Stabilität: Niedrig-Moderat – beeinflusst durch CPU-Drosselung, Hintergrundprozesse, Energiemanagement
3. Stärken des Angreifers
| Stärke | Erklärung |
|---|---|
| Hardware-gebunden | CPU-Features können nicht ohne Hardware-Austausch geändert werden |
| Wasm ist schnell | Feature-Erkennung in <1ms |
| Keine Berechtigungen nötig | Wasm- und Mathe-APIs erfordern keine Benutzerzustimmung |
| Browserübergreifend | Gleiche CPU erzeugt ähnliche Fingerprints über Browser hinweg |
| Passiv | Keine Benutzerinteraktion erforderlich |
4. Schwächen des Angreifers
| Schwäche | Erklärung |
|---|---|
| Niedrige Entropie pro Vektor | Mathe-Fingerprint allein ist unzureichend |
| Browser reduziert Timer-Präzision | performance.now()-Auflösung wird absichtlich reduziert |
| Wasm kann blockiert werden | Browser-Einstellungen können WebAssembly deaktivieren |
| Benchmark-Varianz | CPU-Drosselung macht Messungen verrauscht |
| Gruppiert Benutzer nach CPU-Klasse | Alle Benutzer mit derselben CPU sehen gleich aus |
5. Erkennung von Manipulation
| Technik | Funktionsweise |
|---|---|
| Mathe-Ergebnis-Vergleich | Überschriebene Mathe-Methoden geben verdächtige Werte zurück |
| Wasm-Ausführungszeit | Blockiertes Wasm ist erkennbar (Instanziierung schlägt fehl) |
| Timer-Auflösung | Ungewöhnlich runde Auflösung deutet auf Überschreibung hin |
6. Abschwächungen für Obscura
6.1 Was Obscura tun kann
| Abschwächung | Effektivität | Erkennbarkeit | Implementierung |
|---|---|---|---|
performance.now()-Präzision überschreiben |
Niedrig | Niedrig | Auf 100ms runden |
| Wasm vollständig blockieren | Hoch | Mittel | JS: WebAssembly → undefined |
hardwareConcurrency überschreiben |
Hoch | Niedrig | JS-Injection (bereits in kontrollierbarer Liste) |
deviceMemory überschreiben |
Hoch | Niedrig | JS-Injection (bereits in kontrollierbarer Liste) |
6.2 Was Obscura nicht tun kann
| Kann nicht | Warum |
|---|---|
| FPU-Verhalten ändern | CPU-Hardware führt Befehle direkt aus |
| Wasm-CPU-Erkennung verhindern | Wasm läuft nativ, Proxy kann nicht eingreifen |
| Ausführungsgeschwindigkeit normalisieren | CPU-Geschwindigkeit ist physikalisch |
| Timing-Seitenkanäle entfernen | Jede JS-Ausführung verrät Timing |
6.3 Empfohlener Ansatz
1. hardwareConcurrency + deviceMemory überschreiben (bereits geplant)
2. performance.now()-Präzision überschreiben (geringer Aufwand, teilweiser Nutzen)
3. Mathe-FPU + Wasm-CPU-Erkennung akzeptieren (niedrige individuelle Entropie)
7. Forschungsreferenzen
- Mowery, K. et al. (2011). "Are These Your Keys? Using Cryptographic Fingerprints to Detect Malicious Applets." IEEE S&P 2011.
- Mulazzani, M. et al. (2013). "Fast and Reliable Browser Fingerprinting." ACSAC 2013.
- Olejnik, L. et al. (2015). "The Web Never Forgets: Persistent Tracking Mechanisms in the Wild." CCS 2014 (CPU-Timing-Abschnitt).