# ReBreak Magic — RE-Hardening Assessment & Plan **Erstellt:** 2026-06-09 **Scope:** `apps/rebreak-magic-mac/` · `apps/rebreak-magic-win/` · relevante Backend-Berührungspunkte **Status:** Assessment + Plan zur Founder-Abnahme. Keine Implementierung. --- ## 1. RE-Exposure-Analyse: Was liegt aktuell offen? ### 1.1 Mac-App (SwiftUI, .app-Bundle) **Technische Ausgangslage:** Swift-Binaries sind Mach-O, kompiliert mit Optimierungen. String-Literale im `__TEXT`-Segment bleiben im Binary. `strings`-Analyse + Class-Dump (mit `class-dump` oder Ghidra) reicht für alles Relevante. | Angriffsvektor | Was ist extrahierbar? | Sicherheitskritisch? | |---|---|---| | String-Scan des Binary | `https://staging.rebreak.org`, `https://dns.rebreak.org/dns-query`, `org.rebreak.magic`, `org.rebreak.protection.dns.filter`, `org.rebreak.protection.profile` | Niedrig — Base-URLs sind keine Secrets | | `REBREAK_BACKEND_URL` env-Override | Hardcoded String + Kommentar im Binary: „Default to staging (app.rebreak.org hat aktuell falsches TLS-Zert)" | Mittel — zeigt interne Infrastruktur-Anmerkungen | | Keychain-Keys | `org.rebreak.magic` / `magic-session` — kein Secret-Wert, nur Service/Account-Namen | Niedrig | | `mgc_`-Token-Prefix | Token-Format `mgc_` im Binary erkennbar | Niedrig | | Profil-PayloadIdentifier | `org.rebreak.protection.dns.filter.*` im Binary + `.mobileconfig`-Dateiname | Niedrig | | `MacProfileInstaller.remove()` | Vollständiger Removal-Pfad via `profiles remove -identifier org.rebreak.protection.profile.*` sichtbar | **Mittel-hoch** — RE kann Removal-Kommando 1:1 nachbauen | | `profiles show -type configuration` | Identifier-Scan-Logik offenbart die exakten Identifier des Schutzes | Mittel | | Debug-State in `WizardModel` | `DebugSupervisionMode` mit `forceSupervised`/`forceUnsupervised` im Release-Build sichtbar | Mittel — gibt Hinweise auf interne States | | Removal-Password | **NICHT** im Binary. Kommt server-seitig via `/api/magic/profile.mobileconfig`. Liegt in Keychain auf dem Device. | Kein Exposure-Risiko im Binary | | AdGuard-Creds | **NICHT** im Binary. Nur im Backend via Infisical. | Kein Exposure-Risiko | **Kritische Erkenntnis Mac:** Das eigentliche Schutz-Bypass-Risiko liegt **nicht im Binary**, sondern im Mechanismus selbst: Der User hat Admin-Passwort. Mit Admin-Passwort kann er das .mobileconfig-Profil über System Settings → Geräteverwaltung entfernen — unabhängig vom Binary-Wissen. Das `ProfileRemovalPassword` ändert das erst dann, wenn es korrekt vom Backend injiziert wird. Das ist der echte Lock. --- ### 1.2 Windows-App (Tauri 2 / Rust) **Technische Ausgangslage:** Rust-Binaries sind kompilierter Maschinencode. Ohne Debug-Symbols sind Funktionsnamen weg — aber String-Literale sind **direkt extrahierbar** mit `strings`. Tauri-Apps haben zusätzlich einen eingebetteten WebView mit React-Bundle (JavaScript-Klartext). | Angriffsvektor | Was ist extrahierbar? | Sicherheitskritisch? | |---|---|---| | `strings` auf `.exe` | `https://staging.rebreak.org`, `dns.rebreak.org`, `178.105.101.137` (Fallback-IP), `RebreakProtection` (Service-Name), `HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters`, Registry-Pfade für Browser-Policies | Mittel | | PowerShell-Scripts als String-Literale | **Komplett lesbar** — `apply_script()`, `teardown_script()`, `check_script()` sind reine Strings im Binary. Jeder sieht exakt was geschrieben und gelöscht wird | **Hoch** — Angreifer kann Teardown-Sequenz 1:1 reproduzieren | | Service-Name `RebreakProtection` | Im `sc.exe`-Aufruf als Literal; Service kann per Name gestoppt werden | **Hoch** — `sc.exe stop RebreakProtection` + `sc.exe delete RebreakProtection` reicht für Bypass | | DoH-Template `https://dns.rebreak.org/dns-query/{token}` | Token-Schema erkennbar | Niedrig | | `protection.json` unter `%ProgramData%\ReBreak\` | Pfad im Binary. Datei enthält `dnsToken`, `serverIp`, `dohTemplate`, `backendUrl`, `deviceId` im Klartext | **Kritisch** — wer Pfad kennt, kann DNS-Token + Status-Polling-URL direkt lesen | | Credential Manager Keys | `org.rebreak.magic` / `session-token` / `dns-token` — Keynames extrahierbar. Zugriff auf Werte braucht SYSTEM/selben User-Kontext | Mittel | | WebView-Bundle (JS) | React-Frontend-Code im Klartext, komplett readable. Enthält keine Secrets (Token nie im Frontend), aber alle UI-Strings, State-Typen, IPC-Command-Namen | Niedrig — keine Secrets | | `--console`-Debug-Flag | Im Binary sichtbar: `rebreak-protection-service.exe --console` startet den Service im Vordergrund | Niedrig — Debug-Feature, kein Angriffspfad | | `DOH_FALLBACK_IP` `178.105.101.137` | Hetzner-Box direkt im Binary | Mittel — IP-Wissen; aber auch über DNS auflösbar | **Kritische Erkenntnis Windows:** **Das `protection.json`-File ist das größte Exposure-Problem.** Es liegt unter `%ProgramData%\ReBreak\protection.json` als lesbare JSON-Datei, enthält den DNS-Token im Klartext und ist für jeden User des Systems lesbar (ProgramData ist nicht ACL-beschränkt auf Nicht-Admin-User in Standardkonfiguration). Wer den Token kennt, kann `/api/magic/status?token=` selbst pollen und damit theoretisch den Status-Check-Mechanismus verstehen. **Der Service-Name-Bypass ist das kritischste operative Risiko:** Da `RebreakProtection` im Klartext im Binary steht und der Service mit `sc.exe` verwaltet wird, kann ein technisch versierter User mit Admin-Rechten: 1. `sc.exe stop RebreakProtection` ausführen 2. DoH manuell zurücksetzen (Registry/PowerShell) 3. Schutz ist weg — bis zum nächsten Service-Start (alle 5min Auto-Restart greift, aber Fenster ist offen) Gegenargument: Das braucht Admin-Rechte. Jemand mit Admin kann ohnehin alles. Aber es macht es trivial und skriptbar. --- ### 1.3 Backend-Berührungspunkte | Punkt | Exposure | Kritisch? | |---|---|---| | `/api/magic/status?token=` ist unauthentifiziert | Design-gewollt — Token ist das Secret. 48 hex chars = 192 bit Entropie → praktisch nicht brute-forcebar | Nein | | Tamper-Service pollt diesen Endpoint | Jeder der den Token aus `protection.json` liest, kann denselben Request abschicken und sieht `active=true/false` | Theoretisch — kein zusätzlicher Bypass damit möglich | | `profile.mobileconfig?token=` ist unauthentifiziert | Wie oben — Token-basierter Auth. Profil enthält RemovalPassword im Klartext (für macOS) | Mittel — Removal-PW liegt im Profil-XML falls jemand das Profil-File auf dem Mac lesen kann | | AdGuard-Creds | Nur Backend / Infisical. Kein Client-Exposure | Kein Risiko | | Pairing-Code 6 Ziffern (1M Raum) | 10min TTL, max 5 aktive Attempts unwahrscheinlich throttled | Niedrig — kurze TTL schützt | --- ## 2. Sicherheitsbewertung: Was ist tatsächlich kritisch? ### Kritisch (direkter Bypass möglich) - **Windows `protection.json` lesbar:** DNS-Token im Klartext für lokale User - **Windows Service-Stop via bekanntem Namen + Auto-Restart-Fenster:** 5min-Fenster zwischen Service-Stop und Restart (aber: braucht Admin) ### Mittel (kein direkter Bypass, aber schlechte Praxis / Competitor-Wissen) - **PowerShell-Teardown-Script vollständig im Binary:** Competitor kann Setup/Teardown exakt kopieren - **Mac `profiles remove` Kommando-Syntax im Binary:** Analog zum DNS-Profil-Removal - **`protection.json`-Pfad bekannt:** Komfort-Angriff ### Niedrig (kein operativer Bypass) - Base-URLs im Binary — ohnehin über Proxy/Network sichtbar - Service/Keychain-Namen — braucht lokalen Zugriff - Debug-Flags im Release-Build ### Kein Risiko - Removal-Password (server-gehalten, nicht im Binary) - AdGuard-Creds (Infisical-only) - JWT/mgc-Tokens (Keychain/Credential Manager) --- ## 3. Härtungs-Plan (priorisiert) ### Priorität 1 — Quick Wins (1–3 Tage Aufwand) #### 3.1 Windows `protection.json` ACL härten **Problem:** Datei unter `%ProgramData%\ReBreak\` ist für Standard-User lesbar. **Fix:** Im elevated Setup-Script ACL direkt nach dem Schreiben setzen: ```powershell $acl = Get-Acl $state_path $acl.SetAccessRuleProtection($true, $false) $rule = New-Object System.Security.AccessControl.FileSystemAccessRule("SYSTEM","FullControl","Allow") $acl.SetAccessRule($rule) $rule2 = New-Object System.Security.AccessControl.FileSystemAccessRule("Administrators","FullControl","Allow") $acl.SetAccessRule($rule2) # Standard-User: kein Zugriff Set-Acl $state_path $acl ``` **Effekt:** DNS-Token nicht mehr über Datei extrahierbar ohne Admin-Rechte. **Aufwand:** ~2h, nur `protection-core/src/lib.rs` + `setup.rs`-Script. Kein Backend-Change. #### 3.2 Debug-Code aus Mac Release-Build entfernen **Problem:** `DebugSupervisionMode` enum + Debug-Reset-Logik in `WizardModel.swift` ist im Release-Build sichtbar. **Fix:** `#if DEBUG` Guards um alle Debug-Felder und `startDebugReset()`-Methode. **Aufwand:** ~1h. #### 3.3 Service-Name verschleiern (Windows) **Problem:** `RebreakProtection` ist ein trivialer Stop-Angriff-Vektor. **Diskussion:** Echter Schutz dagegen ist unmöglich — jeder Service-Name kann in der Service-Liste gesehen werden. Aber: einen weniger offensichtlichen Namen verwenden (z.B. `rbkdnsd` oder `SystemDnsOptimizer`) erhöht die Hürde für Script-Kiddies. **Aufwand:** ~1h, aber Service-Name muss in protection-core, setup.rs, service/main.rs konsistent sein. + Re-Deploy. **Warnung:** Security-Theater-Komponente. Echter Schutz: Windows Protected Services (nächste Priorität). #### 3.4 Intern-Kommentar-Strings aus Mac-Binary entfernen **Problem:** Kommentare wie „app.rebreak.org hat aktuell falsches TLS-Zert" sind als Swift-String-Literals im Binary. **Fix:** Kommentare in Code-Kommentare umwandeln (nicht String-Literals), Infobox-Texte externalisieren. **Aufwand:** ~30min. --- ### Priorität 2 — Mittlerer Aufwand (1–2 Wochen) #### 3.5 Windows: Protected Service / PPL (Größter Tamper-Schutz) **Problem:** `sc.exe stop RebreakProtection` mit Admin reicht zum Bypass. **Lösung:** Windows Protected Processes / Service Protection Level. Via `sc.exe sdset` + DACL oder (besser) Service als **Protected Service** signieren — verhindert Stop/Delete auch durch lokale Admins. **Realistisch:** Echter PPL braucht Microsoft ELAM-Zertifikat (teuer + aufwändig). Alternativer Ansatz: **DACL-Restriktion** — Setup-Script entfernt die WRITE/STOP-Berechtigung von der "Administrators"-Gruppe auf dem Service-Object. Zwingt Angreifer zu mehr Aufwand (Token-Impersonation o.ä.). **Aufwand:** ~3 Tage (Recherche + Test auf verschiedenen Windows-Versionen). Hypothese, ungeprüft — Windows Service DACL-Manipulation braucht sorgfältiges Testing. **Eskalation an rebreak-ops für Deploy, kein Backend-Change nötig.** #### 3.6 Windows: PowerShell-Scripts verschlüsseln / nicht als String-Literal **Problem:** Kompletter Teardown-Pfad im Binary. **Lösung A (einfach):** Scripts zur Compile-Zeit mit einem festen XOR-Key oder AES-Key verschlüsseln, zur Laufzeit dekryptieren. Kein echter Schutz gegen entschlossenen Analysten, aber verhindert triviale `strings`-Analyse. **Security-Theater-Level ist hoch.** **Lösung B (besser):** PowerShell-Scripts server-seitig halten. Client pollt bei Setup ein signiertes Script-Template vom Backend, führt es aus. Vorteil: Scripts updatebar ohne App-Release. Nachteil: Offline-Setup geht nicht. **Empfehlung:** Lösung B für Teardown-Script (ohnehin server-getriggert), Lösung A für Setup (muss offline gehen). **Aufwand:** Lösung A ~1 Tag; Lösung B ~3 Tage (+ Backend-Endpoint). #### 3.7 Mac: Profil-Removal-Kommando nicht im Binary **Problem:** `profiles remove -identifier org.rebreak.protection.profile.*` im Source. **Kontext:** Diese Funktion wird bewusst für Testing/Reset verwendet (`MacProfileInstaller.remove()`). Im finalen User-Flow ist sie nicht mehr erreichbar. Trotzdem im Binary vorhanden. **Lösung:** `remove()` Methode in `#if DEBUG` wrappen. Im Release-Build nicht kompilieren. **Aufwand:** ~30min. #### 3.8 Pairing-Code: Rate-Limiting auf Backend **Problem:** 6-stelliger Code, 10min TTL. Aktuell kein explizites Rate-Limiting im `/api/magic/pair/redeem`-Endpoint sichtbar (IP-basiertes Rate-Limiting unklar). **Fix:** Max. 10 Redeem-Attempts pro IP + 5 pro Code, danach 429. Im Nitro-Middleware oder Endpoint. **Aufwand:** ~2h. Eskalation an rebreak-backend für generisches Rate-Limiting-Middleware falls noch nicht vorhanden. #### 3.9 `protection.json` DNS-Token verschlüsseln (Windows) **Problem:** DNS-Token liegt im Klartext in der JSON-Datei. **Lösung:** DNS-Token mit einem Geräteschlüssel (DPAPI unter Windows — `ProtectedData.Protect` mit `DataProtectionScope.LocalMachine`) verschlüsseln vor Speichern in `protection.json`. DPAPI bindet an die Machine — entschlüsselbar nur auf demselben Gerät, nicht auf einem anderen PC. **Effekt:** Datei-Exfiltration nützt nichts. Lokaler Admin-Zugriff für Entschlüsselung nötig (aber dann eh vorbei). **Aufwand:** ~2 Tage. Rust DPAPI via `windows-sys` Crate, braucht Windows-only Conditional Compilation. --- ### Priorität 3 — Größerer Umbau / Nice-to-Have #### 3.10 Binary-Obfuscation **Mac (Swift):** Swift hat keine etablierten Open-Source-Obfuskatoren. ProGuard-Äquivalent existiert nicht. Möglichkeiten: - Symbol-Stripping (ist Standard bei Release-Builds): reduziert Klassen/Methodennamen — bereits gut - `swiftc` mit Optimierungen + `strip` — kein echter RE-Schutz - Kommerzielle Tools (Obfusco, iXGuard) — teuer, fragile, selten Worth-it bei Swift **Windows (Rust):** Rust-Binaries sind nach Release-Kompilierung bereits gut obfusziert (keine Klassen/Methoden-Namen ohne DWARF-Symbole). String-Literale bleiben das Problem (siehe 3.6). Packer wie `UPX` sind möglich aber: - AV-Programme flaggen UPX-gepackte Binaries häufig - Kein echter Security-Gain gegen entschlossenen Analysten **Empfehlung:** Nicht investieren. ROI zu niedrig. Focus auf Secrets-Management + Service-Schutz. #### 3.11 Certificate Pinning für Backend-Calls **Aktuell:** Standard-TLS (kein Pinning). MITM-Angriff theoretisch möglich wenn User eigenes Root-Cert installiert. **Mac:** `URLSession` mit Custom `URLSessionDelegate` + Pinning auf `staging.rebreak.org`-Cert / SPKI. **Windows:** `reqwest` mit Custom Certificate Verifier. **Aufwand:** ~3 Tage. Wartungsaufwand hoch (Cert-Rotationen). Relevant vor allem wenn App auf `app.rebreak.org` (Prod) umgestellt wird. #### 3.12 Code-Signing Status **Mac (aktuell unbekannt):** Notarization-Status des `.app`-Bundles ist unklar. Ohne Notarization zeigt macOS Gatekeeper-Warning beim ersten Start. **Zuständigkeit: User + zied (Developer-ID Credentials).** **Windows (aktuell unbekannt):** Authenticode-Signatur des `.exe`. Ohne Signatur: SmartScreen-Warning bei Download/Start. Signatur mit EV Code Signing Cert (OV reicht nicht mehr für SmartScreen-Reputations-Aufbau). **Zuständigkeit: User + zied.** **Diese Punkte sind keine RE-Härtung, aber essentiell für User-Trust und Download-Conversion.** --- ## 4. Zusammenfassung nach Plattform ### Mac | # | Maßnahme | Aufwand | Priorität | |---|---|---|---| | 3.2 | Debug-Code aus Release entfernen | 1h | Quick Win | | 3.4 | Intern-Strings/Kommentare bereinigen | 30min | Quick Win | | 3.7 | `remove()` auf `#if DEBUG` | 30min | Mittel | | 3.11 | Cert-Pinning | 3 Tage | Nice-to-have | | 3.12 | Notarization (User/zied) | extern | Eskalation | ### Windows | # | Maßnahme | Aufwand | Priorität | |---|---|---|---| | 3.1 | `protection.json` ACL härten | 2h | Quick Win | | 3.3 | Service-Name weniger offensichtlich | 1h | Quick Win | | 3.5 | Service DACL-Restriktion (Prüfen) | 3 Tage | Mittel | | 3.6 | PS-Scripts nicht als Klartext-Strings | 1–3 Tage | Mittel | | 3.9 | DNS-Token DPAPI-verschlüsseln | 2 Tage | Mittel | | 3.12 | Authenticode-Signatur (User/zied) | extern | Eskalation | ### Backend | # | Maßnahme | Aufwand | Priorität | |---|---|---|---| | 3.8 | Pairing-Code Rate-Limiting | 2h | Quick Win | --- ## 5. Was die Härtung NICHT schützt (Grenzen klar kommunizieren) - **Admin-User kann alles aufheben.** Das ist kein Bug, das ist Windows und macOS. Der echte Schutz ist der Cooldown-Server + die Psychologie (24h reichen oft für den Impuls zu vergehen). - **Binary-Obfuscation ≠ Schutz.** Ein entschlossener Competitor mit einem Analysten und einem Tag Zeit kommt an alles ran. Das Ziel ist: erhöhte Hürde für Gelegenheits-RE, nicht Unmöglichkeit. - **Die Kern-Sicherheit liegt im Backend:** Token-Revocation ist server-seitig. Kein lokaler Angriff kann ein revoked Token reaktivieren. Das ist die richtige Architektur-Entscheidung und bleibt so. --- ## 6. Empfohlene Implementierungs-Reihenfolge 1. **Sofort (vor Public-Download):** 3.1 (ACL) + 3.2 (Debug-Guards) + 3.7 (Remove-Method) + 3.8 (Rate-Limiting) — zusammen ~1 Tag 2. **Sprint 1 (Woche 1):** 3.9 (DPAPI) + 3.6 Lösung A (Script-Obfuskation, keine echte Sicherheit aber reduziert Einblick) 3. **Sprint 2 (Woche 2–3):** 3.5 (Service-DACL, mit Test-Aufwand) + 3.11 (Cert-Pinning wenn auf Prod) 4. **Parallel, Founder/zied:** 3.12 Notarization + Authenticode — blockieren Download-Funnel ohne sie --- ## 7. Dateipfade für Implementierung **Quick Wins betreffen:** - `apps/rebreak-magic-win/src-tauri/protection-core/src/lib.rs` — ACL im Setup-Script-Generator, Service-Name - `apps/rebreak-magic-win/src-tauri/src/setup.rs` — ACL-Kommando im build_setup_script - `apps/rebreak-magic-mac/Sources/Models/WizardModel.swift` — #if DEBUG Guards - `apps/rebreak-magic-mac/Sources/Services/MacProfileInstaller.swift` — remove() in #if DEBUG - `apps/rebreak-magic-mac/Sources/Services/MagicAPIClient.swift` — Kommentar-Strings - `backend/server/api/magic/pair/redeem.post.ts` — Rate-Limiting