0x01 jwt简介

http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证。所以为了让我们的应用能识别是哪个用户发出的请求,我们只能在服务器存储一份用户登录的信息,这份登录信息会在响应时传递给浏览器,告诉其保存为cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了,这就是传统的基于session认证。
传统session认证问题有:session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大;session保存在认证服务器的内存中不适用于分布式应用。
jwt基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端内存中去保留用户的session。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。

0x02 JWT构成

jwt由三段信息组成,由点号连接,分别是header、payload、signature,完整如下

  1. eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
  • header

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
    base64解密之后如下:
    {
    "alg": "HS256",
    "typ": "JWT"
    }
    
  • payload

    {
    "sub": "1234567890",
    "name": "John Doe",
    "iat": 1516239022
    }
    
  • signature

这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分

实际情况如下图,一般看到_Authorization: Bearer eyJhbGciOiJIUzUxMiJ9_就是使用了jwt
image.png
也可以使用正则过滤在burp搜索是否有使用JWT的应用

[= ]ey[A-Za-z0-9_-]*\.[A-Za-z0-9._-]*         
[= ]ey[A-Za-z0-9_\/+-]*\.[A-Za-z0-9._\/+-]*

image.png

0x03 攻击思路

1、修改签名算法

{ "alg": "HS256", "typ": "JWT"}修改为{ "alg": "none", "typ": "JWT"}
在某些情况下,此时只用前两段加密后数据组成的token也可以认证成功

2、删除签名

删除整个签名部分也可能导致JWT被解码,最终如下,只由header和payload组成,最后保留试试eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.

3、爆破秘钥

网上有很多爆破的工具,但是据我所知很多key都是32位的类似于md5的值,不好爆破

4、修改用户名

修改payload字段的用户名等信息,然后执行修改名称等操作,尝试是否存在越权