From 8cd3bd295b3f73637a71452cc5e697ac36817f18 Mon Sep 17 00:00:00 2001 From: Jeroen Willemsen Date: Fri, 5 Aug 2022 08:43:16 +0200 Subject: [PATCH 01/13] update dockerfile.web to allow for your own key creation #366 --- Dockerfile.web | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile.web b/Dockerfile.web index 6974f1684..2ce76f005 100644 --- a/Dockerfile.web +++ b/Dockerfile.web @@ -4,10 +4,12 @@ ARG argBasedVersion="1.5.0" ARG CANARY_URLS="http://canarytokens.com/terms/about/s7cfbdakys13246ewd8ivuvku/post.jsp,http://canarytokens.com/terms/about/y0all60b627gzp19ahqh7rl6j/post.jsp" ARG CTF_ENABLED=false ARG HINTS_ENABLED=true +ARG CTF_KEY=TRwzkRJnHOTckssAeyJbysWgP!Qc2T ENV APP_VERSION=$argBasedVersion ENV K8S_ENV=Heroku(Docker) ENV canarytokenURLs=$CANARY_URLS ENV ctf_enabled=$CTF_ENABLED +ENV ctf_key=$CTF_KEY ENV hints_enabled=$HINTS_ENABLED ENV challengedockermtpath="/var/helpers" ENV keepasspath="/var/helpers/alibabacreds.kdbx" From 7fc26427fb523a0b10380c8c8fcb838c440643f5 Mon Sep 17 00:00:00 2001 From: Jeroen Willemsen Date: Fri, 5 Aug 2022 09:12:17 +0200 Subject: [PATCH 02/13] Add support for k8s in ctf container when overriden for #366 --- Dockerfile.web | 7 +++++ .../wrongsecrets/RuntimeEnvironment.java | 30 ++++++++++++++----- src/main/resources/templates/welcome.html | 2 +- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/Dockerfile.web b/Dockerfile.web index 2ce76f005..d6be7e87d 100644 --- a/Dockerfile.web +++ b/Dockerfile.web @@ -4,7 +4,11 @@ ARG argBasedVersion="1.5.0" ARG CANARY_URLS="http://canarytokens.com/terms/about/s7cfbdakys13246ewd8ivuvku/post.jsp,http://canarytokens.com/terms/about/y0all60b627gzp19ahqh7rl6j/post.jsp" ARG CTF_ENABLED=false ARG HINTS_ENABLED=true +#ONLY OVERRIDE THE ARGS BELOW WHEN YOU ARE SETTING UP A CTF! ARG CTF_KEY=TRwzkRJnHOTckssAeyJbysWgP!Qc2T +ARG CHALLENGE_5_VALUE=if_you_see_this_please_use_k8s +ARG CHALLENGE_6_VALUE=if_you_see_this_please_use_k8s +ARG CHALLENGE_7_VALUE=if_you_see_this_please_use_K8S_and_Vault ENV APP_VERSION=$argBasedVersion ENV K8S_ENV=Heroku(Docker) ENV canarytokenURLs=$CANARY_URLS @@ -13,6 +17,9 @@ ENV ctf_key=$CTF_KEY ENV hints_enabled=$HINTS_ENABLED ENV challengedockermtpath="/var/helpers" ENV keepasspath="/var/helpers/alibabacreds.kdbx" +ENV SPECIAL_K8S_SECRET=$CHALLENGE_5_VALUE +ENV SPECIAL_SPECIAL_K8S_SECRET=$CHALLENGE_6_VALUE +ENV vaultpassword=$CHALLENGE_7_VALUE COPY .github/scripts/ /var/helpers COPY src/test/resources/alibabacreds.kdbx /var/helpers CMD java -Xms128m -Xmx128m -Xss512k -jar -Dserver.port=$PORT -XX:MaxRAMPercentage=75 -XX:MinRAMPercentage=25 -Dspring.profiles.active=without-vault application.jar diff --git a/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java b/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java index 1e18884cb..2ce7391f5 100644 --- a/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java +++ b/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java @@ -22,14 +22,21 @@ @Component public class RuntimeEnvironment { + @Value("${ctf_enabled}") + private boolean ctf_mode_enabled; + private final String defaultValueChallenge5 = "if_you_see_this_please_use_k8s"; + + @Value("${SPECIAL_K8S_SECRET}") + private String challenge5Value; //used to determine if they are overriden; + private static final Map> envToOverlappingEnvs = Map.of( - HEROKU_DOCKER, List.of(DOCKER, HEROKU_DOCKER), - DOCKER, List.of(DOCKER, HEROKU_DOCKER), - GCP, List.of(DOCKER, K8S, VAULT), - AWS, List.of(DOCKER, K8S, VAULT), - AZURE, List.of(DOCKER, K8S, VAULT), - VAULT, List.of(DOCKER, K8S), - K8S, List.of(DOCKER) + HEROKU_DOCKER, List.of(DOCKER, HEROKU_DOCKER), + DOCKER, List.of(DOCKER, HEROKU_DOCKER), + GCP, List.of(DOCKER, K8S, VAULT), + AWS, List.of(DOCKER, K8S, VAULT), + AZURE, List.of(DOCKER, K8S, VAULT), + VAULT, List.of(DOCKER, K8S), + K8S, List.of(DOCKER) ); public enum Environment { @@ -49,6 +56,10 @@ static Environment fromId(String id) { @Getter private final Environment runtimeEnvironment; + private boolean isK8sUnlockedInCTFMode() { + return ctf_mode_enabled && !challenge5Value.equals(defaultValueChallenge5); + } + @Autowired public RuntimeEnvironment(@Value("${K8S_ENV}") String currentRuntimeEnvironment) { this.runtimeEnvironment = Environment.fromId(currentRuntimeEnvironment); @@ -59,8 +70,11 @@ public RuntimeEnvironment(Environment runtimeEnvironment) { } public boolean canRun(Challenge challenge) { + if (isK8sUnlockedInCTFMode()) { + return challenge.supportedRuntimeEnvironments().contains(runtimeEnvironment) || challenge.supportedRuntimeEnvironments().contains(K8S) || challenge.supportedRuntimeEnvironments().contains(VAULT); + } //TODO: WRITE TEST FOR THIS & UPDATE UI THEN! return challenge.supportedRuntimeEnvironments().contains(runtimeEnvironment) - || !Collections.disjoint(envToOverlappingEnvs.get(runtimeEnvironment), challenge.supportedRuntimeEnvironments()); + || !Collections.disjoint(envToOverlappingEnvs.get(runtimeEnvironment), challenge.supportedRuntimeEnvironments()); } } diff --git a/src/main/resources/templates/welcome.html b/src/main/resources/templates/welcome.html index c814b3be6..f11baf48e 100644 --- a/src/main/resources/templates/welcome.html +++ b/src/main/resources/templates/welcome.html @@ -21,7 +21,7 @@ # - Challenge    + Challenge      Focus    From 8a4181902cebffddbbf17a58a4a7c480cb8226ff Mon Sep 17 00:00:00 2001 From: Jeroen Willemsen Date: Fri, 5 Aug 2022 09:16:52 +0200 Subject: [PATCH 03/13] Fix of environment --- .../java/org/owasp/wrongsecrets/RuntimeEnvironment.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java b/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java index 2ce7391f5..a47fb3c49 100644 --- a/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java +++ b/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java @@ -23,8 +23,7 @@ public class RuntimeEnvironment { @Value("${ctf_enabled}") - private boolean ctf_mode_enabled; - private final String defaultValueChallenge5 = "if_you_see_this_please_use_k8s"; + private boolean ctfModeEnabled; @Value("${SPECIAL_K8S_SECRET}") private String challenge5Value; //used to determine if they are overriden; @@ -57,7 +56,8 @@ static Environment fromId(String id) { private final Environment runtimeEnvironment; private boolean isK8sUnlockedInCTFMode() { - return ctf_mode_enabled && !challenge5Value.equals(defaultValueChallenge5); + String defaultValueChallenge5 = "if_you_see_this_please_use_k8s"; + return ctfModeEnabled && !challenge5Value.equals(defaultValueChallenge5); } @Autowired From fe929d09745047c0931a61efa4bd12374b5e1821 Mon Sep 17 00:00:00 2001 From: Jeroen Willemsen Date: Fri, 5 Aug 2022 23:19:56 +0200 Subject: [PATCH 04/13] Tests to ensure k8s would work in ctf mode --- Dockerfile.web | 4 + .../ChallengesControllerCTFModeTest.java | 33 +++++++ ...trollerCTFModeWithPresetK8sValuesTest.java | 89 +++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetK8sValuesTest.java diff --git a/Dockerfile.web b/Dockerfile.web index d6be7e87d..80b0a1b16 100644 --- a/Dockerfile.web +++ b/Dockerfile.web @@ -9,6 +9,10 @@ ARG CTF_KEY=TRwzkRJnHOTckssAeyJbysWgP!Qc2T ARG CHALLENGE_5_VALUE=if_you_see_this_please_use_k8s ARG CHALLENGE_6_VALUE=if_you_see_this_please_use_k8s ARG CHALLENGE_7_VALUE=if_you_see_this_please_use_K8S_and_Vault +#TODO: CONTINUE ON THE 3 CHALLENGES BELOW AND TEST THEM! (both with and without CTF!) +ARG CHALLENGE_9_VALUE=if_you_see_this_please_use +ARG CHALLENGE_10_VALUE=if_you_see_this_please_use +ARG CHALLENGE_11_VALUE=if_you_see_this_please_use ENV APP_VERSION=$argBasedVersion ENV K8S_ENV=Heroku(Docker) ENV canarytokenURLs=$CANARY_URLS diff --git a/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeTest.java b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeTest.java index e5eebd7a3..02f734f6c 100644 --- a/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeTest.java +++ b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeTest.java @@ -38,6 +38,14 @@ void shouldNotSpoilWhenInCTFMode() throws Exception { } + @Test + void shouldNotSpoilWhenInCTFModeEvenWhenChallengeUnsupported() throws Exception { + mvc.perform(get("/spoil-5")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("Spoils are disabled in CTF mode"))); + + } + @Test void shouldShowFlagWhenRespondingWithSuccessInCTFMode() throws Exception { var spoil = new Challenge1(new InMemoryScoreCard(1)).spoiler().solution(); @@ -50,4 +58,29 @@ void shouldShowFlagWhenRespondingWithSuccessInCTFMode() throws Exception { .andExpect(content().string(containsString("ba9a72ac7057576344856"))); } + + + @Test + void shouldEnableK8sExercises() throws Exception{ + mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("class=\"disabled\">Challenge 5"))) + .andExpect(content().string(containsString("class=\"disabled\">Challenge 6"))) + .andExpect(content().string(containsString("class=\"disabled\">Challenge 7"))); + } + + @Test + void shouldStillDissableTestsIfNotPreconfigured() throws Exception { + testChallenge("/challenge/5"); + testChallenge("/challenge/6"); + testChallenge("/challenge/7"); + } + + private void testChallenge(String url) throws Exception { + mvc.perform(get(url) + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .with(csrf())) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("We are running outside a K8s cluster. Please run this in the K8s cluster as explained in the"))); + } } diff --git a/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetK8sValuesTest.java b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetK8sValuesTest.java new file mode 100644 index 000000000..14985dffe --- /dev/null +++ b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetK8sValuesTest.java @@ -0,0 +1,89 @@ +package org.owasp.wrongsecrets; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.owasp.wrongsecrets.challenges.docker.Challenge1; +import org.owasp.wrongsecrets.challenges.kubernetes.Challenge5; +import org.owasp.wrongsecrets.challenges.kubernetes.Challenge6; +import org.owasp.wrongsecrets.challenges.kubernetes.Challenge7; +import org.owasp.wrongsecrets.challenges.kubernetes.Vaultpassword; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@ExtendWith(SpringExtension.class) +@SpringBootTest( + properties = {"ctf_enabled=true", "ctf_key=randomtextforkey", "SPECIAL_K8S_SECRET=test5", "SPECIAL_SPECIAL_K8S_SECRET=test6", "vaultpassword=test7"}, + classes = WrongSecretsApplication.class +) +@AutoConfigureMockMvc +class ChallengesControllerCTFModeWithPresetK8sValuesTest { + + @Autowired + private MockMvc mvc; + + + @Test + void shouldNotSpoilWhenInCTFMode() throws Exception { + mvc.perform(get("/spoil-5")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("Spoils are disabled in CTF mode"))); + + } + + @Test + void shouldShowFlagWhenRespondingWithSuccessInCTFModeChallenge5() throws Exception { + var spoil = new Challenge5(new InMemoryScoreCard(1), "test5").spoiler().solution(); + mvc.perform(post("/challenge/5") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .param("solution", spoil) + .param("action", "submit") + .with(csrf())) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("26d5e409100ca8dc3bd2dba115b81f5b7889fbbd"))); + } + + @Test + void shouldShowFlagWhenRespondingWithSuccessInCTFModeChallenge6() throws Exception { + var spoil = new Challenge6(new InMemoryScoreCard(1), "test6").spoiler().solution(); + mvc.perform(post("/challenge/6") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .param("solution", spoil) + .param("action", "submit") + .with(csrf())) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("18af49a1b18359e0bf9b9a0"))); + } + + @Test + void shouldShowFlagWhenRespondingWithSuccessInCTFModeChallenge7() throws Exception { + var spoil = new Challenge7(new InMemoryScoreCard(1), null, "test7").spoiler().solution(); + mvc.perform(post("/challenge/7") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .param("solution", spoil) + .param("action", "submit") + .with(csrf())) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("881951b59ea4818c2"))); + } + + @Test + void shouldEnableK8sExercises() throws Exception{ + mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("Challenge 5"))) + .andExpect(content().string(containsString("Challenge 6"))) + .andExpect(content().string(containsString("Challenge 7"))); + } + +} From 81e2de9b45e66c61dd847925a2b839cbdf9c63de Mon Sep 17 00:00:00 2001 From: Jeroen Willemsen Date: Fri, 5 Aug 2022 23:26:21 +0200 Subject: [PATCH 05/13] Update POM file with new version: ctfd-safe-1 --- Dockerfile.web | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.web b/Dockerfile.web index 80b0a1b16..4d048c0b4 100644 --- a/Dockerfile.web +++ b/Dockerfile.web @@ -1,4 +1,4 @@ -FROM jeroenwillemsen/wrongsecrets:1.5.0-no-vault +FROM jeroenwillemsen/wrongsecrets:ctfd-safe-1-no-vault ARG argBasedVersion="1.5.0" ARG CANARY_URLS="http://canarytokens.com/terms/about/s7cfbdakys13246ewd8ivuvku/post.jsp,http://canarytokens.com/terms/about/y0all60b627gzp19ahqh7rl6j/post.jsp" From 66cd641297e748fcb6fef2e804a1c529d741daca Mon Sep 17 00:00:00 2001 From: Jeroen Willemsen Date: Fri, 5 Aug 2022 23:35:22 +0200 Subject: [PATCH 06/13] Fix tests --- .../owasp/wrongsecrets/ChallengesControllerCTFModeTest.java | 3 +-- .../ChallengesControllerCTFModeWithPresetK8sValuesTest.java | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeTest.java b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeTest.java index 02f734f6c..0f715a176 100644 --- a/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeTest.java +++ b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeTest.java @@ -2,7 +2,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.owasp.wrongsecrets.challenges.ChallengeForm; import org.owasp.wrongsecrets.challenges.docker.Challenge1; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -81,6 +80,6 @@ private void testChallenge(String url) throws Exception { .contentType(MediaType.APPLICATION_FORM_URLENCODED) .with(csrf())) .andExpect(status().isOk()) - .andExpect(content().string(containsString("We are running outside a K8s cluster. Please run this in the K8s cluster as explained in the"))); + .andExpect(content().string(containsString("We are running outside a K8s cluster"))); } } diff --git a/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetK8sValuesTest.java b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetK8sValuesTest.java index 14985dffe..495e43168 100644 --- a/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetK8sValuesTest.java +++ b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetK8sValuesTest.java @@ -2,11 +2,9 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.owasp.wrongsecrets.challenges.docker.Challenge1; import org.owasp.wrongsecrets.challenges.kubernetes.Challenge5; import org.owasp.wrongsecrets.challenges.kubernetes.Challenge6; import org.owasp.wrongsecrets.challenges.kubernetes.Challenge7; -import org.owasp.wrongsecrets.challenges.kubernetes.Vaultpassword; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; From ad9550e43cea469cbabad6ae12ad9e9c7bfe0727 Mon Sep 17 00:00:00 2001 From: Jeroen Willemsen Date: Fri, 5 Aug 2022 23:40:55 +0200 Subject: [PATCH 07/13] recheck with newer verssion --- .github/workflows/minikube-vault-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/minikube-vault-test.yml b/.github/workflows/minikube-vault-test.yml index b4751ba43..645a12048 100644 --- a/.github/workflows/minikube-vault-test.yml +++ b/.github/workflows/minikube-vault-test.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v3 - uses: innovationnorway/setup-vault@v1 with: - version: '~1.9' + version: '>1.9' - name: Start minikube uses: medyagh/setup-minikube@master with: From 8d625f7b21c6976b08cd62f03696f1d0467c7d9f Mon Sep 17 00:00:00 2001 From: Jeroen Willemsen Date: Sat, 6 Aug 2022 10:01:04 +0200 Subject: [PATCH 08/13] Update POM file with new version: ctfd-safe-2 --- Dockerfile.web | 2 +- .../owasp/wrongsecrets/challenges/ChallengeUI.java | 6 +++++- src/main/resources/templates/challenge.html | 2 +- src/main/resources/templates/welcome.html | 12 +++++++----- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Dockerfile.web b/Dockerfile.web index 4d048c0b4..8eeb171ef 100644 --- a/Dockerfile.web +++ b/Dockerfile.web @@ -1,4 +1,4 @@ -FROM jeroenwillemsen/wrongsecrets:ctfd-safe-1-no-vault +FROM jeroenwillemsen/wrongsecrets:ctfd-safe-2-no-vault ARG argBasedVersion="1.5.0" ARG CANARY_URLS="http://canarytokens.com/terms/about/s7cfbdakys13246ewd8ivuvku/post.jsp,http://canarytokens.com/terms/about/y0all60b627gzp19ahqh7rl6j/post.jsp" diff --git a/src/main/java/org/owasp/wrongsecrets/challenges/ChallengeUI.java b/src/main/java/org/owasp/wrongsecrets/challenges/ChallengeUI.java index 84e962321..f5dc4dcc7 100644 --- a/src/main/java/org/owasp/wrongsecrets/challenges/ChallengeUI.java +++ b/src/main/java/org/owasp/wrongsecrets/challenges/ChallengeUI.java @@ -69,13 +69,17 @@ public String requiredEnv() { .collect(Collectors.joining()); } + public int difficulty() { + return challenge.difficulty(); + } + public boolean isChallengeEnabled() { return runtimeEnvironment.canRun(challenge); } public static List toUI(List challenges, RuntimeEnvironment environment) { return challenges.stream() - .sorted(Comparator.comparingInt(challenge -> Integer.parseInt(challenge.getClass().getSimpleName().replace("Challenge","")))) + .sorted(Comparator.comparingInt(challenge -> Integer.parseInt(challenge.getClass().getSimpleName().replace("Challenge", "")))) .map(challenge -> new ChallengeUI(challenge, challenges.indexOf(challenge) + 1, environment)) .toList(); } diff --git a/src/main/resources/templates/challenge.html b/src/main/resources/templates/challenge.html index f38b1996e..483fbd694 100644 --- a/src/main/resources/templates/challenge.html +++ b/src/main/resources/templates/challenge.html @@ -3,7 +3,7 @@
-

+

You need to guess the secret that is hidden in Java, Docker, Kubernetes, Vault, AWS or GCP.

diff --git a/src/main/resources/templates/welcome.html b/src/main/resources/templates/welcome.html index f11baf48e..f5f0a0b9d 100644 --- a/src/main/resources/templates/welcome.html +++ b/src/main/resources/templates/welcome.html @@ -17,19 +17,18 @@
- +
- - + + - - @@ -47,6 +46,9 @@ th:if="${challenge.requiredEnv} == 'AWS' or ${challenge.requiredEnv} == 'GCP'or ${challenge.requiredEnv} == 'AZURE'"> +
#Challenge      Challenge      Focus    Difficulty
 AWS, GCP, Azure + +
From 1fe1a079645054be1faa11495faa95c6676ed1b8 Mon Sep 17 00:00:00 2001 From: Jeroen Willemsen Date: Sat, 6 Aug 2022 10:19:10 +0200 Subject: [PATCH 09/13] Update POM file with new version: ctfd-safe-3 --- Dockerfile.web | 2 +- src/main/resources/templates/welcome.html | 3 ++- .../ChallengesControllerCTFModeWithPresetK8sValuesTest.java | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Dockerfile.web b/Dockerfile.web index 8eeb171ef..1fdd7dbed 100644 --- a/Dockerfile.web +++ b/Dockerfile.web @@ -1,4 +1,4 @@ -FROM jeroenwillemsen/wrongsecrets:ctfd-safe-2-no-vault +FROM jeroenwillemsen/wrongsecrets:ctfd-safe-3-no-vault ARG argBasedVersion="1.5.0" ARG CANARY_URLS="http://canarytokens.com/terms/about/s7cfbdakys13246ewd8ivuvku/post.jsp,http://canarytokens.com/terms/about/y0all60b627gzp19ahqh7rl6j/post.jsp" diff --git a/src/main/resources/templates/welcome.html b/src/main/resources/templates/welcome.html index f5f0a0b9d..25e717245 100644 --- a/src/main/resources/templates/welcome.html +++ b/src/main/resources/templates/welcome.html @@ -22,7 +22,8 @@  Challenge      Focus    - + + Difficulty diff --git a/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetK8sValuesTest.java b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetK8sValuesTest.java index 495e43168..0adfe69cb 100644 --- a/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetK8sValuesTest.java +++ b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetK8sValuesTest.java @@ -79,9 +79,9 @@ void shouldShowFlagWhenRespondingWithSuccessInCTFModeChallenge7() throws Excepti void shouldEnableK8sExercises() throws Exception{ mvc.perform(get("/")) .andExpect(status().isOk()) - .andExpect(content().string(containsString("Challenge 5"))) - .andExpect(content().string(containsString("Challenge 6"))) - .andExpect(content().string(containsString("Challenge 7"))); + .andExpect(content().string(containsString(" Challenge 5"))) + .andExpect(content().string(containsString(" Challenge 6"))) + .andExpect(content().string(containsString(" Challenge 7"))); } } From 7a5e30c1579ebaba8cf426c2192c187401248af0 Mon Sep 17 00:00:00 2001 From: Jeroen Willemsen Date: Sun, 7 Aug 2022 10:40:51 +0200 Subject: [PATCH 10/13] Update POM file with new version: ctfd-safe-4 --- Dockerfile.web | 8 +- ctf-instructions.md | 37 ++++++ .../wrongsecrets/RuntimeEnvironment.java | 19 +++- .../canaries/CanariesController.java | 5 - .../challenges/ChallengesAPIController.java | 10 +- .../challenges/cloud/Challenge10.java | 2 +- .../challenges/cloud/Challenge11.java | 41 ++++--- .../challenges/cloud/Challenge9.java | 2 +- src/main/resources/application.properties | 18 +++ src/main/resources/templates/challenge.html | 2 +- src/main/resources/templates/welcome.html | 30 +++-- .../ChallengesControllerCTFModeTest.java | 19 +++- ...ollerCTFModeWithPresetCloudValuesTest.java | 105 ++++++++++++++++++ 13 files changed, 250 insertions(+), 48 deletions(-) create mode 100644 ctf-instructions.md create mode 100644 src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetCloudValuesTest.java diff --git a/Dockerfile.web b/Dockerfile.web index 1fdd7dbed..3c95c0c8e 100644 --- a/Dockerfile.web +++ b/Dockerfile.web @@ -1,4 +1,4 @@ -FROM jeroenwillemsen/wrongsecrets:ctfd-safe-3-no-vault +FROM jeroenwillemsen/wrongsecrets:ctfd-safe-4-no-vault ARG argBasedVersion="1.5.0" ARG CANARY_URLS="http://canarytokens.com/terms/about/s7cfbdakys13246ewd8ivuvku/post.jsp,http://canarytokens.com/terms/about/y0all60b627gzp19ahqh7rl6j/post.jsp" @@ -9,8 +9,7 @@ ARG CTF_KEY=TRwzkRJnHOTckssAeyJbysWgP!Qc2T ARG CHALLENGE_5_VALUE=if_you_see_this_please_use_k8s ARG CHALLENGE_6_VALUE=if_you_see_this_please_use_k8s ARG CHALLENGE_7_VALUE=if_you_see_this_please_use_K8S_and_Vault -#TODO: CONTINUE ON THE 3 CHALLENGES BELOW AND TEST THEM! (both with and without CTF!) -ARG CHALLENGE_9_VALUE=if_you_see_this_please_use +ARG CHALLENGE_9_VALUE=if_you_see_this_please_use_AWS_Setup ARG CHALLENGE_10_VALUE=if_you_see_this_please_use ARG CHALLENGE_11_VALUE=if_you_see_this_please_use ENV APP_VERSION=$argBasedVersion @@ -24,6 +23,9 @@ ENV keepasspath="/var/helpers/alibabacreds.kdbx" ENV SPECIAL_K8S_SECRET=$CHALLENGE_5_VALUE ENV SPECIAL_SPECIAL_K8S_SECRET=$CHALLENGE_6_VALUE ENV vaultpassword=$CHALLENGE_7_VALUE +ENV default_aws_value_challenge_9=$CHALLENGE_9_VALUE +ENV default_aws_value_challenge_10=$CHALLENGE_10_VALUE +ENV default_aws_value_challenge_11=$CHALLENGE_11_VALUE COPY .github/scripts/ /var/helpers COPY src/test/resources/alibabacreds.kdbx /var/helpers CMD java -Xms128m -Xmx128m -Xss512k -jar -Dserver.port=$PORT -XX:MaxRAMPercentage=75 -XX:MinRAMPercentage=25 -Dspring.profiles.active=without-vault application.jar diff --git a/ctf-instructions.md b/ctf-instructions.md new file mode 100644 index 000000000..298240ac4 --- /dev/null +++ b/ctf-instructions.md @@ -0,0 +1,37 @@ +# CTF Instructions + +So you want to play a CTF with WrongSecrets? This is the place to read up all about it. +Our CTF setup makes use of the [Juice Shop CTF CLI extension](https://github.com/juice-shop/juice-shop-ctf), which you +can read all about at [here](https://pwning.owasp-juice.shop/part1/ctf.html). + +The difference between Juiceshop and WrongSecrets, is that WrongSecrets is more of a secrets-hunter game. Thiss means +that your contestants will try to find the CTF key soon after a few challenges. That is why we should separate out the +actual container for which the CTF scores are generated, from the container where the challenges live in. + +You can see this practice already here in our repository: Our standard [Dockerfile](/Dockerfile) does not contain any +CTF entries, our Heroku [Dockerfile.web](/Dockerfile.web) does contain them. +So make sure you host your actual scoring Dockerfile.web at a place where your contestants cannot enter the container ( +image) in order to extract the CTF key. + +## Setting up CTFs + +There are 3 flavors of CTF to be setup: Docker/Heroku, K8S, Cloud based. + +### Docker or Heroku CTF + +When doing a Docker or Heroku based CTF, you can follow +the [instructions in the readme](https://github.com/commjoen/wrongsecrets#ctfd-support). +If you want to use your own CTF key, you can build a container with the following +arguments `CTF_ENABLED=true,HINTS_ENABLED=false,CTF_KEY=`. Just make sure you provide the same key +to `juice-shop-ctf` when you run it. + +Want to make it a little more exciting? Override the Dockerfile with your preferred values, so that copying from online +hosted solutions no longer works! + +### K8s based CTF - TODO + +TODO + +### Cloud based CTF - TODO + + diff --git a/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java b/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java index a47fb3c49..7f5f92f36 100644 --- a/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java +++ b/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java @@ -26,7 +26,10 @@ public class RuntimeEnvironment { private boolean ctfModeEnabled; @Value("${SPECIAL_K8S_SECRET}") - private String challenge5Value; //used to determine if they are overriden; + private String challenge5Value; //used to determine if k8s/vault challenges are overriden; + + @Value("${default_aws_value_challenge_9}") + private String defaultChallenge9Value; //used to determine if the cloud challenge values are overriden private static final Map> envToOverlappingEnvs = Map.of( HEROKU_DOCKER, List.of(DOCKER, HEROKU_DOCKER), @@ -60,6 +63,11 @@ private boolean isK8sUnlockedInCTFMode() { return ctfModeEnabled && !challenge5Value.equals(defaultValueChallenge5); } + private boolean isCloudUnlockedInCTFMode() { + String defaultValueAWSValue = "if_you_see_this_please_use_AWS_Setup"; + return ctfModeEnabled && !defaultChallenge9Value.equals(defaultValueAWSValue); + } + @Autowired public RuntimeEnvironment(@Value("${K8S_ENV}") String currentRuntimeEnvironment) { this.runtimeEnvironment = Environment.fromId(currentRuntimeEnvironment); @@ -70,9 +78,14 @@ public RuntimeEnvironment(Environment runtimeEnvironment) { } public boolean canRun(Challenge challenge) { + if (isCloudUnlockedInCTFMode()) { + return true; + } if (isK8sUnlockedInCTFMode()) { - return challenge.supportedRuntimeEnvironments().contains(runtimeEnvironment) || challenge.supportedRuntimeEnvironments().contains(K8S) || challenge.supportedRuntimeEnvironments().contains(VAULT); - } //TODO: WRITE TEST FOR THIS & UPDATE UI THEN! + return challenge.supportedRuntimeEnvironments().contains(runtimeEnvironment) || + challenge.supportedRuntimeEnvironments().contains(DOCKER) || challenge.supportedRuntimeEnvironments().contains(K8S) || + challenge.supportedRuntimeEnvironments().contains(VAULT); + } return challenge.supportedRuntimeEnvironments().contains(runtimeEnvironment) || !Collections.disjoint(envToOverlappingEnvs.get(runtimeEnvironment), challenge.supportedRuntimeEnvironments()); } diff --git a/src/main/java/org/owasp/wrongsecrets/canaries/CanariesController.java b/src/main/java/org/owasp/wrongsecrets/canaries/CanariesController.java index 3fc476c88..bb62b4b1d 100644 --- a/src/main/java/org/owasp/wrongsecrets/canaries/CanariesController.java +++ b/src/main/java/org/owasp/wrongsecrets/canaries/CanariesController.java @@ -30,11 +30,6 @@ public ResponseEntity processCanaryToken(@RequestBody CanaryToken canary } log.info("Canarytoken called, with manage_url {}", canaryToken.getManageUrl()); log.info("Total number of canary callback calls: {}", canaryCounter.getTotalCount()); - /* - todo: - - follow 3 of baeldung.com/spring-server-sent-events, but make sure you register the emitter per connection - - and in a map lookup which emiter you can use for the given connection to send the event. - */ return new ResponseEntity<>("all good", HttpStatus.ACCEPTED); } diff --git a/src/main/java/org/owasp/wrongsecrets/challenges/ChallengesAPIController.java b/src/main/java/org/owasp/wrongsecrets/challenges/ChallengesAPIController.java index 409d6e305..ec9175d83 100644 --- a/src/main/java/org/owasp/wrongsecrets/challenges/ChallengesAPIController.java +++ b/src/main/java/org/owasp/wrongsecrets/challenges/ChallengesAPIController.java @@ -8,19 +8,16 @@ import org.owasp.wrongsecrets.RuntimeEnvironment; import org.owasp.wrongsecrets.ScoreCard; import org.owasp.wrongsecrets.asciidoc.TemplateGenerator; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.util.ResourceUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import org.yaml.snakeyaml.Yaml; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; -import java.util.Locale; @Slf4j @RestController @@ -35,11 +32,14 @@ public class ChallengesAPIController { private final TemplateGenerator templateGenerator; + private final RuntimeEnvironment runtimeEnvironment; + public ChallengesAPIController(ScoreCard scoreCard, List challenges, RuntimeEnvironment runtimeEnvironment, TemplateGenerator templateGenerator) { this.scoreCard = scoreCard; this.challenges = challenges; this.descriptions = new ArrayList<>(); this.hints = new ArrayList<>(); + this.runtimeEnvironment = runtimeEnvironment; this.templateGenerator = templateGenerator; } @@ -117,8 +117,8 @@ private String extractResource(String resourceName) { } private String getDisabledEnv(ChallengeUI challenge) { - if (!challenge.getChallenge().supportedRuntimeEnvironments().contains(RuntimeEnvironment.Environment.DOCKER)) { - return "Docker"; + if (runtimeEnvironment.canRun(challenge.getChallenge())) { + return runtimeEnvironment.getRuntimeEnvironment().name(); } return null; } diff --git a/src/main/java/org/owasp/wrongsecrets/challenges/cloud/Challenge10.java b/src/main/java/org/owasp/wrongsecrets/challenges/cloud/Challenge10.java index b0965ce91..8b8188294 100644 --- a/src/main/java/org/owasp/wrongsecrets/challenges/cloud/Challenge10.java +++ b/src/main/java/org/owasp/wrongsecrets/challenges/cloud/Challenge10.java @@ -27,7 +27,7 @@ public class Challenge10 extends CloudChallenge { public Challenge10(ScoreCard scoreCard, @Value("${secretmountpath}") String filePath, - @Value("${default_aws_value}") String awsDefaultValue, + @Value("${default_aws_value_challenge_10}") String awsDefaultValue, RuntimeEnvironment runtimeEnvironment) { super(scoreCard, runtimeEnvironment); this.awsDefaultValue = awsDefaultValue; diff --git a/src/main/java/org/owasp/wrongsecrets/challenges/cloud/Challenge11.java b/src/main/java/org/owasp/wrongsecrets/challenges/cloud/Challenge11.java index bc5cefc36..40ccadb59 100644 --- a/src/main/java/org/owasp/wrongsecrets/challenges/cloud/Challenge11.java +++ b/src/main/java/org/owasp/wrongsecrets/challenges/cloud/Challenge11.java @@ -46,6 +46,10 @@ public class Challenge11 extends CloudChallenge { private final String azureVaultUri; private final String azureWrongSecret3; + private final String ctfValue; + + private final boolean ctfEnabled; + public Challenge11(ScoreCard scoreCard, @Value("${AWS_ROLE_ARN}") String awsRoleArn, @Value("${AWS_WEB_IDENTITY_TOKEN_FILE}") String tokenFileLocation, @@ -56,6 +60,8 @@ public Challenge11(ScoreCard scoreCard, @Value("${azure.keyvault.uri}") String azureVaultUri, @Value("${wrongsecret-3}") String azureWrongSecret3, // Exclusively auto-wired for Azure @Value("${GCP_PROJECT_ID}") String projectId, + @Value("${default_aws_value_challenge_11}") String ctfValue, + @Value("${ctf_enabled}") boolean ctfEnabled, RuntimeEnvironment runtimeEnvironment) { super(scoreCard, runtimeEnvironment); this.awsRoleArn = awsRoleArn; @@ -67,6 +73,8 @@ public Challenge11(ScoreCard scoreCard, this.projectId = projectId; this.azureVaultUri = azureVaultUri; this.azureWrongSecret3 = azureWrongSecret3; + this.ctfValue = ctfValue; + this.ctfEnabled = ctfEnabled; this.challengeAnswer = getChallenge11Value(runtimeEnvironment); } @@ -96,6 +104,9 @@ public String getTech() { private String getChallenge11Value(RuntimeEnvironment runtimeEnvironment) { if (runtimeEnvironment != null && runtimeEnvironment.getRuntimeEnvironment() != null) { + if (ctfEnabled && ctfValue != awsDefaultValue) { + return ctfValue; + } return switch (runtimeEnvironment.getRuntimeEnvironment()) { case AWS -> getAWSChallenge11Value(); case GCP -> getGCPChallenge11Value(); @@ -112,27 +123,27 @@ private String getAWSChallenge11Value() { try { //based on https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/sts/src/main/java/com/example/sts String webIDentityToken = Files.readString(Paths.get(tokenFileLocation)); StsClient stsClient = StsClient.builder() - .region(Region.of(awsRegion)) - .build(); + .region(Region.of(awsRegion)) + .build(); AssumeRoleWithWebIdentityRequest webIdentityRequest = AssumeRoleWithWebIdentityRequest.builder() - .roleArn(awsRoleArn) - .roleSessionName("WrongsecretsApp") - .webIdentityToken(webIDentityToken) - .build(); + .roleArn(awsRoleArn) + .roleSessionName("WrongsecretsApp") + .webIdentityToken(webIDentityToken) + .build(); AssumeRoleWithWebIdentityResponse tokenResponse = stsClient.assumeRoleWithWebIdentity(webIdentityRequest); log.info("The token value is " + tokenResponse.credentials().sessionToken()); SsmClient ssmClient = SsmClient.builder() - .region(Region.of(awsRegion)) - .credentialsProvider(StsAssumeRoleWithWebIdentityCredentialsProvider.builder() - .stsClient(stsClient) - .refreshRequest(webIdentityRequest) - .build()) - .build(); + .region(Region.of(awsRegion)) + .credentialsProvider(StsAssumeRoleWithWebIdentityCredentialsProvider.builder() + .stsClient(stsClient) + .refreshRequest(webIdentityRequest) + .build()) + .build(); GetParameterRequest parameterRequest = GetParameterRequest.builder() - .name("wrongsecretvalue") - .withDecryption(true) - .build(); + .name("wrongsecretvalue") + .withDecryption(true) + .build(); GetParameterResponse parameterResponse = ssmClient.getParameter(parameterRequest); log.info("The parameter value is " + parameterResponse.parameter().value()); ssmClient.close(); diff --git a/src/main/java/org/owasp/wrongsecrets/challenges/cloud/Challenge9.java b/src/main/java/org/owasp/wrongsecrets/challenges/cloud/Challenge9.java index 7b486a9e6..1eb4456b7 100644 --- a/src/main/java/org/owasp/wrongsecrets/challenges/cloud/Challenge9.java +++ b/src/main/java/org/owasp/wrongsecrets/challenges/cloud/Challenge9.java @@ -27,7 +27,7 @@ public class Challenge9 extends CloudChallenge { public Challenge9(ScoreCard scoreCard, @Value("${secretmountpath}") String filePath, - @Value("${default_aws_value}") String awsDefaultValue, + @Value("${default_aws_value_challenge_9}") String awsDefaultValue, RuntimeEnvironment runtimeEnvironment) { super(scoreCard, runtimeEnvironment); this.awsDefaultValue = awsDefaultValue; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6c50dd230..f4a7671a2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,6 +8,9 @@ ARG_BASED_PASSWORD=if_you_see_this_please_use_docker_instead DOCKER_ENV_PASSWORD=if_you_see_this_please_use_docker_instead vaultpassword=if_you_see_this_please_use_K8S_and_Vault default_aws_value=if_you_see_this_please_use_AWS_Setup +default_aws_value_challenge_9=if_you_see_this_please_use_AWS_Setup +default_aws_value_challenge_10=if_you_see_this_please_use_AWS_Setup +default_aws_value_challenge_11=if_you_see_this_please_use_AWS_Setup default_gcp_value=if_you_see_this_please_use_GCP_Setup default_azure_value=if_you_see_this_please_use_Azure_Setup AWS_ROLE_ARN=if_you_see_this_please_use_AWS_Setup @@ -68,3 +71,18 @@ spring.config.activate.on-profile=without-vault wrongsecretvalue=wrongsecret spring.cloud.vault.enabled=false asciidoctor.enabled=false +#--- +spring.config.activate.on-profile=without-vault-ctf-emulation +wrongsecretvalue=wrongsecret +spring.cloud.vault.enabled=false +asciidoctor.enabled=false +ctf_enabled=true +ctf_key=randomtextforkey +vaultpassword=ACTUAL_ANSWER_CHALLENGE7 +secretmountpath=nothere +SPECIAL_K8S_SECRET=ACTUAL_ANSWER_CHALLENGE5 +SPECIAL_SPECIAL_K8S_SECRET=ACTUAL_ANSWER_CHALLENGE6 +default_aws_value_challenge_9=ACTUAL_ANSWER_CHALLENGE9 +default_aws_value_challenge_10=ACTUAL_ANSWER_CHALLENGE10 +default_aws_value_challenge_11=ACTUAL_ANSWER_CHALLENGE_11 +K8S_ENV=Heroku(Docker) diff --git a/src/main/resources/templates/challenge.html b/src/main/resources/templates/challenge.html index 483fbd694..e6f0996e6 100644 --- a/src/main/resources/templates/challenge.html +++ b/src/main/resources/templates/challenge.html @@ -84,7 +84,7 @@
diff --git a/src/main/resources/templates/welcome.html b/src/main/resources/templates/welcome.html index 25e717245..408236a42 100644 --- a/src/main/resources/templates/welcome.html +++ b/src/main/resources/templates/welcome.html @@ -20,20 +20,28 @@ + - - - + + + + + @@ -44,12 +52,10 @@ + th:if="${challenge.requiredEnv} == 'AWS' or ${challenge.requiredEnv} == 'GCP' or ${challenge.requiredEnv} == 'AZURE'"> - +
#  Challenge      Focus   DifficultyDifficulty       
  + + + Docker K8s or Minikube with Vault AWS, GCP, Azure - -
@@ -118,7 +124,9 @@
  • OWASP Secretsmanagement Cheatsheet
  • -
  • Open CRE on Secrets Management
  • +
  • Open + CRE on Secrets Management
  • @@ -142,7 +150,9 @@
    - Want to see if your tool of choice detects all the secrets available in this project? Check the instructions in the README. + Want to see if your tool of choice detects all the secrets available in this project? Check + the instructions in the README.
    diff --git a/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeTest.java b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeTest.java index 0f715a176..3617941d0 100644 --- a/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeTest.java +++ b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeTest.java @@ -70,16 +70,27 @@ void shouldEnableK8sExercises() throws Exception{ @Test void shouldStillDissableTestsIfNotPreconfigured() throws Exception { - testChallenge("/challenge/5"); - testChallenge("/challenge/6"); - testChallenge("/challenge/7"); + testK8sChallenge("/challenge/5"); + testK8sChallenge("/challenge/6"); + testK8sChallenge("/challenge/7"); + testForCloudCluster("/challenge/9"); + testForCloudCluster("/challenge/10"); + testForCloudCluster("/challenge/11"); } - private void testChallenge(String url) throws Exception { + private void testK8sChallenge(String url) throws Exception { mvc.perform(get(url) .contentType(MediaType.APPLICATION_FORM_URLENCODED) .with(csrf())) .andExpect(status().isOk()) .andExpect(content().string(containsString("We are running outside a K8s cluster"))); } + + private void testForCloudCluster(String url) throws Exception { + mvc.perform(get(url) + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .with(csrf())) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("We are running outside a properly configured Cloud environment."))); + } } diff --git a/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetCloudValuesTest.java b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetCloudValuesTest.java new file mode 100644 index 000000000..3ab9d9488 --- /dev/null +++ b/src/test/java/org/owasp/wrongsecrets/ChallengesControllerCTFModeWithPresetCloudValuesTest.java @@ -0,0 +1,105 @@ +package org.owasp.wrongsecrets; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.owasp.wrongsecrets.challenges.cloud.Challenge10; +import org.owasp.wrongsecrets.challenges.cloud.Challenge11; +import org.owasp.wrongsecrets.challenges.cloud.Challenge9; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@ExtendWith(SpringExtension.class) +@SpringBootTest( + properties = {"ctf_enabled=true", "ctf_key=randomtextforkey", + "SPECIAL_K8S_SECRET=test5", "SPECIAL_SPECIAL_K8S_SECRET=test6", "vaultpassword=test7", + "secretmountpath=nothere", "default_aws_value_challenge_9=ACTUAL_ANSWER_CHALLENGE9", + "default_aws_value_challenge_10=ACTUAL_ANSWER_CHALLENGE10", "default_aws_value_challenge_11=ACTUAL_ANSWER_CHALLENGE_11"}, + classes = WrongSecretsApplication.class +) +@AutoConfigureMockMvc +class ChallengesControllerCTFModeWithPresetCloudValuesTest { + + @Autowired + private MockMvc mvc; + + + @Test + void shouldNotSpoilWhenInCTFMode() throws Exception { + mvc.perform(get("/spoil-9")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("Spoils are disabled in CTF mode"))); + + } + + @Test + void shouldShowFlagWhenRespondingWithSuccessInCTFModeChallenge9() throws Exception { + var spoil = new Challenge9(new InMemoryScoreCard(1), null, "ACTUAL_ANSWER_CHALLENGE9", new RuntimeEnvironment(RuntimeEnvironment.Environment.HEROKU_DOCKER)).spoiler().solution(); + mvc.perform(post("/challenge/9") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .param("solution", spoil) + .param("action", "submit") + .with(csrf())) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("70d75bf845890b2419bd8795c"))); + } + + @Test + void shouldShowFlagWhenRespondingWithSuccessInCTFModeChallenge10() throws Exception { + var spoil = new Challenge10(new InMemoryScoreCard(1), null, "ACTUAL_ANSWER_CHALLENGE10", new RuntimeEnvironment(RuntimeEnvironment.Environment.HEROKU_DOCKER)).spoiler().solution(); + mvc.perform(post("/challenge/10") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .param("solution", spoil) + .param("action", "submit") + .with(csrf())) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("176e937a2cafea3b0da3"))); + } + + @Test + void shouldShowFlagWhenRespondingWithSuccessInCTFModeChallenge11() throws Exception { + var spoil = new Challenge11(new InMemoryScoreCard(1), + "awsRoleArn", "tokenFileLocation", + "awsRegion", "gcpDefualtValue", "awsDefaultValue", + "azureDefaultValue", "azureVaultUri", "azureWrongSecret3", + "projectId", "ACTUAL_ANSWER_CHALLENGE_11", true, + new RuntimeEnvironment(RuntimeEnvironment.Environment.HEROKU_DOCKER)).spoiler().solution(); + + mvc.perform(post("/challenge/11") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .param("solution", spoil) + .param("action", "submit") + .with(csrf())) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("89aeb4b29d4a0bc13bd"))); + } + + @Test + void shouldEnableCloudExercises() throws Exception { + mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString(" Challenge 9"))) + .andExpect(content().string(containsString(" Challenge 10"))) + .andExpect(content().string(containsString(" Challenge 11"))); + } + + @Test + void shouldEnableK8sExercises() throws Exception{ + mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString(" Challenge 5"))) + .andExpect(content().string(containsString(" Challenge 6"))) + .andExpect(content().string(containsString(" Challenge 7"))); + } + +} From 24b6452d6d259d68cc7822f9476fcf0214398659 Mon Sep 17 00:00:00 2001 From: Jeroen Willemsen Date: Sun, 7 Aug 2022 10:43:25 +0200 Subject: [PATCH 11/13] Cleanup of code for #366 --- .../java/org/owasp/wrongsecrets/RuntimeEnvironment.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java b/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java index 7f5f92f36..be36cea37 100644 --- a/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java +++ b/src/main/java/org/owasp/wrongsecrets/RuntimeEnvironment.java @@ -82,9 +82,9 @@ public boolean canRun(Challenge challenge) { return true; } if (isK8sUnlockedInCTFMode()) { - return challenge.supportedRuntimeEnvironments().contains(runtimeEnvironment) || - challenge.supportedRuntimeEnvironments().contains(DOCKER) || challenge.supportedRuntimeEnvironments().contains(K8S) || - challenge.supportedRuntimeEnvironments().contains(VAULT); + return challenge.supportedRuntimeEnvironments().contains(runtimeEnvironment) + || challenge.supportedRuntimeEnvironments().contains(DOCKER) || challenge.supportedRuntimeEnvironments().contains(K8S) + || challenge.supportedRuntimeEnvironments().contains(VAULT); } return challenge.supportedRuntimeEnvironments().contains(runtimeEnvironment) || !Collections.disjoint(envToOverlappingEnvs.get(runtimeEnvironment), challenge.supportedRuntimeEnvironments()); From 2f1ef305e2d013cb20c116b76990b898a74d2c15 Mon Sep 17 00:00:00 2001 From: Jeroen Willemsen Date: Tue, 9 Aug 2022 13:50:03 +0200 Subject: [PATCH 12/13] Update ctf-instructions.md --- ctf-instructions.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ctf-instructions.md b/ctf-instructions.md index 298240ac4..5af0e45ef 100644 --- a/ctf-instructions.md +++ b/ctf-instructions.md @@ -28,10 +28,11 @@ to `juice-shop-ctf` when you run it. Want to make it a little more exciting? Override the Dockerfile with your preferred values, so that copying from online hosted solutions no longer works! -### K8s based CTF - TODO +### K8s based CTF -TODO +TODO as #https://github.com/commjoen/wrongsecrets/issues/372 -### Cloud based CTF - TODO +### Cloud based CTF +TODO as #https://github.com/commjoen/wrongsecrets/issues/372 From 2a088f83e8059a2be145c6baf927ffc683a2891e Mon Sep 17 00:00:00 2001 From: Jeroen Willemsen Date: Tue, 9 Aug 2022 14:45:12 +0200 Subject: [PATCH 13/13] fix difficulty star rating --- src/main/resources/templates/welcome.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/resources/templates/welcome.html b/src/main/resources/templates/welcome.html index 408236a42..b62a22d28 100644 --- a/src/main/resources/templates/welcome.html +++ b/src/main/resources/templates/welcome.html @@ -39,8 +39,10 @@ th:remove="tag"> - - + + + Docker