本文首发 奇安信攻防社区奇安信攻防社区-CVE-2025-8110 0day 绕过分析与复现
本文从gogs历史漏洞点入手,结合gogs源码对最新CVE-2025-8110 0day的绕过手法进行分析,结合复现过程给出CVE-2025-8110 0day的正确POC
前情提要
gogs是一款由go语言编写的一款极易搭建的自助 Git 服务.golang的一些web应用最常见出现的问题就是目录穿越了,同样观察前面gogs大部分的历史漏洞都是目录穿越然后覆盖关键文件造成RCE.今天这个CVE-2025-8110 同样也不例外!本质还是任意文件写入漏洞
据披露者的博客来看是在七月的一次应急过程中观察到的,截止到12/14 Github公开的都是错误的POC
影响范围
-
直到最新版本仍未修复
-
根据Fofa来看大概受影响资产为5w左右(可能大部分都是自建在内网?)
利用条件
-
存在
PUT推送接口 -
可以任意注册用户
-
部署在Linux系统
分析
漏洞点
主要是看internal/database/repo_editor.go 这个文件中的UpdateRepoFile 函数
可以看到作者在这个文件上修复了12处,属于是事故高发区了
我们看到该文件的第191行,未对filePath 参数做任何校验
可以看到该函数的签名 WriteFile(name string, data []byte, perm FileMode)
第一个就是目标的文件名了,第二个是写入的数据,第三个是Mode
本身按照gogs的意思就是当仓库的变更时,gogs则会根据文件名写入变更后的新内容到磁盘,因此这个filePath 就是我们仓库里的一个文件名,这肯定是天然可控的~
将这个逻辑抽离出来看看写一个POC
-
首先创建一个软链接
-
运行下面POC
main.go
1 | package main |
可以发现我们symlink软链接指向的origin文件被创建了,并且写入了我们指定的内容.当然这也符合软链接本身的正常用法,不是语言本身的问题.
所以只要我们将这个文件名指向一个符号链接即可,这在git里是可以的
这是git 用来表现符号链接的tree 对象
说白了就是我们可以提交一个提前在本地指向好的符号链接,并且gogs也是可以识别的.
那么在触发对这个文件进行变更时,gogs就会调用WriteFile函数进行写入,且写入的路径是我们最终指向的路径.*
上述的都是符号链接文件,可以看到相关的图标也有指示
ok,漏洞点就是这些了,那我们再来看看触发点~
触发点
与CVE-2024-55947是同一个位置.
先看看UpdateRepoFile 函数的用法,总共3个*
根据前面的历史漏洞可以看到,就是PUT /repos/:username/:reponame/contents/* 触发的,同样这个地方也是*
跟进到internal/route/api/v1/repo/contents.go 看到 PutContents 函数
上面还有之前对CVE-2024-55947 路径穿越的修复,也就是文件路径参数净化
这是Clean函数的实现
1 | func Clean(p string) string { |
但是本次漏洞的成因是软链接,所以这种修复方式自然是拦不住我们的
分析总结
本质是通过上传一个符号链接文件,然后通过put接口触发Update,然后写入的目标路径会是符号链接所指向的最终路径,导致任意文件写入(覆盖).
漏洞复现
环境搭建
docker 拉取镜像启动即可,加速问题自己解决()
这里给出启动参数
1 | docker run -d \ |
启动之后访问3000端口完成安全,注意安装数据选sqlite数据库即可然后不用在下面填管理员用户
安装完成后,我们只需后续在主页注册一个普通用户即可.
注册完成后登录,进入右上角头像处的用户设置,填入自己的ssh公钥即可,为我们后续推送恶意符号文件做准备.
再点击下面的授权应用生成一个令牌,我们后续PUT推送时需要用到
为了方便后续拉取镜像触发sshCommand(选做)
测试ssh是否连通,判断是否可以通过ssh git推送文件
ssh -T -p 2022 git@localhost
绑定 ~/.ssh/config
1 | Host gogs |
本地挂几个软链接符号文件.
创建一个本地仓库,并绑定到远程
可按照下面指示操作
给出我用过的几个命令
1 | git init repo |
这是我本地创建完的样子
然后推送到远端即可
可以看到符号链接的内容为我们想写入恶意内容的文件路径.
然后发送以下PUT数据包
1 | PUT /api/v1/repos/test/aaa/contents/secret-link HTTP/1.1 |
中间的content为echo "Hacked" >> /etc/passwd 的base64编码形式,注意自己是什么分支,默认是master分支!
注意指定的文件路径,对应到仓库页面
复现结果
来到docker容器内更便于我们观察
任意文件写入
可以看到正是将我们本地仓库创建的一个指向/tmp/pwned (手太快了,多打了个字~)的符号链接文件上传了,并且在目标机器上也同样生效
可以看到成功创建并写入了我们的恶意命令
RCE
披露者是通过覆写.git/config 文件来触发RCE的.
本质是仓库拥有者通过ssh协议对仓库做clone,pull等操作时触发恶意命令,所以还是需要搭配仓库所有者自己主动操作仓库时才可触发.这里就以我们自己注册的普通test 用户触发.
1 | [core] |
然后PUT执行即可触发!
修复
目前作者还没有进行修复,好像好久没更新了~
如图, 哈哈哈哈哈
目前观察到的缓解措施就是停止任意用户的注册,相当于是把触发点入口给断了吧
参考
https://www.wiz.io/blog/wiz-research-gogs-cve-2025-8110-rce-exploit