文章首发于先知https://xz.aliyun.com/t/3725
群里发了个gitea rce的issus,跟进看了一下,顺便记录一下
12-26:好像gitea和gogs都修复的差不多了,应该可以发了8
分析commit
当时(12-20)gitea还没修复,gogs有commit,分析commit
![](http://upload-images.jianshu.io/upload_images/16539702-d4cb20e675f4785c.png)
![](http://upload-images.jianshu.io/upload_images/16539702-583e179f24fae4b0.png)
猜想是跨目录上传伪造的管理员session文件,覆盖当前的session文件,导致权限提升
分析代码
![](http://upload-images.jianshu.io/upload_images/16539702-780141d051532804.png)
首先上传一个文件,如果上传成功,就会在数据库中存入这条数据(351行)
![](http://upload-images.jianshu.io/upload_images/16539702-2495cad1be0ce04f.png)
![](http://upload-images.jianshu.io/upload_images/16539702-10dc5359543a669d.png)
从表单中获取刚刚上传文件的uuid,传入UploadRepoFiles中
![](http://upload-images.jianshu.io/upload_images/16539702-edf7df560e9245f9.png)
从数据库中获得刚刚文件的数据结构(uuid, 文件名)
![](http://upload-images.jianshu.io/upload_images/16539702-7a9d07179c7b5e1d.png)
目标路径和文件名进行拼接,然后将上传的文件cp到目标文件夹下
问题就出在这里,因为文件名可控并且没有过滤../
,所以就可以控制targetPath
,造成目录穿越,将这个文件上传到我们想传的任何地方(权限允许)。所以可以生成一个管理员session文件,上传到当前的session文件夹下uid[0]/uid[1]
,uid已知就在cookie里
![](http://upload-images.jianshu.io/upload_images/16539702-171811b47ea1bf5b.png)
验证
已知管理员用户名为: luckycat
用ph师傅的go程序生成管理员session link
然后新建一个仓库,选择上传文件
上传刚刚生成的session文件,用burp拦截,将文件名改为正好能穿越到当前用户的session文件夹下,上传完文件后,提交变更后,发现已经成为管理员了
![](http://upload-images.jianshu.io/upload_images/16539702-f52dbea85d046ea1.png)
RCE部分使用git hook来进行
绕过
gogs最初的修复(12-20)存在绕过
https://github.com/gogs/gogs/commit/8c8c37a66b4cef6fc8a995ab1b4fd6e530c49c51
这里归功于@spine和@HeartSky的细心发现
![](http://upload-images.jianshu.io/upload_images/16539702-742e83d9b4b772d0.png)
这...标准的CTF过滤,进行组合就能绕过
https://play.golang.org/p/z8ZWQYbLVCO
参考
https://www.leavesongs.com/PENETRATION/gitea-remote-command-execution.html
有疑问加站长微信联系(非本文作者)
![](https://static.golangjob.cn/static/img/footer.png?imageView2/2/w/280)