Gitea 1.4.0 目录穿越导致命令执行漏洞


Gitea 1.4.0 目录穿越导致命令执行漏洞

Gitea是从gogs衍生出的一个开源项目,是一个类似于Github、Gitlab的多用户Git仓库管理平台。其1.4.0版本中有一处逻辑错误,导致未授权用户可以穿越目录,读写任意文件,最终导致执行任意命令。

漏洞原理

参考来源:leavesongs

漏洞一、 逻辑错误导致权限绕过

这是本漏洞链的导火索,其出现在Git LFS的处理逻辑中。

Git LFS是Git为大文件设置的存储容器,我们可以理解为,他将真正的文件存储在git仓库外,而git仓库中只存储了这个文件的索引(一个哈希值)。这样,git objects和.git文件夹下其实是没有这个文件的,这个文件储存在git服务器上。gitea作为一个git服务器,也提供了LFS功能。

在 modules/lfs/server.go 文件中,PostHandler是POST请求的处理函数:

可见,其中间部分包含对权限的检查:

if !authenticate(ctx, repository, rv.Authorization, true) {
    requireAuth(ctx)
}

在没有权限的情况下,仅执行了requireAuth函数:这个函数做了两件事,一是写入WWW-Authenticate头,二是设置状态码为401。也就是说,在没有权限的情况下,并没有停止执行PostHandler函数。

所以,这里存在一处权限绕过漏洞。

漏洞二、目录穿越漏洞

这个权限绕过漏洞导致的后果是,未授权的任意用户都可以为某个项目(后面都以vulhub/repo为例)创建一个Git LFS对象。

这个LFS对象可以通过http://example.com/vulhub/repo.git/info/lfs/objects/[oid]这样的接口来访问,比如下载、写入内容等。其中[oid]是LFS对象的ID,通常来说是一个哈希,但gitea中并没有限制这个ID允许包含的字符,这也是导致第二个漏洞的根本原因。

我们利用第一个漏洞,先发送一个数据包,创建一个Oid为....../../../etc/passwd的LFS对象:

POST /vulhub/repo.git/info/lfs/objects HTTP/1.1
Host: your-ip:3000
Accept-Encoding: gzip, deflate
Accept: application/vnd.git-lfs+json
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 151

{
    "Oid": "....../../../etc/passwd",
    "Size": 1000000,
    "User" : "a",
    "Password" : "a",
    "Repo" : "a",
    "Authorization" : "a"
}

其中,vulhub/repo是一个公开的项目。

也就是说,这个漏洞的利用是有条件的,第一个条件就是需要有一个公开项目。为什么呢?虽然“创建LFS对象”接口有权限绕过漏洞,但是“读取这个对象所代表的文件”接口没有漏洞,会先检查你是否有权限访问这个LFS对象所在的项目。只有公开项目才有权限读取。

见下图,发送数据包后,虽然返回了401状态码,但实际上这个LFS对象已经创建成功,且其Oid为....../../../etc/passwd

第二步,就是访问这个对象。访问方法就是GET请求http://example.com/vulhub/repo.git/info/lfs/objects/[oid]/sth,oid就是刚才指定的,这里要用url编码一下。

研究一下原理:
代码 modules/lfs/content_store.go :

可见,meta.Oid被传入transformKey函数,这个函数里,将Oid转换成了key[0:2]/key[2:4]/key[4:]这样的形式,前两个、中间两个字符做为目录名,第四个字符以后的内容作为文件名。

那么,我创建的Oid....../../../etc/passwd,在经过transformKey函数后就变成了../../../../../etc/passwd,s.BasePath是LFS对象的基础目录,二者拼接后自然就读取到了/etc/passwd文件。

这就是第二个漏洞:目录穿越。


文章作者: Geekby
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Geekby !
 上一篇
Gitlab 任意文件读取漏洞 Gitlab 任意文件读取漏洞
Gitlab 任意文件读取漏洞(CVE-2016-9086)Gitlab版本:8.13.1原理剖析:http://paper.seebug.org/104/ 漏洞复现环境运行后,Web端口为10080,ssh端口为10022。访问http:
2019-02-17
下一篇 
GIT-SHELL 沙盒绕过(CVE-2017-8386) GIT-SHELL 沙盒绕过(CVE-2017-8386)
GIT-SHELL 沙盒绕过(CVE-2017-8386)GIT-SHELL 沙盒绕过(CVE-2017-8386)导致任意文件读取、可能的任意命令执行漏洞。 参考链接: https://insinuator.net/2017/05/gi
2019-02-16
  目录