影响版本: Nacos <= 2.0.0-ALPHA.1

小于或等于2.0.0预发布的版本

在2.0.0正式版往后版本不存在

一.复现过程

1.未授权查看用户列表

访问主页

修改路径为/nacos/v1/auth/users?pageNo=1&pageSize=1,访问并抓包

可以看到直接访问是403(无权限),我们把User-Agent:修改为Nacos-Server

直接绕过了认证,查看到了账号以及加密密码。

密码为BCrypt单向哈希加密,可以通过此工具https://github.com/wolaile08/BCryptDecode进行穷举爆破。

2.未授权添加任意用户

访问路径/nacos/v1/auth/users,同时抓包。这里我不建议直接改修改包去访问,因为可能会少一些原本正常访问时会带上的请求头。

添加username与password参数,发送,回显200即添加账密成功。返回登录框验证。

登录成功。

二.漏洞成因

两个都是未授权,未授权意味着这里原本是有限制的,但修改了一下User-Agent头就放行了,为什么?从代码层面分析一下(本身感觉也就是代审洞):

java后端里负责捕获User-Agent头的方法名称叫做 HttpServletRequest,也就是说,我们只需要寻找哪些文件会调用此方法,又调用去干了什么。

为什么我会知道类名?因为java后端的各类接口开发声明是基于 Servlet 规范的,所以方法名基本都是一致的。

开始追溯此方法,打开源码包,直接寻找相关代码:

我在AuthFilter.java文件中发现了User-Agent捕获函数与过滤器chain.doFilter同时出现的代码,这应该就是了,我们分析一下

捕获请求包的User-Agent头,并赋值给req变量:

HttpServletRequest req = (HttpServletRequest) request;

捕获响应包的User-Agent头,并赋值给resp变量:

HttpServletResponse resp = (HttpServletResponse) response;

声明一个字符串变量,userAgrnt,他被赋值了什么呢?

String userAgent = WebUtils.getUserAgent(req);

这就需要接着追溯WebUtils这个类了,

直接就找到了,我这里删一下注释方便看的更清晰。

成功找到了此类的getUserAgent方法,这里也逐步解释一下:

声明一个静态字符串方法,getUserAgent(),里面的HttpServletRequest request是获取请求包里User-Agent内容的方法:

public static String getUserAgent(HttpServletRequest request)

声明一个字符串变量,userAgent,后面的类和方法需要进一步追溯,首先看括号里的

String userAgent = request.getHeader(HttpHeaderConsts.USER_AGENT_HEADER);

只是个传递字符串用的类,所以这个方法可以简化成,

String userAgent = request.getHeader(User-Agent);

而request.getHeader的意思是获取请求头内容,比如

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:141.0) Gecko/20100101 Firefox/141.0

那么request.getHeader(User-Agent)就是:

Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:141.0) Gecko/20100101 Firefox/141.0

综上所述,AuthFilter.java文件里的变量userAgent=当前请求包User-Agent传参内容。

接着往下看这条if语句,这是个比较if判断,如果userAgent的内容和Constants.NACOS_SERVER_HEADER方法内的内容一模一样,触发下面的chain.doFilter方法,先看看Constants.NACOS_SERVER_HEADER是什么:

看到了我们眼熟的东西,这不就是触发未授权的User-Agenr传参吗,所以上面的if语句可以简化成:

if (StringUtils.startsWith(userAgent, "Nacos-Server")) {

chain.doFilter(request, response);

return;

我们传参Nacos-Server,此时userAgent="Nacos-Server",与Constants.NACOS_SERVER_HEADER="Nacos-Server"比对,如果等于,则触发chain.doFilter过滤器,直接绕过限制,漏洞成因已解。

总结,该漏洞本质是开发者留的后门,但被代审大佬发现,故而造成严重的安全漏洞。

Logo

更多推荐