7

CVE-2019-11229详细分析 --git config可控-RCE

 3 years ago
source link: https://lorexxar.cn/2019/07/23/gitea-cve-2019-11229/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

CVE-2019-11229详细分析 --git config可控-RCE



字数统计: 1.6k阅读时长: 6 min
 2019/07/23  76  Share

2019年4月15号,gitea曾爆出过一个漏洞,恰逢当时对这个漏洞比较好奇就着手去研究了一下,漏洞的描述是这样的:

models/repo_mirror.go in Gitea before 1.7.6 and 1.8.x before 1.8-RC3 mishandles mirror repo URL settings, leading to remote code execution.

在和朋友@hammer的一同研究下,成功控制了git config的内容,但是在从git config到RCE的过程遇到了困难,就暂时搁置了,在过了几个月之后,偶然得到@Lz1y和@x1nGuang两位大佬的启发,成功复现了这个漏洞,下面我们就来仔细研究下这个问题。

首先根据cve的信息,确定漏洞1.7.6和1.8.0-rc3上修复

根据漏洞文件为repo_mirror.go这个信息锁定更新的commit,commit主要为 #6593和#6595

根据patch可以大致锁定问题的关键点

/models/repo_mirror.go

当仓库为mirror仓库时,settings页面会显示关于mirror的配置

if !repo.IsMirror {
ctx.NotFound("", nil)
return
}

patch中将原来的修改配置文件中的url选项修改为NewCommand。很容易理解,将写入文件更改为执行命令,这种修复方式一定是因为写入文件存在无法修复这个问题的窘境,那么这也就说明url这里可以通过传入%0d%0a来换行,导致修改config中的其他配置。

控制gitconfig

跟随前面的逻辑,首先我们新建一个mirror仓库。

抓包并修改mirror_address为相应的属性。

mirror_address=https%3A%2F%2Ftest%3A%40github.com%2FLoRexxar%2Ftest_for_gitea.git"""%0d%0a[core]%0d%0atest=/tmp%0d%0aa="""

可以传入各种配置,可以控制config文件的内容。

比较有趣的是,如果你更新同步设置时,服务端还会格式化配置。

进一步利用

而重要的是如何从config文件可控到下一步利用。

首先,git服务端只会保留.git里的内容,并不是完整的类似我们客户端使用的git仓库。所以很难引入外部文件。否则就可以通过设置hook目录来实现RCE,这种思路的关键点在于找到一个可控的文件写入或者文件上传。

其次,另外一种思路就是寻找一个能够执行命令的配置,并寻找一个能够触发相关配置的远程配置。

通过写文件配合githook path RCE

在git中,存在一个叫做Git Hook的东西,是用于在处理一些操作的时,相应的hook就会执行相应的脚本。

在web界面,只有gitea的管理员才能管理git hook,所以对于普通用户来说,我们就不能直接通过编辑git hook来修改脚本。

但我们却可以通过控制git config来修改hook存放的目录。

当我们构造发送

mirror_address=https%3A%2F%2Fgithub.com%2FLoRexxar%2Ftest_for_gitea.git"""%0d%0a[core]%0d%0ahooksPath=/tmp%0d%0aa="""

服务端的config文件变为

这样我们只要能在服务端的任意位置能够写入文件或者创建文件,我们就可以设置hookspath到那里,并触发git hook来执行命令。

在经过我们的仔细研究之后,我们发现,在漏洞存在的版本1.7.5版本以下,如果编辑服务端的文件,那么服务端的文件就会保存在gitea的运行目录下生成。

/data/tmp/local-repo/{repo_id}

而这个文件在不重启gitea的情况下不会清除,而这个repo_id可以从其他的api处挖掘到。

具体详细利用链可以看

值得注意的是,这种方式需要知道服务端运行的位置,虽然我们可以认为go的路径都是比较形似的,也有部分人会在当前编译目录下执行。但可以说这种方式还是不算靠谱。

通过控制git config配置来RCE

在@x1nGuang大佬的帮助下,我重新审视了和git config相关的一些配置。

gitProxy

gitProxy是用来针对git协议需要fetch等操作时,需要执行的命令。是一个用来应对特殊场景的配置选项。一般是应用于,在git请求时,可能的需要使用代理应用的场景。

这里我们设置服务端

[core]
gitproxy = calc.exe

然后需要注意,同步的url必须为git开头

但问题在于,由于gitProxy在git设计中,就是执行一个代理应用,所以无论输入什么,都会被当作一个应用执行,也就没办法带参数。

这样一来,在实际的利用场景中就又收到了很大的局限,这里可以尝试用普通项目中的上传文件功能来上传一个bin,然后抓包获取文件路径,最后通过gitProxy来执行后门。

但同样的是,这种思路仍旧受限于gitea的运行目录,不过比起之前的利用方式来说,1.8.0版本也可以利用这种方式来RCE。

sshCommand

在git的文档中,还有一个配置是sshCommand。

这是一个在git中允许通过特殊的配置,使git fetch/git push 通过ssh来连接远端的系统。在@Lz1y大佬的博客中也提到了这种利用方式。

我们设置sshCommand为指定的命令

mirror_address=https%3A%2F%2Ftest%3A%40github.com%2FLoRexxar%2Ftest_for_gitea.git"""%0d%0a[core]%0d%0asshCommand=calc.exe%0d%0aa="""

然后设置协议为ssh保存,并点击同步。

而与gitProxy不同的是,这里可以跟参数

&mirror_address=https%3A%2F%2Ftest%3A%40github.com%2FLoRexxar%2Ftest_for_gitea.git"""%0d%0a[core]%0d%0asshCommand="touch 2333"%0d%0aa="""

这是一个很特别的关于git类平台的漏洞例子,由于我在研究git config利用方式的时候遭遇了很多困难,导致这篇文章断断续续的复现了很久。整个漏洞利用链和git的特性都有强依赖,还算是挺有趣的体验,有机会再仔细分析一下gitea、gogs和gitlab的代码,希望也能挖一个有趣的洞…


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK