获取解析后的JWT body中的username,若为Tom,则成功!
ResultSet rs = connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = '" + kid + "'"); while (rs.next()) { return TextCodec.BASE64.decode(rs.getString(1)); @PostMapping("delete") public @ResponseBody AttackResult resetVotes(@RequestParam("token") String token) { if (StringUtils.isEmpty(token)) { return trackProgress(failed().feedback("jwt-invalid-token").build()); } else { try { final String[] errorMessage = {null}; Jwt jwt = Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() { @Override public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) { final String kid = (String) header.get("kid"); try { Connection connection = DatabaseUtilities.getConnection(webSession); ResultSet rs = connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = '" + kid + "'"); while (rs.next()) { return TextCodec.BASE64.decode(rs.getString(1)); } } catch (SQLException e) { errorMessage[0] = e.getMessage(); } return null; } }).parseClaimsJws(token); if (errorMessage[0] != null) { return trackProgress(failed().output(errorMessage[0]).build()); } Claims claims = (Claims) jwt.getBody(); String username = (String) claims.get("username"); if ("Jerry".equals(username)) { return trackProgress(failed().feedback("jwt-final-jerry-account").build()); } if ("Tom".equals(username)) { return trackProgress(success().build()); } else { return trackProgress(failed().feedback("jwt-final-not-tom").build()); } } catch (JwtException e) { return trackProgress(failed().feedback("jwt-invalid-token").output(e.toString()).build()); } } }收集到的信息:
1.JWT中原始数据: “kid”: “webgoat_key”
sql语句:”SELECT key FROM jwt_keys WHERE id = ‘” + kid + “‘”;
那么就是说明,jwt_keys表中有一个id的值是:“webgoat_key”
2.Jwts.parser().setSigningKeyResolver(自定义方法获取签名KEY).parseClaimsJws(token);//通过自定义方法获取签名key然后对token进行JWT解析
3.JWT中username要等于Tom
思路:
篡改JWT:
利用sql inject,控制查询语句的查询值来控制JWT的密钥,从而伪造JWT,完成任务。
步骤:
1.从收集的信息中可以构造出sql语句 select id from jwt_keys where id =’webgoat_key’;这个查询结果会输出’webgoat_key’,所以在“: “y’ and 1=2 union select id from jwt_keys where id =’webgoat_key”;签名设置为webgoat_key
2.在payload的username篡改成Tom
3.提交篡改后的JWT进行验证。
失败了。那就来跟踪一下代码执行的情况,定位问题吧。

sql injection的payload确实进来了。
执行的结果也和我们设想的一样,目前没有问题。所以问题就在签名部分没有通过。(值得注意:尽管签名校验没通过,但sql injection的payload已经执行)