Nacos系列安全问题整理
写这篇文章的起源自HW期间遇到很多并且之前并未了解Nacos系列漏洞或者Nacos相关信息,故出生了这篇文章
其实关于Nacos安全问题的根本原因,正如官方的开发文档所说,Nacos提供简单的鉴权实现,即只提供防止业务错用的弱鉴权体系,而不是防止恶意攻击的强鉴权体系,正是导致这些安全问题的根本原因,不知道Nacos是否考虑后续改进一下,因为HW期间因此产生的安全问题已经比较影响正常业务了
事实证明,不安全的一直是人性,而不是其他东西

Nacos快速利用工具
其实本来想放到最后面的,但是想到工作中检查类似漏洞肯定少不了工具,所以放在最前面比较合适,这里我就写俩,其实还是不少的
HKEcho_Nacos
作者:HKEcho@深蓝实验室天玄攻防战队
项目地址:https://github.com/HKEcho5213/HKEcho_Nacos.git
工具支持检测以下漏洞:
1 | |
安装
1 | |
使用
1 | |
1、单个目标检测:
1 | |
2、批量目标检测:
1 | |
其他的我就不做过多讲解了,项目作者在项目的readme已经说的比较详细了,可以直接区GitHub看,文章主要重点放在漏洞上
NacosExploitGUI
https://github.com/charonlight/NacosExploitGUI
对于我这种工作期间需要基线排查的还是很方便快捷的
权限绕过类
除CVE-2021-29441,都是研发人员在代码中没有将以下鉴权功能配置正确导致的权限绕过
1 | |
默认配置未授权访问漏洞
成因:nacos.core.auth.enabled = false
此漏洞不需要添加任何身份标识来绕过校验,仅仅是因为默认配置未开启鉴权导致漏洞出现
1.1 环境搭建
Nacos gtihub下载地址
https://github.com/alibaba/nacos/releases/tag/2.0.0-ALPHA.1
win10环境搭建
1 | |

1.2 漏洞验证
查看用户信息,两个url
1 | |

新建用户
1 | |

成功登陆

1.3 漏洞原理
默认未开启配置 nacos.core.auth.enabled

在auth/src/main/java/com/alibaba/nacos/auth/common/AuthConfigs.java类中,isAuthEnabled方法的返回值取决于nacos.core.auth.enabled (默认False)

在core/src/main/java/com/alibaba/nacos/core/auth/AuthFilter.java类中,根据authConifgs.isAuthEnabled()的返回值默认为flase,所以这里默认跳过检查认证filter,直接进入filterchain的下一个filter

1.4 修复方案
配置文件修改为:nacos.core.auth.enabled=True
修改之后,再次尝试访问http://localhost:8848/nacos/v1/auth/users?pageNo=1&pageSize=1,回显WhitelabelErrorPage

默认jwt密钥未授权访问
2.1 漏洞简介
开启了nacos.core.auth.enabled 的情况下,如果未修改默认nacos.core.auth.default.token.secret.key,则可以生产accessToken值来绕过权限。
该key值固定,在nacos使用jwt构造认证token,使用HS256算法,把配置文件中nacos.core.auth.plugin.nacos.token.secret.key的默认值当作私钥生成Signature,将用户名和时间戳写到jwt token里,所以可以在登录时对accessToken进行伪造,从而实现访问认证绕过
影响版本:0.1.0 <= Nacos <= 2.2.0
配置文件
1 | |
2.2 环境搭建
Nacos gtihub下载地址
https://github.com/alibaba/nacos/releases/tag/2.0.0-ALPHA.1
win10环境搭建
1 | |
2.3 漏洞验证
将默认key拿到在线的jwt生成网站:https://jwt.io/
以及生成一个比当前系统时间晚的unix时间戳,填到payload中,如图
例如我现在系统时间为2024-09-10,所以我填2024-09-11,比系统时间晚就可以


拿到我们构造的accessToken
1 | |
然后带上我们构造的token即可访问,因为将nacos.core.auth.enabled=true打开后,默认只有token验证通过的用户才能访问该页面和添加新用户,甚至可以不需要添加用户直接登陆进去

可以看到返回200,证明登陆成功了,添加用户也是跟上面一样的操作,只不过加个我们伪造的acessToken就好。

2.4 漏洞原理

2.5 修复方案
修改默认的nacos.core.auth.default.token.secret.key
身份认证serverIdentity绕过
3.1 漏洞简介
更合适的说法是危险配置造成的鉴权不严,其实也算是弱口令,因为
3.2 环境搭建
配置如下的时候就会造成这个绕过可用,1.4.1版本复现成功,2.0.0版本复现失败,因为有几个配置并未存在

1 | |

3.3 漏洞验证
在请求头中serverIdentity:security即可绕过jwt鉴权,未加则请求失败

3.4 漏洞原理
首先逻辑是根据前面的分析判断是否开启nacos.core.auth.enabled和是否开启userAgentAuthWhite,然后是对配置文件是否配置了identity.key&identity.value,若配置了则检测与配置文件是否相同,相同则允许通过。
3.5 漏洞修复
identity.key&identity.value的值其实是自定义的,这个安全隐患更像弱口令,建议直接更新版本。
Nacos请求头User-Agent绕过鉴权
4.1 漏洞简介
漏洞编号:CVE-2021-29441
在Nacos的鉴权管理中,有一项配置是通过User-Agent中是否包含Nacos-Server来进行判断请求是否来自其他服务端。
配置文件中nacos.core.auth.enable.userAgentAuthWhite = true,就会获取请求头中UserAgent的值,然后判断是否是以字符串Nacos-Server为开头,若是则直接跳过鉴权。
影响版本:Nacos <= 2.0.0-ALPHA.1
4.2 环境搭建
版本选择低于2.00即可,另外这个漏洞vulhub也有,也可以一键化部署,我这里是vulhub的,自己动手的话建议1.4.1,因为2.0.0我没试过
配置文件如下
1 | |

4.3 漏洞验证
加UA后成功绕过鉴权,不加UA失败

4.4 漏洞原理
相关代码文件是core/src/main/java/com/alibaba/nacos/core/auth/AuthFilter.java
这里的逻辑也很简单,如果authConfigs.isEnableUserAgentAuthWhite()即配置文件中 nacos.core.auth.enable.userAgentAuthWhite 为true,就会获取请求头中UserAgent的值,然后判断是否是以字符串“Nacos-Server”为开头,若是则直接跳过鉴权。
StringUtils.startsWith(userAgent, Constants.NACOS_SERVER_HEADER)

4.5 漏洞修复
更改配置文件中默认选项
1 | |
对User-Agent绕过鉴权的bypass
是对上一个user-agent的bypass,官方修复了之后三梦师傅又发现了另一种方法,可以绕过修复
不过开发者直接删除了漏洞版本的1.4.1(三梦师傅是Jan 14 提的issue,然后封装好的server端是直接更换修复后的了,不过Source code没有换),而低版本中没有对应配置项。所以想要复现试试的可以通过源码编译的方式获取环境,我这里就不详细写了,感觉三梦师傅和谢师傅写的已经很易懂了,我这种菜鸟都能看懂,感兴趣的移步两位师傅文章
https://xz.aliyun.com/t/15151?time__1311=GqjxuQD%3DcDlx0nD2DUxYwrIDcmYwhjox#toc-5
https://github.com/alibaba/nacos/issues/4701
其实是我比较懒hhh
Nacos Jraft Hessian 反序列化漏洞
漏洞描述
Nacos默认的7848端口是用来处理集群模式下raft协议的通信,该端口的服务在处理部分jraft请求的时候使用hessian传输协议进行反序列化过滤不严,导致RCE。
**漏洞编号:**CNVD-2023-45001
影响版本:
- 1.4.0 <= Nacos < 1.4.6(使用cluster集群模式运行)
- 2.0.0 <= Nacos < 2.2.3(任意模式运行)
搭建环境,docker一键部署2.0.0
1 | |
漏洞检测
建议直接工具梭哈,方便快捷,具体食用教程看作者文档就好
https://github.com/c0olw/NacosRce

内存马打进去了,冰蝎哥斯拉什么的去连也是可以的,这里就不多写了
漏洞原理
关于原理,这篇文章暂时不写,以后会不会出,不太确定,字数有点多,大家可以先看p1g3师傅的文章学习
1 | |
漏洞修复
目前,官方已发布新版本修复了该漏洞,请受影响的用户升级到安全版本:
https://github.com/alibaba/nacos/releases/tag/1.4.6
https://github.com/alibaba/nacos/releases/tag/2.2.3
临时缓解措施:
该漏洞仅影响7848端口(默认设置下),该端口是Nacos集群间Raft协议的通信端口,不承载客户端请求,如果受影响的用户无法及时升级,可通过禁止该端口的请求来缓解此漏洞。
Derby未授权->SQL注入
漏洞简介
nacos带有一个嵌入式的小型数据库derby,而在版本<=1.4.0的默认配置部署nacos的情况下,它无需认证即可被访问,并执行任意sql查询,导致敏感信息泄露,而CVE-2021-29442是因为最开始开发者没有为这个内存型数据库接口配置任何的访问控制引发的。
影响版本:Nacos <= 1.4.0;漏洞编号:CVE-2021-29442
漏洞环境用1.4.0进行测试,也可以用vulhub搭建好像,大家可以试试
漏洞验证
手工验证:
1 | |
当然也可以发数据包试试,sql语句为:select * from users,其他注入语句也是一样的

进阶利用是可以直接用下方的代码来破解此处查出来的用户密码的,毕竟加密方式是公开的
1 | |
漏洞原理
漏洞代码在config\src\main\java\com\alibaba\nacos\config\server\controller\ConfigOpsController.java#derbyOps

跟进一下看一眼,第一个if的值取决于是否standalone模式启动的nacos,所以在standalone模式启动nacos的话,默认就可以进入第一个if
1 | |

跟进看一下embeddedStorage

跟进getStandaloneMode(),找到这个方法,我IDEA不知道哪里出了问题,方法跟进不过去,只能搜一下找到定义方法的地方

第二个if也仅仅是判断了参数sql的值是否以”select”为字符串开头,然后就直接可以使用derby的查询功能了。
修复方案
参考1.4.1中此处的代码,添加了nacos/admin 的注解来限制仅管理员角色使用该接口(Nacos基于Spring Security来做了访问控制)

开启鉴权配置后即可做到限制未授权访问

Derby未授权->SQL注入->RCE
漏洞描述
在上文中我们分析了,Derby未授权SQL注入利用的是/derby这个路由,但是限制了语句必须为select开头的即查询语句,而仅仅是查询语句就无法RCE。所以DerbyRCE的这个漏洞是利用removal接口在完成这个利用链完成derby注入的深入利用(最开始出来的打法用到的是”CALL sqlj.install_jar”简单来说就是将远程服务器上的jar包导入数据库,就可以动态调用类中的static方法),也就是所谓组合拳RCE,可以算是Nacos远程代码执行
这个漏洞没给编号,看了一下长亭的通告是7月19日的通告,挺吓人的,HW刚准备开始就出来了,影响版本Nacos < 2.4.0

我这里漏洞环境就用了2.3.2,只要低于2.4.0就可以了
漏洞检测
关于漏洞的手动检测,我看懂了,但是感觉比较复杂,方法我写在这里大家可以去验证一下,我更倾向于直接脚本一把梭,虽然原版poc被删了但是还是流传出来了并且武器化了,关于原版poc的分析后续我可能会出,时间未知
https://github.com/FFR66/Nacos_Rce
1 | |

这种思路就是我们写到本地,也就是我们的vps,然后去加载。但是这种方式,必须在机器出网的情况下,如果目标机器不出网,就歇菜了
这里还想说在网上看到的另一位师傅的思路,通过create type typeClass external 的方式自定义数据类型来映射java类
首先验证未授权存在
1 | |
然后制作命令执行类
1 | |
对应的sql语句,这些语句其实也好理解,上面我们是从vps去加载我们的payload,这个是我们自己去在目标机器通过create type typeClass external 的方式自定义数据类型来映射java类,达到恶意类的效果并且执行我们的命令
1 | |
攻击:去GET我们写到目标机器的这个类,获取到我们想要的
1 | |
不出意外的话复现会遇到”file xxx does not exist”,这个实际上是正常的,建议写个脚本挂着打然后看运气什么时候碰撞成功了
这位师傅提供的思路我并没去复现,大家感兴趣的可以试一下
漏洞原理
两部分,未授权部分的分析在上文已经写出了。
derby数据库rce的原理重点就是理解上面写出的打法中用到的函数,第三种在上文中已经写了,这里简单补充下一和二
1 | |
关于具体的代码层面,这里我就不写了,其实代码跟进可能稍微难懂,其实就是一个条件竞争并且derby数据库是支持调用Java的方法,然后又结合未授权,导致了这个RCE的产生
https://baijiahao.baidu.com/s?id=1804988231747535544&wfr=spider&for=pc
漏洞修复
官方已在2.4.0版本中引入了一个新的选项 derbyOpsEnabled,并将其默认设置为关闭,以防止相关接口被滥用。可在Nacos官网下载最新版本使用。
参考链接
再次特别鸣谢各位师傅
https://xz.aliyun.com/t/13169?time__1311=GqmhLGOGkD%2FD78G7FmeYveAKg115bIeD
https://xz.aliyun.com/t/15151?time__1311=GqjxuQD%3DcDlx0nD2DUxYwrIDcmYwhjox