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:
- 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. - Three-Way-Merge-Fallback: Wenn
git applyauf 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. - 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. - 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
gitodergitea).
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 anlegenREGISTER_EMAIL_CONFIRM = false(Default) — keine E-Mail-Bestätigung nötigENABLE_OPENID_SIGNUP = true— auch OpenID-RegistrierungREQUIRE_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 aufgerufen14:25:16— Konto erstellt14:25:17— Privates Repository angelegt14:25:18— Branch-Info abgefragt14:25:19— Ersterdiffpatch-Aufruf14:25:20— Zweiterdiffpatch-Aufruf14:25:23— Branchrce-prooferstellt14:25:24— Datei in/tmperzeugt14: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
idaus → stdout wird zu einem Git-Objekt → commit →refs/heads/rce-proof - Scanner ruft
GET .../raw/proof?ref=rce-proofab — 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_PRELOADundLD_LIBRARY_PATHbereinigen (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:
- Update auf 1.27.2 (oder mindestens 1.27.1). Keine Ausreden.
- Registrierung deaktivieren —
DISABLE_REGISTRATION = trueinapp.ini, ausser du brauchst sie wirklich. - Prüfen, ob die Instanz bereits kompromittiert wurde — Container-Logs auf ungewöhnliche Registrierungen, verdächtige Repositories,
/tmp-Dateien, hohe CPU-Last checken. - 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: