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

做者:LoRexxar'@知道创宇404实验室

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

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.github

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

分析补丁

首先根据cve的信息,肯定漏洞1.7.6和1.8.0-rc3上修复
. https://github.com/go-gitea/gitea/releases/tag/v1.7.6
. https://github.com/go-gitea/gitea/releases/tag/v1.8.0-rc3
根据漏洞文件为repo_mirror.go这个信息锁定更新的commit,commit主要为 #6593和#6595
. https://github.com/go-gitea/gitea/pull/6595/commits/52af826a7aa1df6ab538d881db236698cb367cd7
根据patch能够大体锁定问题的关键点
/models/repo_mirror.go
CVE-2019-11229详细分析 --git config可控-RCE
当仓库为mirror仓库时,settings页面会显示关于mirror的配置api

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

patch中将原来的修改配置文件中的url选项修改成NewCommand。很容易理解,将写入文件更改成执行命令,这种修复方式必定是由于写入文件存在没法修复这个问题的窘境,那么这也就说明url这里能够经过传入%0d%0a来换行,致使修改config中的其余配置。ssh

控制 gitconfig

跟随前面的逻辑,首先咱们新建一个mirror仓库。
CVE-2019-11229详细分析 --git config可控-RCE
抓包并修改mirror_address为相应的属性。
CVE-2019-11229详细分析 --git config可控-RCE
mirror_address=https%3A%2F%2Ftest%3A%40github.com%2FLoRexxar%2Ftest_for_gitea.git"""%0d%0a[core]%0d%0atest=/tmp%0d%0aa="""
CVE-2019-11229详细分析 --git config可控-RCE
能够传入各类配置,能够控制config文件的内容。
比较有趣的是,若是你更新同步设置时,服务端还会格式化配置。
CVE-2019-11229详细分析 --git config可控-RCEide

进一步利用

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

首先,git服务端只会保留.git里的内容,并非完整的相似咱们客户端使用的git仓库。因此很难引入外部文件。不然就能够经过设置hook目录来实现RCE,这种思路的关键点在于找到一个可控的文件写入或者文件上传。fetch

其次,另一种思路就是寻找一个可以执行命令的配置,并寻找一个可以触发相关配置的远程配置。
.https://git-scm.com/docs/git-configurl

经过写文件配合 githook path RCE

在git中,存在一个叫作Git Hook的东西,是用于在处理一些操做的时,相应的hook就会执行相应的脚本。
CVE-2019-11229详细分析 --git config可控-RCE
在web界面,只有gitea的管理员才能管理git hook,因此对于普通用户来讲,咱们就不能直接经过编辑git hook来修改脚本。spa

但咱们却能够经过控制git config来修改hook存放的目录。
CVE-2019-11229详细分析 --git config可控-RCE
当咱们构造发送
mirror_address=https%3A%2F%2Fgithub.com%2FLoRexxar%2Ftest_for_gitea.git"""%0d%0a[core]%0d%0ahooksPath=/tmp%0d%0aa="""
服务端的config文件变为
CVE-2019-11229详细分析 --git config可控-RCE
这样咱们只要能在服务端的任意位置可以写入文件或者建立文件,咱们就能够设置hookspath到那里,并触发git hook来执行命令。

在通过咱们的仔细研究以后,咱们发现,在漏洞存在的版本1.7.5版本如下,若是编辑服务端的文件,那么服务端的文件就会保存在gitea的运行目录下生成。
/data/tmp/local-repo/{repo_id}
而这个文件在不重启gitea的状况下不会清除,而这个repo_id能够从其余的api处挖掘到。

具体详细利用链能够看
. https://www.jianshu.com/p/684fa071026a
值得注意的是,这种方式须要知道服务端运行的位置,虽然咱们能够认为go的路径都是比较形似的,也有部分人会在当前编译目录下执行。但能够说这种方式仍是不算靠谱。

经过控制 git config 配置来 RCE

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

gitProxy

CVE-2019-11229详细分析 --git config可控-RCE
gitProxy是用来针对git协议须要fetch等操做时,须要执行的命令。是一个用来应对特殊场景的配置选项。通常是应用于,在git请求时,可能的须要使用代理应用的场景。

这里咱们设置服务端

[core]
    gitproxy                = calc.exe

而后须要注意,同步的url必须为git开头
CVE-2019-11229详细分析 --git config可控-RCE
但问题在于,因为gitProxy在git设计中,就是执行一个代理应用,因此不管输入什么,都会被看成一个应用执行,也就没办法带参数。

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

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

sshCommand

在git的文档中,还有一个配置是sshCommand。
CVE-2019-11229详细分析 --git config可控-RCE
这是一个在git中容许经过特殊的配置,使git fetch/git push 经过ssh来链接远端的系统。在@Lz1y大佬的博客中也提到了这种利用方式。
. https://www.lz1y.cn/2019/07/20/CVE-2019-11229-Gitea-RCE/
咱们设置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保存,并点击同步。
CVE-2019-11229详细分析 --git config可控-RCE
而与gitProxy不一样的是,这里能够跟参数
&mirror_address=https%3A%2F%2Ftest%3A%40github.com%2FLoRexxar%2Ftest_for_gitea.git"""%0d%0a[core]%0d%0asshCommand="touch 2333"%0d%0aa="""
CVE-2019-11229详细分析 --git config可控-RCE

写在最后

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

原文连接
英文连接

相关文章
相关标签/搜索