JWT安全
JWT简介
JSON Web Token(JSON Web 令牌)是一种跨域验证身份的方案。JWT 不加密传输的数据,但能够通 过数字签名来验证数据未被篡改。
JWT 分为三部分,头部(Header),声明(Claims),签名(Signature),三个部分以英文句号.隔开。 JWT 的内容以 Base64URL 进行了编码。
如
eyJhbGciOiJIUzI1NiJ9.ew0KICAiYXV0aG9yaXRpZXMiIDogWyAiUk9MRV9BRE1JTiIsICJST0xFX1VTRVIiIF0sDQogICJjbGllbnRfaWQiIDogIm15LWNsaWVudC13aXRoLXNlY3JldCIsDQogICJleHAiIDogMTYwNzA5OTYwOCwNCiAgImp0aSIgOiAiOWJjOTJhNDQtMGIxYS00YzVlLWJlNzAtZGE1MjA3NWI5YTg0IiwNCiAgInNjb3BlIiA6IFsgInJlYWQiLCAid3JpdGUiIF0sDQogICJ1c2VyX25hbWUiIDogInVzZXIiDQp9.9lYaULTuoIDJ86-zKDSntJQyHPpJ2mZAbnWRfel99iI
- eyJhbGciOiJIUzI1NiJ9就是头部,base64解码之后为{"alg":"HS256"}
alg是说明这个 JWT 的签名使用的算法的参数,常见值用 HS256(默认),HS512 等,也可以为 None。HS256 表示 HMAC SHA256。 - ew0KICAiYXV0aG9yaXRpZXMiIDogWyAiUk9MRV9BRE1JTiIsICJST0xFX1VTRVIiIF0sDQogICJjbGllbnRfaWQiIDogIm15LWNsaWVudC13aXRoLXNlY3JldCIsDQogICJleHAiIDogMTYwNzA5OTYwOCwNCiAgImp0aSIgOiAiOWJjOTJhNDQtMGIxYS00YzVlLWJlNzAtZGE1MjA3NWI5YTg0IiwNCiAgInNjb3BlIiA6IFsgInJlYWQiLCAid3JpdGUiIF0sDQogICJ1c2VyX25hbWUiIDogInVzZXIiDQp9 解码之后为
{
"authorities" : [ "ROLE_ADMIN", "ROLE_USER" ],
"client_id" : "my-client-with-secret",
"exp" : 1607099608,
"jti" : "9bc92a44-0b1a-4c5e-be70-da52075b9a84",
"scope" : [ "read", "write" ],
"user_name" : "user"
}
这是声明
签名(Signature) 服务器有一个不会发送给客户端的密码(secret),用头部中指定的算法对头部和声明的内容用此密 码进行加密,生成的字符串就是 JWT 的签名。
下面是一个用 HS256 生成 JWT 的代码例子
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),secret)
JWT工作流程
- 用户端登录,用户名和密码在请求中被发往服务器
- (确认登录信息正确后)服务器生成 JSON 头部和声明,将登录信息写入 JSON 的声明中(通常不 应写入密码,因为 JWT 是不加密的),并用 secret 用指定算法进行加密,生成该用户的 JWT。此时, 服务器并没有保存登录状态信息。
- 服务器将 JWT(通过响应)返回给客户端
- 用户下次会话时,客户端会自动将 JWT 写在 HTTP 请求头部的 Authorization 字段中
- 服务器对 JWT 进行验证,若验证成功,则确认此用户的登录状态
- 服务器返回响应
JWT漏洞成因
若是服务端没有严谨的配置,即并不一定需要拥有签名的JSON token也可以进行身份验证时,就容易造成身份伪造
详细的分析可看:https://juejin.cn/post/7035884549221384223
JWT实战分析
webgoat jwt第五关
尝试用令牌成为管理员用户,一但成为管理员用户即可重置投票
抓取删除投票的包
然后取出jwt令牌查看,
尝试将alg签名算法改为0,admin的改为true。注意由于java原因,可能会对base64编码中的=号出现歧义,因此要将其删除
最终成功
payload:eyJhbGciOiJub25lIn0.eyJpYXQiOjE2NTE0MDkwMjAsImFkbWluIjoidHJ1ZSIsInVzZXIiOiJUb20ifQ.
这里就是利用服务端可以允许none的签名
webgoat jwt第6关
尝试爆破出秘钥,并重新签名将用户名改为WebGoat
可以使用c-jwt-cracker,但一般来说爆破局限性比较大
这里的密码是victory,需要注意的是时间戳同时需要修改签名过期的时间,时间戳
javaweb预编译绕过
https://www.cnblogs.com/klyjb/p/11473857.html
版权声明:本文为原创文章,版权归 Bill's Blog 所有,转载请注明出处!如相关链接出现404,可以在文章下面评论留言。