# 0xL4ugh CTF 2024 - My Vault
**Title:** My Vault
**Description:** I love saving my chats with my friends on my laptop but I should protect them, they have info can make you a billionaire 😎, so to protect them well I decided to protect each chat with a different password, so I will protect each one with the year I knew him at and his country (example is 2013brazil) now I'm sure I'm the only one who know these info
**Files:**
[encrypt.py, encrypted_friend1.txt, encrypted_friend2.txt and encrypted_friend3.txt](https://master-platform-bucket.s3.amazonaws.com/challenges/9954a889-8e28-4736-8f75-446a772bc6fa/public.zip)
## Solution:
I first started by checking out how the messages were encrypted, the encryption mechanism used Python’s `cryptography` library and Fernet symmetric encryption. Here’s a breakdown of the script:
- **Key Generation:**
The `generate_key` function derived a 32-byte key from the provided password using `hashlib.sha256`. This key was then encoded in a URL-safe base64 format, required by Fernet.
- **Encryption Process:**
- The file content was read in binary.
- It was encrypted using the derived Fernet key.
- The encrypted data was saved to a new file with the prefix `encrypted_`.
Since the key derivation process uses only the `password` string, decrypting a file requires knowing the exact password format (`YEARCOUNTRY`).
The goal was to brute force the password for each encrypted file. The `YEAR` part could range from 1960 to 2030 (reasonable assumption based on the timeframe of meeting friends), and `COUNTRY` could be any lowercased country name from a predefined list.
I searched online and found a [list-of-countries.txt](https://gist.githubusercontent.com/dariusz-wozniak/656f2f9070b4205c5009716f05c94067/raw/b291d58154c85dad840859fef4e63efb163005b0/list-of-countries.txt) file, now we need a script to try all possible passwords and decrypt the files. Here's what it will have to do:
1. **Generate Passwords:** Combine years (1960-2030) with country names (from `countries.txt`) to create passwords like `2013brazil`.
3. **Attempt Decryption:** For each file, try every password by:
- Generating a key from the password.
- Trying to decrypt the file with the key.
4. **Check Success:** If decryption works, print the file name, password, and decrypted content.
`solve.py`:
```python
import base64
import hashlib
from cryptography.fernet import Fernet
from itertools import product
def try_decrypt(file_name, password):
try:
key = base64.urlsafe_b64encode(hashlib.sha256(password.encode()).digest())
cipher = Fernet(key)
with open(file_name, "rb") as f:
return cipher.decrypt(f.read()).decode()
except:
return None
def bruteforce_decrypt():
countries = [line.strip().lower() for line in open("list-of-countries.txt")]
years = range(1960, 2030)
files = ["encrypted_friend1.txt", "encrypted_friend2.txt", "encrypted_friend3.txt"]
for file_name in files:
print(f"\nTrying {file_name}...")
for year, country in product(years, countries):
password = f"{year}{country}"
result = try_decrypt(file_name, password)
if result:
print(f"Success! Password: {password}\nDecrypted Content:\n{result}")
break
if __name__ == "__main__":
bruteforce_decrypt()
```
Running the script we got the following output:
```
$ python3 solve.py
Trying encrypted_friend1.txt...
Success! Password: 2005russia
Decrypted Content:
Ossama: Are you ready for the next step in the plan?
Mohammed: Yes, everything is set. But we need to make sure no one knows about these details.
Ossama: Of course, we can't afford for anyone to uncover our identities.
Mohammed: We're at a critical stage, but if we succeed, the reward will be massive.
Ossama: That's what we're hoping for. But we must be cautious at every step, and here is your first part of our plan 0xL4ugh{sad!_
Trying encrypted_friend2.txt...
Success! Password: 2016qatar
Decrypted Content:
Ossama: Do you have any updates on the project?
Khalid: Yes, but I want to remind you to be careful. There are some eyes watching us.
Ossama: Don't worry, the whole team is aware of the situation.
Khalid: But there's something unexpected—there might be leaks from inside the organization.
Ossama: Then we need to change our plans. We can't take any risks, here is the your part _no_easy_challs
Khalid: I'll secure all the channels. Don't worry.
Trying encrypted_friend3.txt...
Success! Password: 1980turkey
Decrypted Content:
Ossama: Do you remember the secret meeting we had last week?
Ali: Yes, but I need to remind you that any leaks could have severe consequences.
Ossama: We know, that's why I don't allow anyone access to sensitive information, here is your part anymore}
Ali: I hope we have enough time to complete everything before they find out what we're doing.
Ossama: We'll finish everything on time, we just need to work together and stay cautious.
```
Taking out the part that's useful to us:
- `0xL4ugh{sad!_`
- `_no_easy_challs`
- `anymore}`
Combining them this was the flag: `0xL4ugh{sad!_no_easy_challs_anymore}`