OWASP WrongSecrets writeup

Vineeth Jagadeesh
7 min readSep 8, 2023

--

Hello reader! In this article, I have written down my learnings and a walkthrough of the OWASP WrongSecrets challenges. The challenges are presented in an organized manner to the user and each challenge teaches the user on how to NOT store their secrets! I had a lot of fun while playing through the challenges and helped the project owners fix a few bugs in it too! :)

On to the walkthrough now -

Challenge 0

Simply enter the answer seen in the challenge into the given text field to complete the challenge!

Challenge 1

Since the source code was readily available from the git repo, I cloned the repo and looked through the java files using grep recursively. The answer was in the Constants.java file.

Challenge 2

Simply looking into the application.properties file in the /src/main/resources directory gave me the right answer

Challenge 3

Since dockle was recommend on the challenge spec, I installed dockle on my kali linux machine and ran the dockle <docker_image>:<tagname> command here and looked for the docker environment password to solve the challenge.
Another way was to get into the container itself and run the ‘env’ command which gave me the password. (docker exec -it <cranky_cannon> /bin/bash → to get into the container)

Challenge 4

For this challenge, I ran the docker inspect command on the container, and looked through passwords that had something to do with arguments. The ARG_BASED_PASSWORD worked!

Challenge 5 — Needs kubernetes (k8s) to be setup first

Getting the k8s cluster to work was my first hurdle here since I probably messed up during the installation the first time. An hour of googling and asking chatgpt later, I got to the challenge. k8s was new to me so I first read through the available commands in the manual and understood what some of the basic ones do.
To find the secret, I used the kubectl get command to first fetch the clusters and then used the describe option to look at the secret-challenge cluster. There was a k8s secret in there but that was not the final answer. I took a hint and checked the secrets-config.yml file in the github repo to find the secret!

Challenge 6 — k8s again

On the similar lines as challenge5, I found that the answer was the key ‘funnier’s value. I looked for the value in the in the secret-secret.yml file and submitted the value against the funnier key as my answer only to fail. I did understand that the value was base64 encoded, and so I used an online base64 decoder to get the answer!

Challenge 8

Following the instructions given in the challenge specification, I read through the logs generated as I started up the application using docker. The answer password was written against the `Initializing challenge 8 with random value` log. Entering the value in the text field completed the challenge!

Challenge 12

I first ran the docker history command to check for any COPY commands that were run on the container. Using the — no-trunc option and grepping for COPY narrowed down my search. The /helpers directory stood out to me since the .bash_history file was located in there too. Next, I exec’d into the docker container and navigated to the /var/tmp/helpers directory and found a number text files, all with keys in them. Luckily the yourkey.txt file had my answer in it. Note: The answer to this challenge varies each time the container is spun up.

Challenge 14

I first had to install keepass on my machine in order to work with the keepass file that I had stumbled upon while working on a different challenge. When I opened it, I was welcomed with a password prompt for the vault. In order to find the password to the vault, I looked at the source code for the challenge which was readily available in the github repo. To validate the answer, there was a function that was referring to a default keepass password variable. I then checked the application.properties file of the project since it is a configuration file that can be accessed by all files in the project. In there I found the vault’s password and from there finding credentials to the alibaba cloud was pretty straightforward!

Challenge 16

When I know that the client attempts to connect to a server and the credentials are being sent to it as well, the ‘network’ tab is exactly what I am thinking about in the developer tools. While being on the challenge page, I opened up the network tab and refreshed the page and observed the requests that went through and the ‘token’ file quite obviously stood out to me. I opened the ‘Request’ section of the request and the answer was against the ‘client_secret’ key.

Challenge 17

Reverse engineered the challenge since the password in the .bash_history file did not work out. The thirdkey.txt in the /var/tmp/helpers directory was the answer. This was fixed by the owners based on my feedback documented here (https://github.com/OWASP/wrongsecrets/pull/951)

Challenge 18

Simplest challenge among the docker challenges! Using crackstation to crack both hashes gave me the answer.

Challenge 19

I analyzed the file given in the challenge spec using ghidra. I looked at the functions to learn what the entry point for the program was and how checks are being made. The _secret function had the answer in it!

Challenge 20

Similar to challenge 19, the secret function in the function section seen on ghidra had the answer.

Challenge 21

For this challenge, I decided to play around with radare2 (r2), a reverse engineering tool that comes pre-built into Kali. I followed the hints given to learn how r2 worked to find the answer to this challenge. r2 is a simple yet effective tool!

Challenge 23

Simple challenge. Inspecting the html code on the challenge page gave me the answer.

Challenge 24

The answer to this challenge is the ‘key’ used in the spec from NIST which is linked to the challenge.

Challenge 25

I had little knowledge of web3 and contracts when I did the challenge. I simply googled Goerli EVM testnet and navigated to the block explorer which leads to https://goerli.etherscan.io/. I keyed in the given contract’s hash to look at the details. I opened up the only transaction hash and at the bottom, I opened the ‘More Details’ link to see a bunch of gibberish, maybe my answer is hidden in here? A convenient option to ‘View Data As’ was given and when I used the UTF-8 option, I could see a flag variable like flag{…} but it was not obvious that that was the secret variable. I pasted the entire variable in the challenge text field and that was the end of the challenge!

Challenge 26

This was a simpler challenge once I got a hang of how to look at contracts and transaction on etherscan. I opened up the contract to find two transactions this time. Since the challenge was to find the secret which was modified at some point, it made sense to look at the older of the two transactions. Surely enough, the flag variable was in the older transaction! Just for completeness, I looked into the other transaction in the contract and it did say ‘not the secret’ :)

Challenge 27

I did the same thing as in the previous two challenges. Opening the transaction hashes and viewing details using the UTF-8 encoder gave me the flag.

Challenge 28

I navigated to the issues tab in the github repository, filtered the closed issues and also added in the AWS keyword to help shorten the search. One issue with the title ‘Rotate our AWS credentials’ stood out to me and the key in the discussions was the answer.

Challenge 29

I looked through the github issues page and filtered for closed issues. One particular issue that was exactly about challenge 29 stood out and the password was clearly written down in the screenshot! But when I attempted the challenge, there was a decryption error due in the challenge due to which the seen password was not working as the correct answer. I reached out to the project owners who deployed a fix for it (documented https://github.com/OWASP/wrongsecrets/discussions/946) and I helped testing it out. win-win!

Challenge 30

If the secret was stored on the client side, the first idea that struck me was to check the ‘storage’ tab in the web developer tools in the browser. Rightly enough, the secret was in the local storage section!

Challenge 31

I kind of over thought the challenge in the beginning and started looking at the source code for the website on the wayback machine since the secret sauce would have been removed soon after it was found uploaded to the website but when I browsed through each of the tabs on the website’s latest version itself, I found the password on the ‘passwords’ tab! Not the best way to store a password at all this!

Challenge 32

When I played the challenge for the first time, I saw that the creator of the challenge had brought it down due to the cloud billing costs they incurred. I reached out to the project owners and they quickly modified the challenge based on my feedback.
The first level on the platform is enough for this challenge, which was quite simple. Simply asking ‘what’s the password’ gave me the answer.

Challenge 33

I managed to solve the challenge purely based on the git repo. The spec says the value in the stringdata and data keys could be interchanged and so I looked for the stringdata key in the yml file, which was the correct answer!

Challenge 34

I looked through the source code available for this challenge and at the bottom, I read through the working of the generateKey() method. It took the static salt of ‘secret_salt’, which should be avoided for practical purposes, the password was given in the encryptedKey variable, the algorithm used was SHA256 and the number of iterations done was 100000. Using the dcode[.]fr website, I keyed in the information found in the source code and generated the output using the Base64 format since the last line in the generateKey() method encodes the hash to Base64. Upon submitting the obtained hash value, the challenge was solved!

Challenge 35

I might not have discovered the answer to this in the intended way! I ran a grep for the word advisory and then I learned about the ‘Security’ section in a github repository! Until then I was looking for the answer manually in the code section.

--

--