本帖最后由 alyssa 于 2023-4-7 00:18 编辑
转载于:安全帮Live
什么是JWT ?
JSON Web Token (JWT) 是一种紧凑的 URL 安全方式,用于表示要在两方之间传输的声明。JWT 中的声明被编码为 JSON 对象,用作 JSON Web 签名 (JWS) 结构的有效负载或用作 JSON Web 加密 (JWE) 结构的明文,从而使声明能够进行数字签名或完整性保护使用消息验证码 (MAC) 和/或加密。
JSON Web 令牌 (JWT) 是一种标准化格式,用于在系统之间发送加密签名的 JSON 数据。它们理论上可以包含任何类型的数据,但最常用于发送有关用户的信息(“声明”),作为身份验证、会话处理和访问控制机制的一部分。
JWT格式 3个部分 : HEADER, PAYLAOD 和 SIGNATURE由点 ( . )分隔eyJraWQiOiI5MTM2ZGRiMy1jYjBhLTRhMTktYTA3ZS1lYWRmNWE0NGM4YjUiLCJhbGciOiJSUzI1NiJ9. HEADER eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTY0ODAzNzE2NCwibmFtZSI6IkNhcmxvcyBNb250b3lhIiwic3ViIjoiY2FybG9zIiwicm9sZSI6ImJsb2dfYXV0aG9yIiwiZW1haWwiOiJjYXJsb3NAY2FybG9zLW1vbnRveWEubmV0IiwiaWF0IjoxNTE2MjM5MDIyfQ. PAYLOAD SYZBPIBg2CRjXAJ8vCER0LA_ENjII1JakvNQoP-Hw6GG1zfl4JyngsZReIfqRvIAEi5L4HV0q7_9qGhQZvy9ZdxEJbwTxRs_6Lb-fZTDpW6lKYNdMyjw45_alSCZ1fypsMWz_2mTpQzil0lOtps5Ei_z7mM7M8gCwe_AGpI53JxduQOaB5HkT5gVrv9cKu9CsW5MS6ZbqYXpGyOG5ehoxqm8DL5tFYaW3lB50ELxi0KsuTKEbD0t5BCl0aCR2MBJWAbN-xeLwEenaqBiwPVvKixYleeDQiBEIylFdNNIMviKRgXiYuAvMziVPbwSgkZVHeEdF5MQP1Oe2Spac-6IfA SIGNATURE
这就是从 JWT TOKEN 解码后的 Paylaod 看起来像 - <font color="#000000" face="宋体">{
- “iss” :“portswigger” ,
- “exp” :1648037164 ,
- “name” :“Carlos Montoya” ,
- “sub” :“carlos” ,
- “role” :“blog_author” ,
- “email” :“carlos@carlos-montoya ” .net" ,
- "iat" : 1516239022
- }</font>
复制代码
在大多数情况下,任何有权访问令牌的人都可以轻松读取或修改此数据。因此,任何基于 JWT 的机制的安全性都严重依赖于加密签名。颁发令牌的服务器通常通过散列标头和有效负载来生成签名。在某些情况下,他们还会加密生成的哈希值。无论哪种方式,此过程都涉及秘密签名密钥。此机制为服务器提供了一种方法来验证令牌中的任何数据自发布以来均未被篡改: - 由于签名直接源自令牌的其余部分,因此更改标头或paylaod的单个字节会导致签名不匹配。
- 在不知道服务器的秘密签名密钥的情况下,不可能为给定的标头或paylaod生成正确的签名。
JWT 令牌主要用于会话令牌、用于用户身份验证和授权的 API 令牌。当用户登录服务器时,将为登录的用户生成一个签名的 JWT 令牌,并将其用作会话令牌以进行身份验证。 用户将修改后的 JWT 发送到服务器,以便可以绕过服务器上的访问控制、权限提升或帐户接管 我们使用完整的工具来操纵 JWT 令牌 JWT Editor Burp-Suite 扩展,对分析令牌、编辑和开发非常有用。 jwt.io:这些也是 JWT-Editor 的替代品,用于查看、签名和利用 jwt 错误配置漏洞。
为了找到这些类型的漏洞,我们需要采用手动方法,并且需要逐一检查所有可能的错误配置
- {
- "username" : "dk" ,
- "isAdmin" : false //将此更改为 true,
- //重新编码令牌并将其发送到服务器
- }
复制代码
- <font color="#000000" face="宋体">hashcat hashcat -a 0 -m 16500 jwt wordlist</font>
复制代码
https://github.com/wallarm/jwt-secrets/blob/master/jwt.secrets.list常见的 jwt 秘密列表
Acc to JWS only algparameter 是强制性的,但实际上jwt headers(JOSE headers)包含几个参数,例如 jwk: JSON WEB KEY - 提供一个嵌入的 JSON 对象表示密钥 jku: JSON Web 密钥集 Url:提供一个 URL,服务器可以从该 URL 获取一组包含正确密钥的密钥。 kid: 密钥 ID - 为密钥提供一个 ID,以便服务器可以识别正确的密钥,因为存在多个密钥
- {
- “kid” :“ed2Nf8sb-sD6ng0-scs5390g-fFD8sfxG” ,
- “typ” :“JWT” ,
- “alg” :“RS256” ,
- “jwk” :{
- “kty” :“RSA” ,
- “e” :“AQAB " ,
- "kid" : "ed2Nf8sb-sD6ng0-scs5390g-fFD8sfxG" ,
- "n" : "yy1wpYmffgXBxhAUJzHHocCuJolwDqql75ZWuCQ_cb33K2vh9m"
- }
- }
复制代码
理想情况下,服务器应该只使用有限的公钥白名单来验证 JWT 签名。但是,配置错误的服务器有时会使用嵌入在参数中的任何密钥jwk。
我们可以使用我们自己生成的 RSA 私钥对修改后的 jwt 进行签名,然后在jwk参数中嵌入匹配的公钥来利用这一点。 通过 jku 参数注入自签名 JWT
一些服务器允许您使用jku (JWK set URL) ,标头参数,而不是直接使用 jwk 标头参数嵌入公钥 有时 JWK 集会通过 Standerd 端点公开公开,例如/.well-known/jwks.json - {
- "keys": [
- {
- "kty": "RSA",
- "e": "AQAB",
- "kid": "75d0ef47-af89-47a9-9061-7c02a610d5ab",
- "n": "o-yy1wpYmffgXBxhAUJzHHocCuJolwDqql75ZWuCQ_cb33K2vh9mk6GPM9gNN4Y_qTVX67WhsN3JvaFYw-fhvsWQ"
- },
- {
- "kty": "RSA",
- "e": "AQAB",
- "kid": "d8fDFo-fS9-faS14a9-ASf99sa-7c1Ad5abA",
- "n": "fc3f-yy1wpYmffgXBxhAUJzHql79gNNQ_cb33HocCuJolwDqmk6GPM4Y_qTVX67WhsN3JvaFYw-dfg6DH-asAScw"
- }
- ]
- }
复制代码更安全的网站只会从受信任的域中获取密钥,但有时您可以利用 URL解析差异来绕过这种过滤修改jwt的payload。 在JWT 标头中注入“ jku ”标头参数,并将已签名的公钥按上述格式放入your-server.com/jwk.json中。 - "kid":"somr hex of kid of key","kid":"somr hex of kid of key",
- "jku":"https://ourserver.com/jwks.json"
复制代码 如何防止 JWT 攻击
|