Forevncrypt Writeup
Extract .img file to get files, find the "compressor" binary and the bash history, use pyinstxtractor and pycdas to get partial source code, and "decompress" (decrypt) the target file to retrieve the flag.
Challenge Description
After reading this article, I’m now hesitant to use xz-utils for compression: https://www.openwall.com/lists/oss-security/2024/03/29/4 As a result, I’ve been searching for alternative compression tools. I found one online, but unfortunately this tools are trash because it has limited features. Specifically, I’m unable to decompress files that were compressed with a password. Could you please help me recover them?
Solution
Step 1: Extracting the Disk Image
First, we extract the .img
file with PowerISO to explore its contents.
Once inside, we find a bash history file and a suspicious file called superimportantfile.xyz
.
Step 2: Investigating the bash_history
In the extracted files, we find the bash_history
file, which provides us some useful information on how the encryption was performed:
1
2
3
4
5
6
7
8
9
10
11
12
13
ls -lah
cd Desktop
../Downloads/forevncrypt note.txt
rm note.txt
cd Document
../Downloads/forevncrypt mydesign.odg
rm mydesign.odg
cd Music
../Downloads/forevncrypt myfavsong.mp3
rm myfavsong.mp3
cd Videos
../Downloads/forevncrypt superimportantfile.xyz -p thiswillbenotinrockyoubro
cd
This reveals that the file superimportantfile.xyz
was encrypted using a tool called forevncrypt
with the password thiswillbenotinrockyoubro
.
Step 3: Decompiling the Forevncrypt Python Executable
The encryption tool forevncrypt
is not a common utility, so we extract it to inspect how it works. Using PyInstxtractor, we decompile the Python bytecode (.pyc
files) and analyze the partial source code using PyCDAS:
1
./pycdas app.pyc
The decompiled source code reveals an encryption process based on XOR and LZMA compression. Key sections of the code include:
1
2
3
4
5
6
7
8
9
def xor(self, data, key):
return bytes(a ^ b for a, b in zip(data, (key * (len(data) // len(key) + 1))[:len(data)]))
def encrypt_compress(self):
compressed = self.compress()
keygen = os.urandom(2)
compressed = self.xor(compressed, keygen)
result = self.xor(compressed, self.password.encode('utf-8'))
return result
The encryption process involves two rounds of XOR: the first using a random key generated by os.urandom(2)
, and the second using the password from bash_history
.
Step 4: Writing a Decryption Script
Using the insights gained from decompiling the source, we write a Python script to reverse the encryption. Here’s the final decryption script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from Crypto.Cipher import AES
import os
def xor(data, key):
"""XOR operation between data and key."""
return bytes(a ^ b for a, b in zip(data, (key * (len(data) // len(key) + 1))[:len(data)]))
def decrypt_file(encrypted_file, password):
# Read the encrypted file
with open(encrypted_file, 'rb') as f:
file_content = f.read()
# Skip the first 37 bytes (header)
data_after_header = file_content[37:]
# Known random value generated by os.urandom(2)
urandom_xor_value = bytes.fromhex('80FE') # Based on analysis
# XOR with the password
xor_with_password = xor(data_after_header, password.encode('utf-8'))
# XOR the result with the known urandom XOR value
decrypted_data = xor(xor_with_password, urandom_xor_value)
return decrypted_data
if __name__ == '__main__':
password = 'thiswillbenotinrockyoubro'
decrypted_content = decrypt_file('superimportantfile.xyz', password)
# Save the decrypted content
with open('decrypted_superimportantfile.mp4', 'wb') as f:
f.write(decrypted_content)
print("Decryption successful! Decrypted file saved as decrypted_superimportantfile.mp4")
Step 5: Running the Decryption Script
We execute the script to decrypt the file and find out that it’s an MP4 video file.
Step 6: Recovering the Flag
Upon playing the decrypted video file, we find that the flag is embedded within the video.
Conclusion
To summarize the steps we took:
- We extracted the
.img
file to explore its contents and found abash_history
file and a suspicious file calledsuperimportantfile.xyz
. - We investigated the
bash_history
file, which revealed the password used for encryption. - We decompiled the
forevncrypt
Python executable using PyInstxtractor and PyCDAS to understand the encryption mechanism. - We wrote a decryption script based on the insights gained from the decompiled source code.
- We executed the decryption script to decrypt the file, which turned out to be an MP4 video.
- Upon playing the decrypted video file, we found the flag embedded within the video.
By carefully following these steps, we were able to decrypt the contents and retrieve the flag.
Flag
TCP1P{3_challenge_in_one_category_ummm_hehe}