Projects STRLCPY wrongsecrets Commits e8db22d3
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    src/main/java/org/owasp/wrongsecrets/challenges/docker/Challenge26.java
     1 +package org.owasp.wrongsecrets.challenges.docker;
     2 + 
     3 + 
     4 +import lombok.extern.slf4j.Slf4j;
     5 +import org.bouncycastle.util.encoders.Base64;
     6 +import org.owasp.wrongsecrets.RuntimeEnvironment;
     7 +import org.owasp.wrongsecrets.ScoreCard;
     8 +import org.owasp.wrongsecrets.challenges.Challenge;
     9 +import org.owasp.wrongsecrets.challenges.ChallengeTechnology;
     10 +import org.owasp.wrongsecrets.challenges.Spoiler;
     11 +import org.springframework.core.annotation.Order;
     12 +import org.springframework.stereotype.Component;
     13 +import org.springframework.beans.factory.annotation.Value;
     14 + 
     15 +import javax.crypto.Cipher;
     16 +import javax.crypto.SecretKey;
     17 +import javax.crypto.spec.GCMParameterSpec;
     18 +import javax.crypto.spec.SecretKeySpec;
     19 +import java.nio.charset.StandardCharsets;
     20 +import java.security.spec.AlgorithmParameterSpec;
     21 +import java.util.List;
     22 + 
     23 +@Slf4j
     24 +@Component
     25 +@Order(26)
     26 +public class Challenge26 extends Challenge {
     27 + private final String cipherText;
     28 + 
     29 + public Challenge26(ScoreCard scoreCard, @Value("${challenge26ciphertext}") String cipherText) {
     30 + super(scoreCard);
     31 + this.cipherText = cipherText;
     32 + }
     33 + 
     34 + @Override
     35 + public boolean canRunInCTFMode() {
     36 + return true;
     37 + }
     38 + 
     39 + @Override
     40 + public Spoiler spoiler() {
     41 + return new Spoiler(quickDecrypt(cipherText));
     42 + }
     43 + 
     44 + @Override
     45 + public boolean answerCorrect(String answer) {
     46 + String correctString = quickDecrypt(cipherText);
     47 + return answer.equals(correctString);
     48 + }
     49 + 
     50 + @Override
     51 + public List<RuntimeEnvironment.Environment> supportedRuntimeEnvironments() {
     52 + return List.of(RuntimeEnvironment.Environment.DOCKER);
     53 + }
     54 + 
     55 + @Override
     56 + public int difficulty() {
     57 + return 2;
     58 + }
     59 + 
     60 + @Override
     61 + public String getTech() {
     62 + return ChallengeTechnology.Tech.WEB3.id;
     63 + }
     64 + 
     65 + @Override
     66 + public boolean isLimittedWhenOnlineHosted() {
     67 + return false;
     68 + }
     69 + 
     70 + private String quickDecrypt(String cipherText) {
     71 + try {
     72 + final Cipher decryptor = Cipher.getInstance("AES/GCM/NoPadding");
     73 + SecretKey decryptKey = new SecretKeySpec("thiszthekeytoday".getBytes(StandardCharsets.UTF_8), "AES");
     74 + AlgorithmParameterSpec gcmIv = new GCMParameterSpec(128, Base64.decode(cipherText), 0, 12);
     75 + decryptor.init(Cipher.DECRYPT_MODE, decryptKey, gcmIv);
     76 + return new String(decryptor.doFinal(Base64.decode(cipherText), 12, Base64.decode(cipherText).length - 12));
     77 + } catch (Exception e) {
     78 + log.warn("Exception with Challenge 26", e);
     79 + return "";
     80 + }
     81 + }
     82 +}
     83 + 
  • ■ ■ ■ ■ ■ ■
    src/main/java/org/owasp/wrongsecrets/challenges/docker/Challenge27.java
     1 +package org.owasp.wrongsecrets.challenges.docker;
     2 + 
     3 + 
     4 +import lombok.extern.slf4j.Slf4j;
     5 +import org.bouncycastle.util.encoders.Base64;
     6 +import org.owasp.wrongsecrets.RuntimeEnvironment;
     7 +import org.owasp.wrongsecrets.ScoreCard;
     8 +import org.owasp.wrongsecrets.challenges.Challenge;
     9 +import org.owasp.wrongsecrets.challenges.ChallengeTechnology;
     10 +import org.owasp.wrongsecrets.challenges.Spoiler;
     11 +import org.springframework.core.annotation.Order;
     12 +import org.springframework.stereotype.Component;
     13 +import org.springframework.beans.factory.annotation.Value;
     14 + 
     15 +import javax.crypto.Cipher;
     16 +import javax.crypto.SecretKey;
     17 +import javax.crypto.spec.GCMParameterSpec;
     18 +import javax.crypto.spec.SecretKeySpec;
     19 +import java.nio.charset.StandardCharsets;
     20 +import java.security.spec.AlgorithmParameterSpec;
     21 +import java.util.List;
     22 + 
     23 +@Slf4j
     24 +@Component
     25 +@Order(26)
     26 +public class Challenge27 extends Challenge {
     27 + private final String cipherText;
     28 + 
     29 + public Challenge27(ScoreCard scoreCard, @Value("${challenge27ciphertext}") String cipherText) {
     30 + super(scoreCard);
     31 + this.cipherText = cipherText;
     32 + }
     33 + 
     34 + @Override
     35 + public boolean canRunInCTFMode() {
     36 + return true;
     37 + }
     38 + 
     39 + @Override
     40 + public Spoiler spoiler() {
     41 + return new Spoiler(quickDecrypt(cipherText));
     42 + }
     43 + 
     44 + @Override
     45 + public boolean answerCorrect(String answer) {
     46 + String correctString = quickDecrypt(cipherText);
     47 + return answer.equals(correctString);
     48 + }
     49 + 
     50 + @Override
     51 + public List<RuntimeEnvironment.Environment> supportedRuntimeEnvironments() {
     52 + return List.of(RuntimeEnvironment.Environment.DOCKER);
     53 + }
     54 + 
     55 + @Override
     56 + public int difficulty() {
     57 + return 2;
     58 + }
     59 + 
     60 + @Override
     61 + public String getTech() {
     62 + return ChallengeTechnology.Tech.WEB3.id;
     63 + }
     64 + 
     65 + @Override
     66 + public boolean isLimittedWhenOnlineHosted() {
     67 + return false;
     68 + }
     69 + 
     70 + private String quickDecrypt(String cipherText) {
     71 + try {
     72 + final Cipher decryptor = Cipher.getInstance("AES/GCM/NoPadding");
     73 + SecretKey decryptKey = new SecretKeySpec("thiszthekeytoday".getBytes(StandardCharsets.UTF_8), "AES");
     74 + AlgorithmParameterSpec gcmIv = new GCMParameterSpec(128, Base64.decode(cipherText), 0, 12);
     75 + decryptor.init(Cipher.DECRYPT_MODE, decryptKey, gcmIv);
     76 + return new String(decryptor.doFinal(Base64.decode(cipherText), 12, Base64.decode(cipherText).length - 12));
     77 + } catch (Exception e) {
     78 + log.warn("Exception with Challenge 27", e);
     79 + return "";
     80 + }
     81 + }
     82 +}
     83 + 
  • ■ ■ ■ ■ ■ ■
    src/main/resources/application.properties
    skipped 44 lines
    45 45  canarytokenURLs=http://canarytokens.com/terms/about/s7cfbdakys13246ewd8ivuvku/post.jsp,http://canarytokens.com/terms/about/y0all60b627gzp19ahqh7rl6j/post.jsp
    46 46  challenge15ciphertext=qcyRgfXSh0HUKsW/Xb5LnuWt9DgU8tQJfluR66UDDlmMgVWCGEwk1qxKCi4ZvzDwM38xP3nRFqO4SZEgqp8Ul8Ej/lNDbQCgBuszSILVSV6D9eojOMl6zTcNgzUmjW2K3dJKN9LqXOLYezEpEN2gUaYqPu2nVqmUptKTmXGwAnmQH1TIl2MUueRuXpRKe72IMzKenxZHKRsNFp+ebQebS3qzP+Q=
    47 47  challenge25ciphertext=dQMhBe8oLxIdGLcxPanDLS++srED/x05P+Ph9PFZKlL2K42vXi7Vtbh3/N90sGT087W7ARURZg==
     48 +challenge26ciphertext=gbU5thfgy8nwzF/qc1Pq59PrJzLB+bfAdTOrx969JZx1CKeG4Sq7v1uUpzyCH/Fo8W8ghdBJJrQORw==
     49 +challenge27ciphertext=gYPQPfb0TUgWK630tHCWGwwME6IWtPWA51eU0Qpb9H7/lMlZPdLGZWmYE83YmEDmaEvFr2hX
    48 50  management.endpoint.health.probes.enabled=true
    49 51  management.health.livenessState.enabled=true
    50 52  management.health.readinessState.enabled=true
    skipped 49 lines
  • ■ ■ ■ ■ ■ ■
    src/main/resources/explanations/challenge25_hint.adoc
    1 1  You can solve this challenge by the following steps:
    2 2   
    3  -Option 1:
    4  -1. Look under the contract creation transaction on https://goerli.etherscan.io/tx/0x497b71a1fd4c57509bfecc2114ec649387fe669c23a3a7e97961f389444d9561[Etherscan]
    5  -2. Go to state and look at storage.
     3 +1. Look at the storage in Etherscan:
     4 +- Look under the contract creation transaction on https://goerli.etherscan.io/tx/0x497b71a1fd4c57509bfecc2114ec649387fe669c23a3a7e97961f389444d9561[Etherscan]
     5 +- Go to state and look at storage.
    6 6   
    7  -Option 2:
    8  -1. Look under the contract creation transaction on https://goerli.etherscan.io/tx/0x497b71a1fd4c57509bfecc2114ec649387fe669c23a3a7e97961f389444d9561[Etherscan]
    9  -2. Have a look at the input data.
     7 +2. Look at the input data in Etherscan:
     8 +- Look under the contract creation transaction on https://goerli.etherscan.io/tx/0x497b71a1fd4c57509bfecc2114ec649387fe669c23a3a7e97961f389444d9561[Etherscan]
     9 +- Have a look at the input data.
     10 + 
     11 +3. Use Infura with web3js at Infura:
     12 +- Create an Infura key at https://infura.io/[Infura].
     13 +- Write a simple script with web3js to call the view function on the public string "secret"
    10 14   
    11  -Option 3:
    12  -1. Create an Infura key at https://infura.io/[Infura].
    13  -2. Write a simple script with web3js to call the view function on the public string "secret"
     15 +4. Do a storage request at Infura:
     16 +- Create an Infura key at https://infura.io/[Infura].
     17 +- Read the storage at position 0 for the contract like:
    14 18   
    15  -Option 2:
    16  -1. Create an Infura key at https://infura.io/[Infura].
    17  -2. Read the storage at position 0 for the contract like:
    18  -curl https://goerli.infura.io/v3/${<your-infura-key>} \
     19 + curl https://goerli.infura.io/v3/${<your-infura-key>} \
    19 20   -X POST \
    20 21   -H "Content-Type: application/json" \
    21 22   -d '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": ["0x8b72f7cbAD50620c46219ad676Ad9d3a5A273587", "0x0", "latest"], "id": 1}'
    skipped 1 lines
  • ■ ■ ■ ■ ■ ■
    src/main/resources/explanations/challenge26.adoc
     1 +=== Secrets in smart contracts part 2
     2 + 
     3 +Our smart contract developer realized he wrote a secret to the chain and went back and wrote over it.
     4 + 
     5 +In this challenge, you need to read the variable named secret from the contract `0xCe793D588cd1Ee091290b4A1aE1D586B2a748eB4` on the Goerli EVM Testnet as it was before it got changed.
     6 + 
  • ■ ■ ■ ■ ■ ■
    src/main/resources/explanations/challenge26_hint.adoc
     1 +You can find the previous state one of two ways.
     2 + 
     3 +1. Find the previous block via a request to https://infura.io/[Infura]:
     4 +- Find the block number for any block after the contract was created and before it was updated.
     5 +- Search for the storage state of the contract for that block. The below command is an example vs the infura API:
     6 + 
     7 + curl https://goerli.infura.io/v3/${your-infura-key} \
     8 + -X POST \
     9 + -H "Content-Type: application/json" \
     10 + -d '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": ["${contract address}", "0x0", "${blocknumber}"], "id": 1}'
     11 + 
     12 +2. Look at the contract creation on https://etherscan.io/[Etherscan]:
     13 +- Look under the contract creation transaction on etherscan
     14 +- Go to state and look at storage
     15 + 
  • ■ ■ ■ ■ ■ ■
    src/main/resources/explanations/challenge26_reason.adoc
     1 +*Why overwriting secrets on the blockchain does not get rid of them*
     2 + 
     3 +The state of the chain can be verified for any point in time by executing the state updates up until a certain block.
     4 + 
     5 +Updating the state of the chain does not remove previous changes to state.
     6 + 
  • ■ ■ ■ ■ ■ ■
    src/main/resources/explanations/challenge27.adoc
     1 +=== Secrets in smart contracts part 3
     2 + 
     3 +Our smart contract developer got somewhat smarter and only stored a hashed secret in his contract. He then checks a input data vs that hash to validate whether or not a transaction returns true or false. He is sure that since the secret is never stored in the internal state of the contract, that it can't be found.
     4 + 
     5 +In this challenge, you need to find the correct secret that has the guess method from the contract `0x8318d477f4BCae5a80BEA22E3c040cf8BaaFFe8B` on the Goerli EVM Testnet return true.
     6 + 
  • ■ ■ ■ ■ ■ ■
    src/main/resources/explanations/challenge27_hint.adoc
     1 +You can find the correct input to the guess method by:
     2 + 
     3 +1. Comparing hashes:
     4 +- Look up the contract on the https://etherscan.io/[Etherscan] explorer.
     5 +- Pull the hash from the contract storage.
     6 +- Go through the transactions and then opening the inputs tab and decoding them as UTF-8.
     7 +- Compare the hashes of the inputs from the transactions with the stored hash value.
     8 + 
  • ■ ■ ■ ■ ■
    src/main/resources/explanations/challenge27_reason.adoc
     1 +*Why sending secrets as inputs to smart contracts is a bad idea even if they aren't stored*
     2 + 
     3 +Inputs to all transactions to contracts, like the state of internal storage of contracts on the chain are stored forever and are easy to query.
     4 +Inputs to transactions are even visible before those transactions are accepted. This can lead to front-running by a 3rd party who has access to the pool of transactions and can send a transaction (with higher gas) that benefits from the known transaction running after it.
     5 + 
  • ■ ■ ■ ■ ■ ■
    src/test/java/org/owasp/wrongsecrets/challenges/docker/Challenge26Test.java
     1 +package org.owasp.wrongsecrets.challenges.docker;
     2 + 
     3 +import org.assertj.core.api.Assertions;
     4 +import org.junit.jupiter.api.Test;
     5 +import org.junit.jupiter.api.extension.ExtendWith;
     6 +import org.mockito.Mock;
     7 +import org.mockito.Mockito;
     8 +import org.mockito.junit.jupiter.MockitoExtension;
     9 +import org.owasp.wrongsecrets.ScoreCard;
     10 + 
     11 +@ExtendWith(MockitoExtension.class)
     12 +class Challenge26Test {
     13 + 
     14 + @Mock
     15 + private ScoreCard scoreCard;
     16 + 
     17 + @Test
     18 + void rightAnswerShouldSolveChallenge() {
     19 + var challenge = new Challenge26(scoreCard, "gbU5thfgy8nwzF/qc1Pq59PrJzLB+bfAdTOrx969JZx1CKeG4Sq7v1uUpzyCH/Fo8W8ghdBJJrQORw==");
     20 + Assertions.assertThat(challenge.solved(challenge.spoiler().solution())).isTrue();
     21 + Mockito.verify(scoreCard).completeChallenge(challenge);
     22 + }
     23 + 
     24 + 
     25 + 
     26 +}
     27 + 
  • ■ ■ ■ ■ ■ ■
    src/test/java/org/owasp/wrongsecrets/challenges/docker/Challenge27Test.java
     1 +package org.owasp.wrongsecrets.challenges.docker;
     2 + 
     3 +import org.assertj.core.api.Assertions;
     4 +import org.junit.jupiter.api.Test;
     5 +import org.junit.jupiter.api.extension.ExtendWith;
     6 +import org.mockito.Mock;
     7 +import org.mockito.Mockito;
     8 +import org.mockito.junit.jupiter.MockitoExtension;
     9 +import org.owasp.wrongsecrets.ScoreCard;
     10 + 
     11 +@ExtendWith(MockitoExtension.class)
     12 +class Challenge27Test {
     13 + 
     14 + @Mock
     15 + private ScoreCard scoreCard;
     16 + 
     17 + @Test
     18 + void rightAnswerShouldSolveChallenge() {
     19 + var challenge = new Challenge27(scoreCard, "gYPQPfb0TUgWK630tHCWGwwME6IWtPWA51eU0Qpb9H7/lMlZPdLGZWmYE83YmEDmaEvFr2hX");
     20 + Assertions.assertThat(challenge.solved(challenge.spoiler().solution())).isTrue();
     21 + Mockito.verify(scoreCard).completeChallenge(challenge);
     22 + }
     23 + 
     24 + 
     25 + 
     26 +}
     27 + 
Please wait...
Page is in error, reload to recover