从一次内部渗透测试说起:我们如何利用JWT令牌篡改拿到了管理员权限
渗透测试实战JWT令牌篡改攻防全解析那天下午三点我们红队接到一个特殊任务——对公司的核心业务系统进行内部渗透测试。系统刚刚完成微服务架构改造前端采用React框架后端API全部基于JWT令牌进行身份验证。项目经理拍着胸脯保证这套安全体系绝对可靠你们要是能找出漏洞我请大家吃日料。事实证明那顿日料他请定了。1. 突破口API端点发现与初步分析任何渗透测试都始于信息收集。我们首先使用公司配发的普通员工账号登录系统同时打开Burp Suite抓包。在浏览用户个人中心时Burp的Proxy历史记录里出现了这样的请求GET /api/v1/user/profile HTTP/1.1 Host: internal.corp.com Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwidXNlcm5hbWUiOiJqb2huLmRvZSIsInJvbGUiOiJlbXBsb3llZSIsImlhdCI6MTUxNjIzOTAyMn0.5mhBHQ6gQzY6f5Q7w7Q8w9e0rTspnH4kLmZuZ0Jjg5E这个JWT令牌引起了我们的注意。通过Burp的Decoder模块解码后令牌结构清晰可见{ alg: HS256, typ: JWT } { sub: 1234567890, username: john.doe, role: employee, iat: 1516239022 }关键发现使用HS256对称加密算法包含明显的角色声明(role字段)没有过期时间(exp字段)签发时间(iat)显示令牌已使用超过6个月提示长期有效的JWT令牌是重大安全隐患建议设置合理的过期时间(通常不超过1小时)2. JWT令牌篡改实验发现JWT的结构缺陷后我们开始测试篡改可能性。首先尝试最简单的重放攻击使用原始令牌访问管理员接口/api/v1/admin/users返回403 Forbidden符合预期修改role字段为admin后重放请求仍然返回403因为签名验证失败接下来尝试破解签名密钥。由于系统使用HS256算法我们需要获取或暴力破解签名密钥。通过以下步骤最终获取了密钥# 使用hashcat进行暴力破解 hashcat -m 16500 jwt.txt rockyou.txt -O破解参数对比表参数初始值优化值字典rockyou.txt公司名常见密码组合线程数默认最大尝试次数约100万/分钟约300万/分钟8小时后我们成功获取了签名密钥Company2023。这个弱密钥直接导致了整个安全体系的崩塌。3. 权限提升实战有了签名密钥我们可以任意构造有效令牌。以下是生成管理员令牌的Python代码示例import jwt secret Company2023 payload { sub: 1234567890, username: john.doe, role: admin, iat: 1516239022 } token jwt.encode(payload, secret, algorithmHS256) print(token)使用新生成的令牌我们成功实现了查看所有用户信息修改系统配置访问财务敏感数据创建具有管理员权限的新用户攻击路径总结发现长期有效的JWT令牌识别弱加密算法(HS256)暴力破解签名密钥构造高权限令牌完全控制系统4. 防御方案设计与实施完成渗透后我们立即与开发团队合作修复漏洞。以下是实施的多层防御措施技术控制措施层级措施实施细节令牌设计使用RS256非对称加密私钥签名公钥验证生命周期短期有效刷新机制访问令牌15分钟过期内容安全移除敏感声明只保留必要字段密钥管理定期轮换密钥每季度更换一次开发流程改进在CI/CD管道中加入JWT安全扫描对密钥进行强度检测实施自动化令牌撤销机制定期红蓝对抗演练注意防御措施需要根据业务场景平衡安全性与用户体验过度安全可能影响系统可用性5. 深度防御超越基础配置真正的安全需要纵深防御体系。我们进一步实施了这些增强措施监控与响应实时分析JWT使用模式异常令牌使用告警如权限突变自动阻断可疑请求架构级防护# 示例JWT验证中间件增强版 def verify_jwt_middleware(request): token extract_token(request) try: payload jwt.decode(token, PUBLIC_KEY, algorithms[RS256]) if payload.get(role) admin: log_admin_access(request.ip) verify_second_factor(request) return payload except jwt.ExpiredSignatureError: abort(401, Token expired) except jwt.InvalidTokenError: abort(403, Invalid token)人员培训重点安全编码规范威胁建模方法应急响应流程安全设计模式那次渗透测试后公司全面升级了身份认证体系。最让我意外的是开发团队主动要求每月进行一次安全演练——那顿日料花的真值。