漏洞描述
某些WSO2产品允许不受限制地上传文件,从而执行远程代码。以WSO2 API Manager 为例,它是一个完全开源的 API 管理平台。它支持API设计,API发布,生命周期管理,应用程序开发,API安全性,速率限制,查看API的统计信息,以及连接API,API产品和端点。
漏洞版本
WSO2 API Manager 2.2.0 及以上版本
WSO2 Identity Server 5.2.0 及以上
版本WSO2 Identity Server Analytics 5.4.0、5.4.1、5.5.0、5.6.0WSO2
Identity Server as Key Manager 5.3.0 及更高版本
WSO2 Enterprise Integrator 6.2.0 及更高版本
WSO2 Open Banking AM 1.4.0 及更高版本
WSO2 Open Banking KM 1.4.0 及更高
环境搭建
采用Dockerfile搭建 wso2/wso2am - Docker Image | Docker Hub
版本:WSO2 API Manager 4.0.0
# ------------------------------------------------------------------------ # # Copyright 2018 WSO2, Inc. (http://wso2.com) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License # # ------------------------------------------------------------------------ # set base Docker image to AdoptOpenJDK CentOS Docker image FROM adoptopenjdk/openjdk11:x86_64-centos-jdk-11.0.10_9 LABEL maintainer="WSO2 Docker Maintainers <dev@wso2.org>" \ com.wso2.docker.source="https://github.com/wso2/docker-apim/releases/tag/v4.0.0.1" # set Docker image build arguments # build arguments for user/group configurations ARG USER=wso2carbon ARG USER_ID=802 ARG USER_GROUP=wso2 ARG USER_GROUP_ID=802 ARG USER_HOME=/home/${USER} # build arguments for WSO2 product installation ARG WSO2_SERVER_NAME=wso2am ARG WSO2_SERVER_VERSION=4.0.0 ARG WSO2_SERVER_REPOSITORY=product-apim ARG WSO2_SERVER=${WSO2_SERVER_NAME}-${WSO2_SERVER_VERSION} ARG WSO2_SERVER_HOME=${USER_HOME}/${WSO2_SERVER} ARG WSO2_SERVER_DIST_URL=https://github.com/wso2/${WSO2_SERVER_REPOSITORY}/releases/download/v${WSO2_SERVER_VERSION}/${WSO2_SERVER}.zip # build argument for MOTD ARG MOTD='printf "\n\ Welcome to WSO2 Docker resources.\n\ ------------------------------------ \n\ This Docker container comprises of a WSO2 product, running with its latest GA release \n\ which is under the Apache License, Version 2.0. \n\ Read more about Apache License, Version 2.0 here @ http://www.apache.org/licenses/LICENSE-2.0.\n\n"' # create the non-root user and group and set MOTD login message RUN \ groupadd --system -g ${USER_GROUP_ID} ${USER_GROUP} \ && useradd --system --create-home --home-dir ${USER_HOME} --no-log-init -g ${USER_GROUP_ID} -u ${USER_ID} ${USER} \ && echo ${MOTD} > /etc/profile.d/motd.sh # copy init script to user home COPY --chown=wso2carbon:wso2 docker-entrypoint.sh ${USER_HOME}/ # install required packages RUN \ yum -y update \ && yum install -y \ nc \ unzip \ wget \ && rm -rf /var/cache/yum/* # add the WSO2 product distribution to user's home directory RUN \ wget -O ${WSO2_SERVER}.zip "${WSO2_SERVER_DIST_URL}" \ && unzip -d ${USER_HOME} ${WSO2_SERVER}.zip \ && chown wso2carbon:wso2 -R ${WSO2_SERVER_HOME} \ && mkdir ${USER_HOME}/wso2-tmp \ && bash -c 'mkdir -p ${USER_HOME}/solr/{indexed-data,database}' \ && chown wso2carbon:wso2 -R ${USER_HOME}/solr \ && cp -r ${WSO2_SERVER_HOME}/repository/deployment/server/synapse-configs ${USER_HOME}/wso2-tmp \ && cp -r ${WSO2_SERVER_HOME}/repository/deployment/server/executionplans ${USER_HOME}/wso2-tmp \ && rm -f ${WSO2_SERVER}.zip # set the user and work directory USER ${USER_ID} WORKDIR ${USER_HOME} # set environment variables ENV WORKING_DIRECTORY=${USER_HOME} \ WSO2_SERVER_HOME=${WSO2_SERVER_HOME} # expose ports EXPOSE 9763 9443 9999 11111 8280 8243 5672 9711 9611 9099 # initiate container and start WSO2 Carbon server ENTRYPOINT ["/home/wso2carbon/docker-entrypoint.sh"]
运行docker run命令 搭建docker环境。
docker run -it -p 8280:8280 -p 8243:8243 -p 9443:9443 --name api-manager wso2/wso2am:4.0.0
搭建完成后,访问 https://localhost:9943 默认用户名 密码 admin admin。
漏洞复现
漏洞原理
补丁diff记录Remove Unnecessary file uploader classes and improve parent path validation. by bhagyasakalanka · Pull Request #3152 · wso2/carbon-kernel (github.com)
查看diff记录、在创建file对象时会先对上传文件的路径做校验。
carbon-kernel/FileUploadServlet.java at 4.4.x · wso2/carbon-kernel (github.com)
开启docker镜像调试模式,在idea上使用远程调试。
docker run -it -p 8280:8280 -p 8243:8243 -p 9443:9443 -p 5005:5005 --name another-api-manager wso2/wso2am:4.0.0 -debug *:5005
/fileupload 会在服务器启动期间被注册。
在使用文件上传时,会调用/org/wso2/carbon/ui/transports/FileUploadServlet.java 。
构造函数FileUploadServlet 会将类内部定义的私有属性进行修改。
使用POST方法时,会调用doPost(),接着调用fileUploadExecutorManager.execute()
因此我们将断点打到/org/wso2/carbon/ui/transports/fileupload/FileUploadExecutorManager.java#execute,正如上面描述所说、当收到一个文件上传请求,这个方法会被调用。它接受的两个参数:http request、https response,会返回布尔值。
CarbonConstants类包含Carbon所有重要常数
然后对CarbonConstants的cookie、webContext、SERVER_URL、进行操作。向下走,通过对requestURI的截取获得actionString。
在下面的代码中会注册execution handlers、首先会创建execHandlerManager对象 ,接下来会加上ExecHandler链条 。FileUploadExecutionHandlerManager => CarbonXmlFileUploadExecHandler=>OSGiFileUploadExecHandler=>AnyFileUploadExecHandler。
进入startExec() 会调用/org/wso2/carbon/ui/transports/fileupload/FileUploadExecutorManager.java# execute() 在for循环中匹配到 toolsAny。
然后进入/org/wso2/carbon/ui/transports/fileupload/AbstractFileUploadExecutor.java# executeGeneric() ,然后调用parseRequest(request) 获取request 参数。
/org/wso2/carbon/ui/transports/fileupload/AbstractFileUploadExecutor.java#parseRequest()
将断点打到该位置,继续调试。它首先确保 POST 请求是分段 POST 请求,然后提取上传的文件,确保 POST 请求至少包含上传的文件,并根据最大文件大小对其进行验证。
走了很长一串之后,进入到/org/wso2/carbon/ui/transports/fileupload/ToolsAnyFileUploadExecutor.java# execute()
这是错误所在,该方法容易受到路径遍历vulenerabulity的影响,因为它信任用户在POST请求中给出的文件名。
在该方法下,会返回一个 uuid 是由系统时间和随机数组成。在uploadeFile中可以看到存放上传文件的路径。
漏洞测试
运行以下命令:
python3 exploit.py https://127.0.0.1:9443/ shell.jsp
在网页中打开以下链接。在输入框中输入命令 ls 。
修复建议
如果最新版本未列在受影响的产品列表下,则可以迁移到产品的最新版本。否则,您可以根据以下公开修复程序将相关修复程序应用于产品:
https://github.com/wso2/carbon-kernel/pull/3152
https://github.com/wso2/carbon-identity-framework/pull/3864
https://github.com/wso2-extensions/identity-carbon-auth-rest/pull/167
临时缓解措施:
产品版本 | 临时缓解步 |
WSO2 API 管理器 2.6.0、2.5.0、2.2.0 及更早版本 WSO2 身份服务器 5.8.0、5.7.0、5.6.0、5.5.0、5.4.1、5.4.0、5.3.0、5.2.0 和更早版本 作为密钥管理器的 WSO2 身份服务器 5.7.0、5.6.0、5.5.0、5.3.0 和更早版本 WSO2 IS 分析 5.6.0、5.5.0、5.4.1、5.4.0 及更早版本 | 删除 <product_home>/repository/conf/carbon 中 FileUploadConfig 标记内定义的所有映射.xml |
WSO2 API 管理器 4.0.0、3.2.0、3.1.0、3.0.0 | 将以下配置添加到 <product_home>/repository/conf/deployment.toml deployment.toml [[resource.access_control]]context="(.*)/fileupload/resource(.*)"secure=falsehttp_method = "all" [[resource.access_control]]context="(.*)/fileupload/(.*)"secure=truehttp_method = "all"permissions = ["/permission/protected/"] |
SO2 企业集成商 6.6.0、6.5.0、6.4.0、6.3.0、6.2.0 及更早版本 | 于 EI 配置文件,请从<文件上传配置>部分中删除<product_home>/conf/carbon.xml 文件中的以下映射。 对于业务流程/代理和分析配置文件,分别在以下位置对 carbon.xml文件应用相同的更改。
deployment.toml <Mapping> <Actions> <Action>keystore</Action> <Action>certificate</Action> <Action>*</Action> </Actions> <Class>org.wso2.carbon.ui.transports.fileupload.AnyFileUploadExecutor</Class></Mapping> <Mapping> <Actions> <Action>jarZip</Action> </Actions> <Class>org.wso2.carbon.ui.transports.fileupload.JarZipUploadExecutor</Class></Mapping> <Mapping> <Actions> <Action>tools</Action> </Actions> <Class>org.wso2.carbon.ui.transports.fileupload.ToolsFileUploadExecutor</Class></Mapping> <Mapping> <Actions> <Action>toolsAny</Action> </Actions> <Class>org.wso2.carbon.ui.transports.fileupload.ToolsAnyFileUploadExecutor</Class></Mapping> |
WSO2 身份服务器 5.11.0、5.10.0、5.9.0 作为密钥管理器的 WSO2 身份服务器 5.10.0、5.9.0 | 将以下配置添加到 <product_home>/repository/conf/deployment.toml deployment.toml [[resource.access_control]]context="(.*)/fileupload/service(.*)"secure=falsehttp_method = "all" [[resource.access_control]]context="(.*)/fileupload/entitlement-policy(.*)"secure=falsehttp_method = "all" [[resource.access_control]]context="(.*)/fileupload/resource(.*)"secure=falsehttp_method = "all" [[resource.access_control]]context="(.*)/fileupload/(.*)"secure=truehttp_method = "all"permissions = ["/permission/protected/"] |
基于 WSO2 碳核 4 版本的其他不受支持的产品/版本 | 删除 <product_home>/repository/conf/carbon 中 FileUploadConfig 标记内 定义的所有映射 .xml |
参考材料
1. 安全公告 WSO2-2021-1738 - WSO2 平台安全性 - WSO2 文档:https://docs.wso2.com/display/Security/Security+Advisory+WSO2-2021-1738
2. 关键概念 - WSO2 API 管理器文档 4.1.0:https://apim.docs.wso2.com/en/latest/get-started/key-concepts/
3. hakivvi/CVE-2022-29464:WSO2 RCE (CVE-2022-29464) 漏洞利用和写入。(github.com):https://github.com/hakivvi/CVE-2022-29464