Twisting seA – CTF challenge GP August ’21

The first challenge in the "Crypto"-category of the GuidePoint CTF August 2021, is called "Twisting seA".

The Twisting seA challenge.

We are asked to decipher the data provided:

617a316a5a6d526a4d44466c4f54526d5a4463794f4445354d5455354f444d77593255344e54646d597a45354d437870505446684f57526c5a6a6b344e57457a4d7a49334e6a59784d6d49314d6a4532596a5a6a5a6a4e6b4d5755344c4449774f5446685a444d325a444d324d574d344f475131597a4d794d444a6c4d7a5a6b4f546331595441314e4455314e5464694e4455775a44566d5a47466d5954466b4e6a49774e7a6c6d4d5749324e6a677a59544a6b4e574e6c595459335a5759774f47557a4d6d4533595445314f4755315932526b4d7a67304f44557a5a413d3d

Okay, the data seems alphanumeric - could it be HEX? We also is asked to "decipher" and being in the crypto-category I would suspect to be required to use some kind of cryptographic algoritm for getting the flag. Even the name of the challenge is suggesting this to us - twisting "seA" in reverse is "Aes". Arh - that is interesting.
But for us to make any sense of the data is regards to AES - we would need a key, an initialization vector and the cipher to decrypt.

I started to see if any sense could be maked out of the data by de-encoding the HEX with binascii.unhexlify(), and sure thing - we now have a beautiful base64-encoded string, even padded and every thing.

az1jZmRjMDFlOTRmZDcyODE5MTU5ODMwY2U4NTdmYzE5MCxpPTFhOWRlZjk4NWEzMzI3NjYxMmI1MjE2YjZjZjNkMWU4LDIwOTFhZDM2ZDM2MWM4OGQ1YzMyMDJlMzZkOTc1YTA1NDU1NTdiNDUwZDVmZGFmYTFkNjIwNzlmMWI2NjgzYTJkNWNlYTY3ZWYwOGUzMmE3YTE1OGU1Y2RkMzg0ODUzZA==

Using base64.b64decode() to decode the string and we are left with a comma-separated string with what seems to be the three components for the AES-deciphering.

k=cfdc01e94fd72819159830ce857fc190,i=1a9def985a33276612b5216b6cf3d1e8,2091ad36d361c88d5c3202e36d975a0545557b450d5fdafa1d62079f1b6683a2d5cea67ef08e32a7a158e5cdd384853d

Providing the decoding in python makes our string in binary - just to sanitise the input for the next step, make sure the string is formatted correctly by applying .decode(). Splitting the string in the three components and cleaning up the "k=" and "i=" to have the raw values stored in variables, ready for the AES-deciphering.

In python I use the Crypto-library to firstly create an AES-cipher object - here it's important to de-HEX the key and carve the IV for excess padding. The provided IV has a length longer than the required 16 bytes. Using this cipher-object, we can use the .decrypt()-function to decrypt the ciphertext - make sure to provide the correct encoding, as the text seems to be HEX-formatted. Further we can remove excess padding from the decrypted string by using Crypto.Util.Padding.unpad().

And would you look at that - printing the result (and pretified the output to "normal" utf-8 encoding) gives us the flag for this challenge.
Below is the full python-code created for this challenge.

#!/usr/bin/env python3
import base64
from binascii import unhexlify
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

data ="617a316a5a6d526a4d44466c4f54526d5a4463794f4445354d5455354f444d77593255344e54646d597a45354d437870505446684f57526c5a6a6b344e57457a4d7a49334e6a59784d6d49314d6a4532596a5a6a5a6a4e6b4d5755344c4449774f5446685a444d325a444d324d574d344f475131597a4d794d444a6c4d7a5a6b4f546331595441314e4455314e5464694e4455775a44566d5a47466d5954466b4e6a49774e7a6c6d4d5749324e6a677a59544a6b4e574e6c595459335a5759774f47557a4d6d4533595445314f4755315932526b4d7a67304f44557a5a413d3d"

decoded = base64.b64decode(unhexlify(data))
decoded = decoded.decode()

k, i, v = decoded.split(',')

# Cleanup the values
k = k[2:]
i = i[2:]

cipher = AES.new(unhexlify(k), AES.MODE_CBC, i[:AES.block_size])
decrypted = unpad(cipher.decrypt(unhexlify(v)), AES.block_size)

print(decrypted.decode())

And with that, the challenge has been conquered and 200 points is safely in the bag.

FLAG

GPSCTF{208E5f02Dc1EEe20DE59F8dfcA2bd06e}

Leave a Reply

Your email address will not be published. Required fields are marked *