认证后命令执行

Gitlab本身包含图片上传功能,所以按照上文构造思路,很容易实现RCE。

首先修改djvu命令为curl指令,生成文件后修改为图片后缀名。

使用用户登录Gitlab,新建一个工程。

然后建一个issue,点击`attach a new file`导入图片,命令随即被执行。

新建issue和工程需要用户权限,存在一定的限制。

认证绕过探索

通常来讲,像Gitlab这样通用的框架图片上传解析应该都是需要认证的,但是经过深入分析,发现了无需认证的接口。由于信息并没有公开,这里尝试利用自己的思路寻找一种无需认证图片上传的办法,复盘整个漏洞分析过程。

查阅Gitlab官方文档:

user_file_uploads.html
https://docs.gitlab.com/ee/security/user_file_uploads.html

在`Administrator users/User file uploads`中说明了用户文件上传的规则,其中`Non-image attachments do require authentication to be viewed`这句话显得很突出。大体来说就是Gitlab为了支持电子邮件正文中图片的处理,设计上认为图片上传无需用户认证。

从Gitlab官网下载v13.10.2-ce版本源码,全文搜索`upload`和`user`字段,找到了`/uploads/user`接口:

全文搜索`/uploads/user`,在routes.go中找到路由映射:

按照`snippetUploadPattern`往后跟并没有找到引用链,而`/uploads/user`接口处理代码位于`uploads_controller`中。

测试`/uploads/user/`GET请求返回404,但POST请求返回422错误:

使用`gitlab-ctl tail`命令查看日志,显示`InvalidAuthenticityToken`。

搜索代码,请求必须必须加上`HTTP_X_CSRF_TOKEN`。

添加X-CSRF-TOKEN后显示404:

尝试向该接口发送图片文件,然后抓包修改报文,将登录用户的Cookie和XSRF-TOKEN设置好,诡异得返回了`Faild to Process image`,说明图片已经被处理,而且不验证传输文件的变量名:

以上步骤还是需要用户认证的,那么怎样不需要认证呢。查看登录页面`/users/sign_in`,同样返回了Cookie信息,且页面中包含csrf-token:

使用登录页面返回的Cookie值和csrf-token值,成功实现RCE。

至此未授权图片解析复现成功,进而实现RCE,这里就不进行代码分析了,有兴趣的小伙伴可以自行下载源代码调试学习。

漏洞修复

主要修补了exif图片处理模块。

修补后,请求返回404。

最后记得升级GitLab到最新版本。