(CVE-2017-8386)GIT-SHELL_沙盒绕过

# (CVE-2017-8386)GIT-SHELL 沙盒绕过

===================================

一、漏洞简介
————

二、漏洞影响
————

Git
2.4.12之前的版本,2.5.6之前的2.5.x版本,2.6.7之前的2.6.x版本,2.7.5之前的2.7.x版本,2.8.5之前的2.8.x版本,2.9.4之前的2.9.x版本,2.10.3之前的2.10.x版本,2.11.2之前的2.11.x版本,2.12.3之前的2.12.x版本。

三、复现过程
————

### 漏洞分析

git-shell是git服务中重要的组成部分,众所周知,git服务支持ssh、git、https三种协议来传递项目,其中ssh是最安全,也最方便的一种方式。

我们随便打开Github上一个项目,找到`Clone with SSH`里列出的地址::phith0n/vulhub.git,其实这个url就是告诉git,ssh用户名是git,地址是github.com(默认端口是22),该项目位于`phith0n/vulhub.git`这个目录下;然后git就通过ssh协议连接上github.com,并将对应目录下的项目拉取下来。

所以,基于ssh协议的git
clone等操作,本质上就是通过ssh协议连接上git服务器,并将指定目录拉取下来的过程。

那么,既然这个过程是个ssh交互的过程,那么我直接执行`ssh git@github.com`是不是就可以登录github服务器了呢?显然是不行的,你可以试试:![01.png](/static/qingy/(CVE-2017-8386)GIT-SHELL_沙盒绕过/img/rId25.png)说”不行”其实也有偏差,实际上我确实是连接上了其ssh服务,并验证身份通过了,但他给了我一段提示信息”Hi
phith0n! You\’ve successfully authenticated, but GitHub does not provide
shell access.”,就把我的连接关了。

所以,正常来说,基于ssh的git拉取过程对于git服务器是安全的。

#### 如何禁止git用户执行系统shell

那么,github这类git服务商是怎么实现上述”安全”通信的流程的呢?

让用户可以通过ssh认证身份,但又不给用户shell,这个过程有两种方法实现:

1. 创建系统用户git的时候将其shell设置成git-shell
2. 在authorized\_keys文件每个ssh-key的前面设置command,覆盖或劫持重写原本的命令

第一种方法比较直观,就是创建用户的时候不给其正常的bash或sh的shell,而是给它一个git-shell。git-shell是一个沙盒环境,在git-shell下,只允许执行沙盒内包含的命令。

第二种方法不仅在git服务器上使用,很多Linux发行版也会用到。比如aws,默认安装后是不允许root登录的,实现方法就是在/root/.ssh/authorized\_keys中设置`command=”echo ‘Please login as the user \”ec2-user\” rather than the user \”root\”.’;echo;sleep 10″`。这句话相当于覆盖了原本执行的shell,变成了echo一段文字。

当然,第二种方法内也可以用git-shell,比如在添加git用户的时候赋予其正常的`/bin/bash`,但在authorized\_keys中设置`command=”git-shell -c \”$SSH_ORIGINAL_COMMAND\””`,实际上还是使用了git-shell。

#### git-shell 沙盒绕过漏洞(CVE-2017-8386)

git-shell是一个可以限制用户执行命令的shell,如果我们在git用户家目录下创建一个新目录,叫`git-shell-commands`,然后将你允许用户执行的命令放在这个目录下,这就创建好了一个沙盒。在git-shell中,只能执行`/home/git/git-shell-commands`目录下的命令。

如果系统是没有`git-shell-commands`目录,那么git-shell默认只允许执行如下三个命令:

– `git-receive-pack `
– `git-upload-pack `
– `git-upload-archive `

这就是白名单。

但CVE-2017-8386的作者发现,执行`git-upload-archive –help`(或`git-receive-pack –help`),将会进入一个交互式的man页面,man又调用了less命令,最后是一个可以上下翻页的帮助文档。

本来这也没什么,但是,less命令有一个特性,就是其支持一些交互式的方法。比如在less页面中,按`shift`+e可以打开Examine功能,通过这个功能可以读取任意文件;输入`!id`就可以执行id这个命令。

可以随便找台linux计算机试一下,执行`less /etc/passwd`来到less的页面,然后在英文输入法下输入`!id`,就可以执行id命令:![02.png](/static/qingy/(CVE-2017-8386)GIT-SHELL_沙盒绕过/img/rId28.png)所以,利用这个特性,我们就可以绕过git-shell的沙盒读取任意文件,或执行任意命令了!

我们可以先试试,在Linux下直接执行git-receive-pack
\–help,再输入!id,看到的效果和上图是类似的。

#### 通过ssh进行利用

那么,如何远程利用这个漏洞?

我们前面试了,直接`ssh git@gitserver`只能拿到git-shell(或返回一段提醒文字),我们就利用上一节里提到的沙盒绕过漏洞执行命令:

ssh -p 3322 -i id_rsa -t git@127.0.0.1 “git-upload-archive ‘–help'”

进入帮助页面,然后按shift+e或`!id`即可。

#### 一些限制

我前文说了,一般配置git用户,不让ssh拥有shell,有两种方法:一是创建用户的时候设置其shell为`/usr/bin/git-shell`,二是在authorized\_keys中覆盖command。

如果目标服务器使用了第一种方法,我们即使成功执行了`git-upload-archive ‘–help’`进入帮助页面,也不能执行命令。因为`!id`还是在git-shell下执行,git-shell中没有id命令,所以依旧执行不成功。

但读取文件是一定可以的,因为读取文件不是通过命令读取的,所以不受git-shell沙盒的影响。

如果目标服务器是用第二种方法配置的git-shell,比如我这里这个测试环境,我是在`/etc/passwd`文件设置git用户的shell是bash,而在authorized\_keys中覆盖command,执行git-shell。

这种情况下,如果我进入了帮助页面,输入`!id`是可以成功执行id命令的,因为此时id是在bash下执行的,而不是在git-shell下执行的,所以没有沙盒限制。

总的来说,这个漏洞至少能做到任意文件读取,有可能可以执行任意命令。

### 漏洞复现

#### 测试环境

编译及运行测试环境:

docker-compose build
docker-compose up -d

为了不和docker母机的ssh端口冲突,我将容器的ssh端口设置成3322。本目录下我生成了一个`id_rsa`,这是ssh的私钥,连接的时候请指定之。

在连接以前,需要先设置私钥的权限为0600:`chmod 0600 id_rsa`,否则连接可能失败。

正常连接其ssh服务`ssh -p 3322 -i id_rsa git@127.0.0.1`,会被git-shell给拦截,返回错误`fatal: unrecognized command ”`,并且连接被关闭。

使用\–help技巧,连接目标并进入帮助页面:

ssh -p 3322 -i id_rsa -t git@127.0.0.1 “git-upload-archive ‘–help'”

按`shift`+e,读取任意文件:![03.png](/static/qingy/(CVE-2017-8386)GIT-SHELL_沙盒绕过/img/rId33.png)

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容