diff --git a/maven/settings/settings.xml b/maven/settings/settings.xml new file mode 100644 index 000000000..a8a60225f --- /dev/null +++ b/maven/settings/settings.xml @@ -0,0 +1,51 @@ + + + + nexus + * + http://localhost:8081/nexus/content/groups/public + + + + nexus + + + + nexus + + + central + http://central + + true + + + true + + + + + + central + http://central + + true + + + true + + + + + + + org.owsap.plugins + + + + nexus + admin + admin123 + + + diff --git a/pom.xml b/pom.xml index f1242c655..72d16b0fd 100644 --- a/pom.xml +++ b/pom.xml @@ -248,6 +248,12 @@ spotbugs-annotations 4.7.3 + + org.apache.commons + commons-configuration2 + 2.7 + + diff --git a/src/main/java/org/owasp/wrongsecrets/challenges/docker/Challenge42.java b/src/main/java/org/owasp/wrongsecrets/challenges/docker/Challenge42.java new file mode 100644 index 000000000..3776d66a7 --- /dev/null +++ b/src/main/java/org/owasp/wrongsecrets/challenges/docker/Challenge42.java @@ -0,0 +1,88 @@ +package org.owasp.wrongsecrets.challenges.docker; + +import java.io.StringReader; +import java.nio.charset.Charset; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.configuration2.XMLConfiguration; +import org.owasp.wrongsecrets.RuntimeEnvironment; +import org.owasp.wrongsecrets.ScoreCard; +import org.owasp.wrongsecrets.challenges.Challenge; +import org.owasp.wrongsecrets.challenges.ChallengeTechnology; +import org.owasp.wrongsecrets.challenges.Difficulty; +import org.owasp.wrongsecrets.challenges.Spoiler; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.annotation.Order; +import org.springframework.core.io.Resource; +import org.springframework.stereotype.Component; + +/** + * This is a challenge based on leaking secrets due to keeping the encryption key and secret + * together + */ +@Slf4j +@Component +@Order(42) +public class Challenge42 extends Challenge { + + private final Resource resource; + + public Challenge42( + ScoreCard scoreCard, @Value("classpath:maven/settings/settings.xml") Resource resource) { + super(scoreCard); + this.resource = resource; + } + + @Override + public boolean canRunInCTFMode() { + return true; + } + + @Override + public Spoiler spoiler() { + return new Spoiler(getSolution()); + } + + @Override + public boolean answerCorrect(String answer) { + return getSolution().equals(answer); + } + + /** {@inheritDoc} */ + @Override + public int difficulty() { + return Difficulty.EASY; + } + + /** {@inheritDoc} Cryptography based. */ + @Override + public String getTech() { + return ChallengeTechnology.Tech.CRYPTOGRAPHY.id; + } + + @Override + public boolean isLimitedWhenOnlineHosted() { + return false; + } + + @Override + public List supportedRuntimeEnvironments() { + return List.of(RuntimeEnvironment.Environment.DOCKER); + } + + private String getSolution() { + try { + String config = resource.getContentAsString(Charset.defaultCharset()); + StringReader stringReader = new StringReader(config); + + XMLConfiguration xmlConfiguration = new XMLConfiguration(); + xmlConfiguration.read(stringReader); + + // Retrieve the Nexus password + return xmlConfiguration.getString("nexus.password"); + } catch (Exception e) { + log.warn("there was an exception with decrypting content in challenge42", e); + return "error_decryption"; + } + } +} diff --git a/src/main/resources/explanations/challenge42.adoc b/src/main/resources/explanations/challenge42.adoc new file mode 100644 index 000000000..e87367d5f --- /dev/null +++ b/src/main/resources/explanations/challenge42.adoc @@ -0,0 +1,3 @@ +=== Nexus credential read + +Storing nexus deployment credentials in your github project hardcoded is generally considered a bad practice because it undermines the security provided by encryption. diff --git a/src/main/resources/explanations/challenge42_hint.adoc b/src/main/resources/explanations/challenge42_hint.adoc new file mode 100644 index 000000000..0098bdf49 --- /dev/null +++ b/src/main/resources/explanations/challenge42_hint.adoc @@ -0,0 +1,10 @@ +This challenge can be solved by decrypting the base64 encoded secret in `secrchallenge.json`. You can do this either by: + +1. Using an online aes decryption tool like https://www.devglan.com/online-tools/aes-encryption-decryption[https://www.devglan.com/online-tools/aes-encryption-decryption] +- Copy the value of `secret` from `secrchallenge.json` and paste it into the textbox of the decryptor. +- Ensure the input format is `Base64` and the cipher mode is `ECB`. +- Use the value of `key` from `secrchallenge.json` as decryption key and click on `Decrypt` to get the secret. + +2. Using the terminal +- Launch the terminal while you are in the `maven` directory. +- Copy the value of `password` from `settings.xml`. diff --git a/src/main/resources/explanations/challenge42_reason.adoc b/src/main/resources/explanations/challenge42_reason.adoc new file mode 100644 index 000000000..393863b46 --- /dev/null +++ b/src/main/resources/explanations/challenge42_reason.adoc @@ -0,0 +1,7 @@ +*Why you should not have nexus deployment credentials in your github project hardcoded* + +Storing nexus deployment credentials in your github project hardcoded is generally considered a bad practice because it undermines the security provided by encryption. + +In such scenarios, an attacker has the key the moment the file is in his possession. + +It is always recommended to store your credentials securely. diff --git a/src/test/java/org/owasp/wrongsecrets/challenges/docker/Challenge42Test.java b/src/test/java/org/owasp/wrongsecrets/challenges/docker/Challenge42Test.java new file mode 100644 index 000000000..208d4bc7b --- /dev/null +++ b/src/test/java/org/owasp/wrongsecrets/challenges/docker/Challenge42Test.java @@ -0,0 +1,41 @@ +package org.owasp.wrongsecrets.challenges.docker; + +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.nio.charset.Charset; +import org.assertj.core.api.Assertions; +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.wrongsecrets.ScoreCard; +import org.springframework.core.io.Resource; + +@ExtendWith(MockitoExtension.class) +class Challenge42Test { + @Mock private ScoreCard scoreCard; + + @Mock private Resource resource; + + @BeforeEach + void setUp() throws IOException { + when(resource.getContentAsString(Charset.defaultCharset())) + .thenReturn( + "test_usertest_password"); + } + + @Test + void spoilerShouldGiveAnswer() { + var challenge = new Challenge42(scoreCard, resource); + Assertions.assertThat(challenge.spoiler().solution()).isNotEmpty(); + Assertions.assertThat(challenge.answerCorrect(challenge.spoiler().solution())).isTrue(); + } + + @Test + void incorrectAnswerShouldNotSolveChallenge() { + var challenge = new Challenge42(scoreCard, resource); + Assertions.assertThat(challenge.answerCorrect("wrong answer")).isFalse(); + } +}