abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · gitea-restore-file-open
技术分析文章:https://abraxaslabs.tech/research/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 会跟随转储侧的符号链接。拼接路径仍位于转储目录之下,但符号链接不会。
运维人员恢复不可信转储时,会将符号链接目标复制到发布附件中。以 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 |
交给管理员一个不可信转储(一个“备份”目录,或从不可信远程恢复),其中在拼接于转储之下的路径处包含一个符号链接。恢复过程会将目标文件复制到恢复后仓库的发布附件中。任何能读取该仓库的人都可以下载它。
如果转储作者将文件命名为 app.ini,那就是凭据窃取(INTERNAL_TOKEN、SECRET_KEY、JWT、数据库密码)。实验环境中的判定依据是一个植入的见证文件,而非 app.ini。这不是操作系统本地提权,也不是未认证攻击,更不是转储根目录的拼接逃逸。从 GitHub/GitLab/Gitea 进行的实时迁移会设置 DownloadFunc,并且不会对攻击者提供的 file:// 执行 os.Open。
两张恢复映射表留在了遗留表上。我先对最明显的那张做了实验。
发现 8 是转储根目录拼接逃逸:在 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 拼接的结果仍为 /tmp/dump/tmp/GITEA-JOIN-OUTSIDE。恢复过程在转储之下重写了 file://,并因 open ...: no such file or directory 而失败。在该标签上这不是拼接逃逸。
发现 9 才是最终成立的。我在转储之外植入了一个见证文件,在拼接于转储之下的路径处放置了一个符号链接,然后运行 gitea restore-repo。恢复返回码为 0。恢复后的发布附件中包含 GITEA-FILE-OPEN-WITNESS。
已记录的弯路:通过绝对路径 DownloadURL 实现转储根目录拼接逃逸;实时迁移 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://,或拒绝跟随 dump 符号链接,并且不要恢复不受信任的 dump。恢复的附件不得包含 dump 之外的见证文件。
uri.go · gitea_uploader.go · FilePathJoinAbsGNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境。不提供任何担保。