漏洞分析 | Apache StreamPark经过身份验证的系统用户可触发远程命令执行(CVE-2023-49898)

Apache Streampark是一个开源的流数据处理平台,它提供了一套强大的工具和框架,用于处理实时数据流。它基于Apache Flink流处理引擎构建,并提供了一系列的库和API,使开发者能够方便地构建、部署和管理流数据处理应用程序。

2023年12月,官方发布新版本(2.1.2)修复了CVE-2023-49898 Apache StreamPark 代码执行漏洞。经过身份验证的系统用户可以触发远程命令执行,攻击者能够利用该漏洞获取服务器权限,建议尽快修复漏洞。

▌漏洞详情

在Apache Streampark中,有一个项目管理功能模块集成了Maven的编译功能,但是该功能没有对Maven的编译参数进行检查。

同时,Apache Streampark允许用户自定义Maven配置,攻击者可以在Maven Settings File Path配置中插入恶意代码用于远程命令执行。

该漏洞成功利用的前提是用户需要登录到streampark系统并拥有系统级权限。因此,此漏洞的风险级别较低。

 

▌漏洞复现

1. 靶场环境搭建

  • 下载Apache Streampark的docker-compose.yaml和.env文件:
  • wget https://raw.githubusercontent.com/apache/incubator-streampark/dev/deploy/docker/docker-compose.yaml
    wget https://raw.githubusercontent.com/apache/incubator-streampark/dev/deploy/docker/.env
  • 修改docker-compose.yaml中Apache Streampark的版本号为release-2.1.1。
  • 使用docker-compose up -d启动容器,在等待数分钟后,访问http://localhost:10000查看到StreamPark的登录页面,说明环境已启动成功。

2. 登录系统并配置恶意的Maven Settings.xml 路径

使用StreamPark默认的用户名admin和密码streampark登录系统。

在设置中心->系统设置->Maven Settings File Path中配置恶意的Maven Settings.xml 路径:

/usr/share/java/maven-3/conf/settings.xml & touch /tmp/success

此时,浏览器会调用/flink/setting/update接口修改Maven Settings File Path的配置信息。

3. 触发漏洞

在StreamPark->项目管理中,有一个默认的streampark-quickstart项目,点击右侧更新项目。修改项目分支为任意存在的分支并提交。需要注意的是,这里容器必须要能够访问到仓库,并且能获取到仓库分支信息。

然后构建该项目,来触发漏洞执行远程命令。

通过抓包,我们看到浏览器调用了/flink/project/build接口来启动项目构建:

查看构建日志,可以看到maven编译参数中被嵌入了恶意代码:

进入容器中,可见touch /tmp/success已成功执行:


 

▌漏洞分析

首先将分支切换到release-2.1.1。该漏洞的利用过程可以分为以下两个步骤:

  1. 配置Maven Settings.xml 路径,将恶意代码插入到Maven Settings.xml文件路径后面。
  2. 构建项目,触发漏洞执行远程命令。

 

1. 配置Maven Settings.xml 路径

通过抓包分析我们发现,在修改Maven Settings File Path时浏览器会调用/flink/setting/update接口,该接口会调用settingService的update()方法:

update()方法会将Maven Settings File Path的值写入到数据库中和全局配置中。

 

2. 构建项目,触发漏洞执行远程命令

当我们点击开始构建项目时,浏览器会调用/flink/project/build接口。该接口通过调用projectService.build方法进行构建:

找到projectService.build方法的实现,我们发现该方法会通过异步任务的方式执行构建命令:

并且会触发projectBuildTask.doRun()方法开始执行构建任务:

projectBuildTask.doRun()方法首先会把项目克隆下来,克隆成功之后再调用projectBuild(project)进行编译构建:

显然,服务端通过CommandUtils.execute方法执行系统命令,而参数是project.getMavenArgs()的返回结果。

getMavenArgs()方法在拼接cmdBuffer时,没有对InternalConfigHolder取出的MAVEN_SETTINGS_PATH进行任何过滤和校验。所以如果在配置的maven settings.xml文件路径后面嵌入恶意的系统命令,包含恶意系统命令的maven参数会直接传入到CommandUtils.execute方法中执行。

 

塞讯验证规则

12月28日,针对该漏洞的攻击模拟已经加入到塞讯安全度量验证平台中,您可以在塞讯安全度量验证平台中搜索关键词“Apache StreamPark”“CVE-2023-49898”获取相关攻击模拟验证动作,从而验证您的安全防御体系是否能够有效应对该漏洞,平台以业界独有方式确保您的验证过程安全无害。

 

参考:

https://github.com/apache/incubator-streampark
https://streampark.apache.org/zh-CN/docs/user-guide/docker-deployment/