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();
+ }
+}