11 Sekunden bis RCE: Kritische Gitea-Lücke aktiv ausgenutzt — mit Krypto-Miner als Beute

Was passiert ist

Die US-Behörde CISA hat am 25. August 2026 die kritische Sicherheitslücke CVE-2026-60004 (CVSS 9.8) in ihrer Known Exploited Vulnerabilities (KEV) gelistet. Das bedeutet: Die Lücke wird aktiv im Feld ausgenutzt. US-Bundesbehörden müssen bis zum 28. August patchen.

Betroffen ist Gitea — die schlanke, selbst hostbare Git-Plattform, die als Open-Source-Alternative zu GitHub und GitLab beliebt ist. Die Lücke ermöglicht Remote Code Execution (RCE): Wer Schreibzugriff auf ein Repository hat, kann beliebige Shell-Befehle als Gitea-Systemuser ausführen. Unter Default-Konfiguration — offene Registrierung — reicht ein anonymer Besucher, der sich ein Konto anlegt.

Entdeckt wurde die Lücke von Sicherheitsexperte Shai rod (NightRang3r). Sie betrifft alle Gitea-Versionen ab 1.17.0 und wurde in 1.27.1 gepatched. Aktuell ist 1.27.2.

Die technische Mechanik

Der Angriff nutzt Giteas diffpatch-API-Endpoint (POST /api/v1/repos/{owner}/{repo}/diffpatch). Die Funktionsweise in Kurzfassung:

  1. Temporäres Bare-Repository: Gitea legt beim Patchen ein temporäres Bare-Git-Repo an. Bei einem Bare-Repo ist das Root-Verzeichnis gleichzeitig $GIT_DIR — es gibt keinen separaten Working Tree.
  2. Three-Way-Merge-Fallback: Wenn git apply auf mehrdeutige Patches stösst, schaltet Git auf einen Three-Way-Merge-Fallback um. Dabei kann Git unter bestimmten Konfliktbedingungen Dateien ausserhalb des eigentlichen Staging-Bereichs auf die Platte schreiben — mit Pfaden relativ zum Repository-Root.
  3. Hook-Injection: Ein gezielt präparierter Patch schreibt eine ausführbare Datei nach hooks/post-index-change — ein Git-Hook, der automatisch beim nächsten Index-Update ausgeführt wird.
  4. Ausführung: Sobald Gitea den nächsten internen Git-Befehl auf dem temporären Repo ausführt, feuert der Hook. Der Angreifer läuft jetzt als Gitea-Systemuser (meist git oder gitea).

Das ist elegant und brutal zugleich. Der Angreifer braucht keinen Zero-Day im klassischen Sinne — er nutzt das Zusammenspiel aus Git-Standardverhalten (Three-Way-Merge-Fallback) und Giteas Architektur (Bare-Repo als temporärer Workspace).

Die Default-Falle: Offene Registrierung

Technisch gesehen erfordert die Lücke Schreibzugriff auf ein Repository. Das klingt nach einem eingeschränkten Angriffsvektor — ist es aber nicht, weil Gitea standardmässig offene Registrierung erlaubt:

  • DISABLE_REGISTRATION = false (Default) — jeder kann sich ein Konto anlegen
  • REGISTER_EMAIL_CONFIRM = false (Default) — keine E-Mail-Bestätigung nötig
  • ENABLE_OPENID_SIGNUP = true — auch OpenID-Registrierung
  • REQUIRE_SIGNIN_VIEW = false — Seiten ohne Login sichtbar

Die Angriffskette wird damit praktisch Pre-Auth: Anonymer Besucher → Konto erstellen → Repository anlegen → Schreibzugriff haben → diffpatch missbrauchen → RCE. Fertig.

Der echte Vorfall: 11 Sekunden bis zur Übernahme

Ein russischer Entwickler hat auf Habr einen detaillierten Incident Report veröffentlicht. Seine selbst gehostete Gitea-Instanz (Version 1.24.7) wurde angegriffen. Die aktive Phase dauerte etwa 11 Sekunden:

  • 14:25:16 — Registrierungsformular aufgerufen
  • 14:25:16 — Konto erstellt
  • 14:25:17 — Privates Repository angelegt
  • 14:25:18 — Branch-Info abgefragt
  • 14:25:19 — Erster diffpatch-Aufruf
  • 14:25:20 — Zweiter diffpatch-Aufruf
  • 14:25:23 — Branch rce-proof erstellt
  • 14:25:24 — Datei in /tmp erzeugt
  • 14:25:27 — Proof-of-Concept abgerufen

Das war ein automatisierter Scanner, kein gezielter Angriff. Der Server wurde nicht wegen seines Inhalts ausgewählt — er hatte einfach den richtigen Fingerprint: Gitea + verwundbare Version + offene Registrierung.

Die Proof-of-Concept-Methode

Besonderer Clou: Der Angreifer nutzte Git selbst als Rückkanal. Anstatt HTTP-Callbacks oder DNS-Exfiltration zu verwenden, lief der Proof über Git:

  • Hook führt id aus → stdout wird zu einem Git-Objekt → commit → refs/heads/rce-proof
  • Scanner ruft GET .../raw/proof?ref=rce-proof ab — fertig

Das ist für Massen-Scanning ideal: Exploit feuert → Branch erscheint → Proof lesen → nächster Host. Keine externen Abhängigkeiten.

Stage 2: Der Krypto-Dropper

Nach dem RCE-Proof startete der Hook im Hintergrund die eigentliche Nutzlast. Die Ladungskette:

Stage 0 (Git-Hook) → base64 decodieren → Shell-Loader starten

Stage 1 (Shell-Loader) — probiert reihum Download-Tools: curl → wget → python3 urllib → perl HTTP::Tiny → perl IO::Socket::INET

Der Autor wusste nicht, was auf dem Zielsystem verfügbar ist — also versucht er alles. Pragmatisch.

Stage 2 (Miner-Dropper) — der eigentliche Schaden:

  • LD_PRELOAD und LD_LIBRARY_PATH bereinigen (Anti-Detection)
  • Prozesse mit hoher CPU-Last suchen und killen (Konkurrenz ausschalten)
  • Payload passend zur Systemarchitektur herunterladen
  • Binary unter zufälligem 8-Zeichen-Namen speichern
  • Ausführen, Datei danach löschen

Der Server-Betreiber wurde durch eine E-Mail seines Hosters HOSTKEY aufmerksam: CPU-Auslastung über 70% über längere Zeit — ein Verstoß gegen die Nutzungsbedingungen. Der Hoster drosselte die Ressourcen.

Was der Angreifer nicht fand

Gute Nachrichten aus dem Incident: Der Gitea-Container war nicht privilegiert. Nach Container-Restarts überlebte der Miner-Prozess nicht. Keine Persistenz über cron, systemd oder neue SSH-Keys wurde gefunden. Der Angriff war also nicht-persistent — solange der Container neu startet, ist der Miner weg.

Das ist aber Glück, kein Verdienst. Hätte der Angreifer Persistenz gewollt, hätte er sie mit dem RCE-Zugriff wahrscheinlich auch erreichen können.

Maßnahmen

Wenn Gitea im Einsatz ist — egal ob selbst gehostet oder als Container:

Sofort:

  1. Update auf 1.27.2 (oder mindestens 1.27.1). Keine Ausreden.
  2. Registrierung deaktivieren — DISABLE_REGISTRATION = true in app.ini, ausser du brauchst sie wirklich.
  3. Prüfen, ob die Instanz bereits kompromittiert wurde — Container-Logs auf ungewöhnliche Registrierungen, verdächtige Repositories, /tmp-Dateien, hohe CPU-Last checken.
  4. Alle Secrets rotieren — API-Keys, OAuth-Credentials, Datenbankpasswörter. Wenn jemand RCE hatte, muss man davon ausgehen, dass alles im Container zugänglich war.

Strukturell: 5. Outbound-Traffic aus Application-Containern einschränken — der Miner brauchte Internetzugang zum Download. Ohne den wäre Stage 2 ins Leere gelaufen. 6. REQUIRE_SIGNIN_VIEW = true — zwingt Login vor jeder Seitenanzeige. 7. REGISTER_EMAIL_CONFIRM = true — erschwert automatisierte Kontoerstellung. 8. Keine offene OpenID-Registrierung — ENABLE_OPENID_SIGNUP = false.

Einordnung

Drei Beobachtungen:

1. Self-hosted bedeutet selbst verantwortlich. Gitea ist beliebt, weil es leicht aufzusetzen ist. Aber leicht aufzusetzen heisst nicht leicht abzusichern. Die Default-Config ist auf Bequemlichkeit getrimmt — offene Registrierung, keine E-Mail-Bestätigung, keine CAPTCHA. Für ein internes Development-Tool mag das funktionieren. Für eine öffentlich erreichbare Instanz ist es ein Einladungsschreiben.

2. Der Angriff war nicht persönlich. Der Habr-Bericht macht klar: Das war ein automatisierter Scanner, der systematisch nach verwundbaren Gitea-Instanzen sucht. Der Server des Entwicklers war nicht das Ziel einer gezielten Attacke — er hatte einfach den richtigen Fingerprint. Wer denkt, sein kleiner self-hosted Server sei zu unbedeutend für Angreifer, irrt sich. Für Scanner existiert kein «zu klein».

3. 11 Sekunden. Von der Registrierung bis zum Proof-of-RCE vergingen 11 Sekunden. Das ist die Zeit, in der ein Mensch gerade mal ein Login-Formular ausfüllen würde. Automatisierung macht Angriffe nicht nur möglich — sie macht sie sofort. Wer auf manuelle Erkennung von Angriffen vertraut, ist immer zu langsam.


Quellen: