从CTFHub靶场实战聊聊JWT那些不安全的默认配置在Web安全领域JSON Web TokenJWT作为一种轻量级的身份验证机制被广泛应用于现代Web应用和API接口中。然而正是这种看似简单的技术却因为开发者的疏忽和默认配置的不安全性成为了攻击者眼中的香饽饽。本文将通过CTFHub靶场中的实战案例深入剖析JWT常见的安全隐患并提供实用的工具和脚本帮助读者在实战中快速识别和利用这些漏洞。1. JWT基础与安全风险概述JWT由三部分组成头部Header、载荷Payload和签名Signature这三部分通过点号连接形成一个完整的令牌。看似简单的结构背后却隐藏着多个可能被攻击者利用的安全隐患。典型的JWT结构示例eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c在实际应用中JWT的安全风险主要来自以下几个方面算法选择不当使用弱加密算法或允许算法为空none算法密钥管理不善使用默认密钥、弱密钥或密钥泄露令牌验证不严未验证签名、未检查过期时间信息泄露风险敏感数据存储在未加密的载荷中提示JWT本身是明文传输的头部和载荷部分只是Base64编码而非加密。任何能够截获令牌的人都可以轻松解码查看内容。2. 无签名漏洞算法置空的危险在CTFHub的JWT题目中最常见的一类漏洞就是无签名攻击即利用JWT支持none算法的特性绕过验证。2.1 漏洞原理JWT规范允许使用none算法这意味着令牌可以不进行签名验证。当服务器配置不当未明确禁用none算法时攻击者可以篡改令牌内容后将算法改为none从而绕过服务器的签名验证。修改算法为none的步骤获取原始JWT令牌解码头部将alg字段改为none修改载荷中的任意内容如将普通用户改为管理员删除签名部分或保留空签名将修改后的令牌发送给服务器2.2 实战案例CTFHub JWT题目解析假设我们遇到一个CTFHub题目要求通过JWT漏洞获取管理员权限。以下是具体操作步骤获取原始令牌 通过登录获取普通用户的JWT令牌eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imd1ZXN0Iiwicm9sZSI6InVzZXIifQ.7Z6Jz4hX6d9gRtj5l7K8m9n0o1p2q3r4s5t6u7v8w9x0y解码分析 使用jwt.io解码头部{alg:HS256,typ:JWT}载荷{username:guest,role:user}构造攻击令牌 修改头部和载荷{ alg: none, typ: JWT } { username: guest, role: admin }生成攻击令牌 将修改后的头部和载荷进行Base64编码并去掉签名部分eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VybmFtZSI6Imd1ZXN0Iiwicm9sZSI6ImFkbWluIn0.提交测试 将生成的令牌替换原有Authorization头中的令牌成功获取管理员权限。2.3 防御措施为了防止无签名攻击开发者应该明确指定允许的算法列表禁用none算法使用成熟的JWT库避免自行实现验证逻辑在验证令牌时严格检查算法是否与预期一致Python代码示例安全的JWT验证import jwt from jwt.exceptions import InvalidAlgorithmError def verify_jwt(token, secret): try: # 明确指定允许的算法 payload jwt.decode(token, secret, algorithms[HS256]) return payload except InvalidAlgorithmError: raise Exception(不安全的算法类型)3. 弱密钥与密钥爆破攻击另一个常见的JWT安全问题是对称加密中使用弱密钥或默认密钥。在CTFHub靶场中这类题目往往要求通过爆破方式获取HS256算法的密钥。3.1 漏洞原理HS256HMAC with SHA-256是一种对称加密算法使用同一个密钥进行签名和验证。如果密钥强度不足如短密码、常见单词攻击者可以通过暴力破解或字典攻击获取密钥从而伪造任意令牌。常见弱密钥示例secretpassword123456qwertysupersecret3.2 实战工具hashcat爆破JWT密钥hashcat是一款强大的密码恢复工具可以用来爆破JWT密钥。以下是具体操作步骤准备JWT令牌和字典文件 假设我们有令牌eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imd1ZXN0Iiwicm9sZSI6InVzZXIifQ.7Z6Jz4hX6d9gRtj5l7K8m9n0o1p2q3r4s5t6u7v8w9x0y以及一个包含常见密钥的字典文件wordlist.txt使用hashcat爆破hashcat -m 16500 -a 0 jwt.txt wordlist.txt --force参数说明-m 16500指定JWT爆破模式-a 0使用字典攻击jwt.txt包含JWT令牌的文件wordlist.txt字典文件获取爆破结果 如果爆破成功hashcat会输出找到的密钥。3.3 防御措施为了防止密钥被爆破使用足够长且复杂的密钥至少32个随机字符避免使用默认密钥或常见单词定期轮换密钥考虑使用非对称加密算法如RS256密钥生成建议# 生成32字节随机密钥 openssl rand -hex 324. 算法混淆攻击算法混淆攻击是一种利用服务器在验证JWT时未正确处理算法类型而导致的漏洞。在CTFHub靶场中这类题目通常涉及从HS256到RS256的算法转换。4.1 漏洞原理当服务器预期使用RS256非对称加密算法但实际上接受HS256对称加密算法时攻击者可以利用这一不一致性进行攻击。具体步骤获取服务器的公钥使用公钥作为HS256的密钥伪造令牌并将算法改为HS256服务器使用公钥验证HS256签名错误地认为令牌有效4.2 实战工具jwt_tool的使用jwt_tool是一款专门用于JWT测试的工具可以方便地进行各种攻击尝试。算法混淆攻击步骤获取公钥 通常可以从应用的/static目录或/.well-known端点找到公钥。使用jwt_tool生成恶意令牌python3 jwt_tool.py 原始JWT -X k -pk public.pem参数说明-X k指定算法混淆攻击-pk public.pem指定公钥文件测试令牌 将生成的令牌替换原有令牌测试是否能够绕过验证。4.3 防御措施为了防止算法混淆攻击在验证令牌时严格检查算法是否与预期一致不要将公钥用于对称加密验证使用专门的JWT库避免自行实现验证逻辑Java代码示例安全的算法验证Jwts.parser() .setSigningKey(secret) .require(alg, RS256) // 明确要求特定算法 .parseClaimsJws(token);5. 其他常见JWT安全问题除了上述主要漏洞外JWT在实际应用中还存在其他安全问题值得开发者注意。5.1 令牌过期问题JWT通常包含exp过期时间字段但如果服务器未正确验证攻击者可以使用过期的令牌继续访问系统。防御措施始终验证exp字段设置合理的令牌有效期考虑使用刷新令牌机制5.2 敏感信息泄露由于JWT的载荷部分是明文Base64编码如果在其中存储敏感信息如密码、API密钥可能导致信息泄露。防御措施不要在JWT中存储敏感信息必要时对载荷进行加密使用HTTPS传输令牌5.3 令牌撤销问题JWT一旦签发在有效期内无法单独撤销这是其设计上的一个局限性。解决方案使用短有效期令牌配合刷新令牌维护令牌黑名单采用分布式会话存储检查令牌状态6. JWT安全最佳实践基于CTFHub靶场和实际应用中的经验我们总结出以下JWT安全最佳实践开发配置清单安全措施具体实施备注算法选择禁用none优先使用RS256非对称加密更安全密钥管理使用强密钥定期轮换建议32字节以上随机密钥令牌验证检查算法、签名、过期时间完整验证链信息存储避免敏感数据最小化声明只存储必要信息传输安全始终使用HTTPS防止中间人攻击令牌有效期设置合理短的有效期通常1-2小时运维检查清单定期审计JWT实现代码监控异常令牌使用模式保持JWT库更新到最新版本对开发团队进行安全培训建立应急响应机制在实际开发中我曾遇到一个案例由于使用了默认的HS256密钥secret导致攻击者轻易伪造了管理员令牌。这个教训让我深刻认识到安全无小事每一个默认配置都可能成为系统漏洞。