abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · gitea-restore-file-open
Gitea 1.27.3 - Gitea
CVE-2026-59765 在 OpenWithClient 上放置了一个 hostmatcher HTTP 客户端。file:// 分支忽略该客户端并调用 os.Open。转储的恢复没有 DownloadFunc。gitea_uploader.go 随后打开重写后的 file:// URL。os.Open 会跟随转储侧符号链接。Join 保持在转储目录下。符号链接则不然。
操作员恢复不受信任的转储时,会将符号链接目标复制到发布附件中。以 Gitea uid 身份,即服务账户可读取的任何文件。
| ID | 暂无 CVE |
| CWE | CWE-73 |
| CVSS | 中危:4.2 CVSS:3.1/AV:L/AC:L/PR:H/UI:R/S:U/C:H/I:N/A:N |
| 产品 | Gitea |
| 受影响版本 | 至 v1.27.3(146cc3e);本地操作员 gitea restore-repo |
| 认证 | 本地操作员恢复不受信任的转储 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1 |
交给管理员一个不受信任的转储(一个“备份”目录,或从不受信任的远程恢复),其中在 join 到转储下的路径处包含一个符号链接。恢复会将目标文件复制到被恢复仓库的发布附件中。任何能读取该仓库的人都可以下载它。
如果转储作者将其命名为 app.ini,那就是凭据窃取(INTERNAL_TOKEN、SECRET_KEY、JWT、数据库密码)。实验环境中的验证物是一个植入的见证文件,而非 app.ini。这不是操作系统本地提权。这不是未认证攻击。这不是转储根目录 join 逃逸。从 GitHub/GitLab/Gitea 进行的实时迁移会设置 DownloadFunc,并且不会对攻击者的 file:// 执行 os.Open。
遗留表上有两个恢复映射。我先对最明显的那个做了实验。
发现 8 是转储根目录 join 逃逸:在 release.yml 中放入一个绝对路径的 DownloadURL,期望 FilePathJoinAbs 像朴素的 filepath.Join(base, "/etc/passwd") 那样丢弃转储前缀。在 1.27.3 上它并不会。每个 sub 先经过 filepath.Clean("/"+s),然后 filepath.Join(base, cleaned)。/tmp/dump + /tmp/GITEA-JOIN-OUTSIDE 的副本 join 结果仍为 /tmp/dump/tmp/GITEA-JOIN-OUTSIDE。恢复将 file:// 重写到转储目录下,并失败于 open ...: no such file or directory。在这个标签上这不是 join 逃逸。
发现 9 才是最终成功的。我在转储目录外植入了一个见证文件,在 join 到转储下的路径处放置了一个符号链接,运行了 gitea restore-repo。恢复 rc=0。被恢复的发布附件中包含 GITEA-FILE-OPEN-WITNESS。
已记录的弯路:通过绝对路径 DownloadURL 进行转储根目录 join 逃逸;实时迁移 file:// 本地文件包含;X-Gitea-Internal-Auth(恢复是以 Gitea uid 运行的 CLI,而非 /api/internal);将恢复 HTTP 视为远程未认证(CVSS 是本地、高权限、需要用户交互);反弹 shell。都是表演。
cd lab
./run.sh
目标仅限 http://127.0.0.1:18137。Compose 以只读方式挂载 lab/dump。run.sh 在容器内植入见证文件,构建转储,放置符号链接,然后执行 gitea restore-repo。
restore-rc=0 Restore repo labadmin/restored successfully
download status=200 snippet=GITEA-FILE-OPEN-WITNESS
SUCCESS GITEA-RESTORE-FILE-OPEN
从 OpenWithClient 中移除 file://,或拒绝跟随转储符号链接,并且不要恢复不受信任的转储。被恢复的附件不得包含转储目录外的见证文件。
uri.go · gitea_uploader.go · FilePathJoinAbsGNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境。无担保。