forked from OWASP/wrongsecrets
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'OWASP:master' into nexus-credentials
- Loading branch information
Showing
13 changed files
with
211 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
src/main/java/org/owasp/wrongsecrets/challenges/docker/Challenge41.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package org.owasp.wrongsecrets.challenges.docker; | ||
|
||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; | ||
import java.nio.charset.StandardCharsets; | ||
import java.security.MessageDigest; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.util.Base64; | ||
import java.util.List; | ||
import lombok.extern.slf4j.Slf4j; | ||
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.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
import org.springframework.stereotype.Component; | ||
|
||
/** This is a challenge based on finding secret using password shucking */ | ||
@Slf4j | ||
@Component | ||
@Order(41) | ||
public class Challenge41 extends Challenge { | ||
|
||
private final String password; | ||
|
||
public Challenge41(ScoreCard scoreCard, @Value("${challenge41password}") String password) { | ||
super(scoreCard); | ||
this.password = password; | ||
} | ||
|
||
@Override | ||
public boolean canRunInCTFMode() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public Spoiler spoiler() { | ||
return new Spoiler(base64Decode(password)); | ||
} | ||
|
||
/** {@inheritDoc} */ | ||
@Override | ||
public int difficulty() { | ||
return Difficulty.HARD; | ||
} | ||
|
||
/** {@inheritDoc} Cryptography based. */ | ||
@Override | ||
public String getTech() { | ||
return ChallengeTechnology.Tech.CRYPTOGRAPHY.id; | ||
} | ||
|
||
@Override | ||
public boolean isLimitedWhenOnlineHosted() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public List<RuntimeEnvironment.Environment> supportedRuntimeEnvironments() { | ||
return List.of(RuntimeEnvironment.Environment.DOCKER); | ||
} | ||
|
||
@Override | ||
public boolean answerCorrect(String answer) { | ||
try { | ||
BCryptPasswordEncoder bcrypt = new BCryptPasswordEncoder(); | ||
String hash = bcrypt.encode(hashWithMd5(base64Decode(password))); | ||
String md5Hash = hashWithMd5(answer); | ||
return bcrypt.matches(md5Hash, hash); | ||
} catch (Exception e) { | ||
log.warn("there was an exception with hashing content in challenge41", e); | ||
return false; | ||
} | ||
} | ||
|
||
@SuppressFBWarnings( | ||
value = "WEAK_MESSAGE_DIGEST_MD5", | ||
justification = "This is to allow md5 hashing") | ||
private String hashWithMd5(String plainText) throws NoSuchAlgorithmException { | ||
MessageDigest md = MessageDigest.getInstance("MD5"); | ||
|
||
byte[] result = md.digest(plainText.getBytes(StandardCharsets.UTF_8)); | ||
StringBuilder hexString = new StringBuilder(); | ||
for (byte b : result) { | ||
hexString.append(String.format("%02x", b)); | ||
} | ||
return hexString.toString(); | ||
} | ||
|
||
private String base64Decode(String base64) { | ||
byte[] decodedBytes = Base64.getDecoder().decode(base64); | ||
return new String(decodedBytes, StandardCharsets.UTF_8); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
user_1, $2b$10$AL/XPsWYU0cekug9KxIEBuSWbgaNCjaDWq/w/MBT0l3FEyz1RtaE2 | ||
user_2, $2b$10$AL/XPsWYU0cekug9KxIEBu/hlEgW48XTPh7IxKMoUD7MvR5yw5GzS | ||
user_3, $2b$10$AL/XPsWYU0cekug9KxIEBucrOlG1vqF9tT12HHMQO3LsoZfXV4Kwm | ||
user_4, $2b$10$AL/XPsWYU0cekug9KxIEBuzCs0Pf9LkaJr4q3RoQmN4pMfQ4W3f7W | ||
user_5, $2b$10$AL/XPsWYU0cekug9KxIEBub4kocue4NeBWRw13nJY73lfcpj0W9sK | ||
user_6, $2b$10$AL/XPsWYU0cekug9KxIEBueWjLD7koXriGpJubmPHZdgvXr7TXqt2 | ||
user_7, $2b$10$AL/XPsWYU0cekug9KxIEBub7GTp65ElqcvyNYn7tiTgfIJDbSIor2 | ||
user_8, $2b$10$AL/XPsWYU0cekug9KxIEBuXJmQXySRKIzazcUmQmTdsD6nqGLwjp6 | ||
user_9, $2b$10$AL/XPsWYU0cekug9KxIEBuQLvMTuJ3ZEcOQwGFhAAJxZEDurO5nkK | ||
user_10, $2b$10$AL/XPsWYU0cekug9KxIEBuG0lxHNKB1b8/irnbvU.LewlaOCpNsYK | ||
user_11, $2b$10$AL/XPsWYU0cekug9KxIEBuDQnjd2Pq8MrbcnbJWC0eJndpg25AKDS | ||
user_12, $2b$10$AL/XPsWYU0cekug9KxIEBuvZcoNJHxTiiQKxbUhWjOcm9ACoaIFNW | ||
user_13, $2b$10$AL/XPsWYU0cekug9KxIEBuG4wtyDXcqJsGC6EOUELUXV0GHULXZ32 | ||
user_14, $2b$10$AL/XPsWYU0cekug9KxIEBu75XkDPcwCMNEp1n1HqVJhtwXIdr/qsS | ||
user_15, $2b$10$AL/XPsWYU0cekug9KxIEBuE5MsvF02vTcs/F/YfgUS/8bsntiNj1S | ||
user_16, $2b$10$AL/XPsWYU0cekug9KxIEBuss9lfL0d0Fo5bwXngStAWpxp.IwSt9q | ||
user_17, $2b$10$AL/XPsWYU0cekug9KxIEBuyQ.QgBukZtpC83AALn/5DhxmqJPDQmW | ||
user_18, $2b$10$AL/XPsWYU0cekug9KxIEBuqD0hv0PWUPIbwKPI7n6s.qRGiOXgHxO | ||
user_19, $2b$10$AL/XPsWYU0cekug9KxIEBubeLb2lU4oRL.eW38bbJsjdL.ddrUJoi | ||
user_20, $2b$10$AL/XPsWYU0cekug9KxIEBueJHMcO2DtodfwSHkzDbL4vrkrerLzk. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
user_1, 9ed98e5c3e9685aa3de82c99009a2ed3 | ||
user_2, 6988ec3aba1eaddf2435141bf10487ca | ||
user_3, 056f2914fd9a607d48f5491a53b4deb5 | ||
user_4, 04dac8afe0ca501587bad66f6b5ce5ad | ||
user_5, 82080600934821faf0bc59cba79964bc | ||
user_6, 74e37ee1078418fb58433aaf0fdd5a9a | ||
user_7, 5903d9e9a8884c8c04ad16559446735a | ||
user_8, 229979fce5174c17d4645bf8752dae1e | ||
user_9, 67b2bad64c2f7ae974140d1742539665 | ||
user_10, ffc150a160d37e92012c196b6af4160d | ||
user_11, 52b14869c15726dda86b87cb93666a74 | ||
user_12, 210dc1fd8cb4e4e43cb4961b28fac275 | ||
user_13, e60408e9a55027070e3caf0550d2b4df | ||
user_14, 6d6354ece40846bf7fca65dfabd5d9d4 | ||
user_15, 231badb19b93e44f47da1bd64a8147f2 | ||
user_16, 292903fa88d000b48ebdacd12eaf124e | ||
user_17, af089cedf4fb105aca50a170c2b545de | ||
user_18, aa1cbddbb1667f7227bcfdb25772f85c | ||
user_19, ef4cdd3117793b9fd593d7488409626d | ||
user_20, c5aa3124b1adad080927ce4d144c6b33 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
=== Password Shucking | ||
|
||
A website was using https://en.wikipedia.org/wiki/MD5[MD5] for hashing passwords, and its developers recently found out that someone released a dump of their user data. | ||
|
||
In an attempt to improve security, they decided to migrate to a stronger hashing algorithm like https://en.wikipedia.org/wiki/Bcrypt[bcrypt]. | ||
|
||
The developers decided that the fastest way to migrate would be to hash the pre-existing hashes using bcrypt. Using two hashing algorithms would be more secure than using one, right? It appears so. | ||
|
||
Unfortunately, a data leak occurred again and this time the dump contained the bcrypt hashed passwords. At least, this time they are safe right? | ||
|
||
For this challenge, you are provided with two database dumps containing usernames and passwords. The dump file https://github.com/OWASP/wrongsecrets/tree/master/src/main/resources/executables/db-dumps/db-dump.txt[db-dump.txt] was generated before the migration and the other dump file https://github.com/OWASP/wrongsecrets/tree/master/src/main/resources/executables/db-dumps/db-dump-2.txt[db-dump-2.txt] was generated after the migration. Both dump files are available inside the https://github.com/OWASP/wrongsecrets/tree/master/src/main/resources/executables/db-dumps[db-dumps folder]. | ||
|
||
Now, assuming that all the users except one have changed their passwords, can you find the unchanged password? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
This challenge can be solved using the following steps: | ||
|
||
1. Create two txt files `old_hashes.txt` and `new_hashes.txt` containing only the hashes copied from the dump files. | ||
2. Using `old_hashes.txt` as password list we can use hashcat to check md5 hashes that match with the bcrypt hashes. | ||
- Install https://hashcat.net/hashcat/[Hashcat] | ||
- Type in `hashcat -m 3200 -a 0 new_hashes.txt old_hashes.txt --show`. You will find a single bcrypt hash mapped to a md5 hash. | ||
3. Using `rockyou.txt` as password list we can crack the obtained md5 hash. | ||
- Download the https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt[rockyou.txt password list] | ||
- Type in `hashcat -m 0 -a 0 82080600934821faf0bc59cba79964bc rockyou.txt --show` to find the cracked password. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
*Why pre-hashing passwords is not a good idea?* | ||
|
||
Though pre-hashing passwords is an easy way to upgrade legacy hashes, it becomes prone to https://www.scottbrady91.com/authentication/beware-of-password-shucking[Password shucking]. | ||
|
||
It is a technique in which the attackers strip off the newer secure layers of an updated hash reducing it into its weak older counterpart. In this case, we were able to reduce bcrypt hashes to insecure md5 hashes and then crack it. | ||
|
||
The safest way to avoid this is to reset the passwords of all users and hash the new passwords with the newer algorithm. But, this method is not user-friendly. | ||
|
||
The best way to upgrade is by layering the hashes initially and replacing with direct hashes of the users' passwords next time they logs in. |
31 changes: 31 additions & 0 deletions
31
src/test/java/org/owasp/wrongsecrets/challenges/docker/Challenge41Test.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package org.owasp.wrongsecrets.challenges.docker; | ||
|
||
import org.assertj.core.api.Assertions; | ||
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; | ||
|
||
@ExtendWith(MockitoExtension.class) | ||
class Challenge41Test { | ||
@Mock private ScoreCard scoreCard; | ||
|
||
@Test | ||
void spoilerShouldGiveAnswer() { | ||
var challenge = new Challenge41(scoreCard, "dGVzdA=="); | ||
Assertions.assertThat(challenge.spoiler().solution()).isEqualTo("test"); | ||
} | ||
|
||
@Test | ||
void rightAnswerShouldSolveChallenge() { | ||
var challenge = new Challenge18(scoreCard, "dGVzdA=="); | ||
Assertions.assertThat(challenge.solved("test")).isTrue(); | ||
} | ||
|
||
@Test | ||
void incorrectAnswerShouldNotSolveChallenge() { | ||
var challenge = new Challenge41(scoreCard, "dGVzdA=="); | ||
Assertions.assertThat(challenge.answerCorrect("wrong answer")).isFalse(); | ||
} | ||
} |