top of page

HackTM 2020 Qualifiers - Count on Me 🚩

Updated: Sep 22, 2022

Description:

There is no description for the challenge. The zip file includes three resources:

  • challenge.txt – gives us the encryption scheme – AES 256 CBC mode, iv, and ciphertext to decrypt

  • aes.py – simple example of how to use Crypto.Cipher to encrypt/decrypt in Python

  • key.png – presumably a representation of the key

What seems to be the challenge is to derive the key from key.png and decipher the ciphertext from challenge.txt


We explored many different ideas as to how the key is derived. Looking up the image in stega tools showed nothing interesting. Pretty quickly we reached the conclusion that there is an upper part and a lower part to each symbol. The top can be one of four characters, the bottom can be one of five characters. Interestingly, the symbols can be sequenced using the number of lines per symbol. A special curved character could signify the zero character (when both parts are empty). The three pixelated symbols are unknown, we probably need to bruteforce them once more information is known.


In total there are 59 symbols. Each one can be one of 20 values, resulting in 20^59 possible combinations (5.764608e+76). This was suspiciously close to half of the representation space of 256bit keys – 1.157921e+77. Since the bottom has 5 possible “digits” and the top has 4, we can look at the symbols as two-digit base5 numbers with the top character being more significant (if we look at it the other way round we get values above 20). Now we can represent the symbol array as 59 base20 digits, which we did here:


DIGITS = [19, 3, 10, 15, 2, -6, 16, 16, 18, 12, 19, 6, 19, 12, 8, -6, 5, 8, 17, 18, 18, 5, 9, 3, 11, 10, 1, 10, 10, 0, 10, -6, 0, 8, 18, 10, 0, 15, 18, 5, 18, 14, 19, 1, 1, 0, 4, 6, 15, 4, 11, 16, 10, 8, 14, 5, 13, 16, 9]


Now we took a leap of faith and assumed the key is zero-extended, meaning the key is prepended with a 0 bit. Therefore we just need to plug in the calculated key as is. The only thing left is to loop over the pixelated symbols and look for a plaintext which includes HackTM.



from Crypto.Cipher import AES  

DIGITS = [19, 3, 10, 15, 2, -6, 16, 16, 18, 12, 19, 6, 19, 12, 8, -6, 5, 8, 17, 18, 18, 5, 9, 3, 11, 10, 1, 10, 10, 0, 10, -6, 0, 8, 18, 10, 0, 15, 18, 5, 18, 14, 19, 1, 1, 0, 4, 6, 15, 4, 11, 16, 10, 8, 14, 5, 13, 16, 9]

cipher = '059fd04bca4152a5938262220f822ed6997f9b4d9334db02ea1223c231d4c73bfbac61e7f4bf1c48001dca2fe3a75c975b0284486398c019259f4fee7dda8fec'.decode("hex")
iv = '42042042042042042042042042042042'.decode('hex')
def get_key_from_digits(digits):
    key = 0
    for i in range(len(digits)):
        key += digits[len(digits) - 1 - i] * (20 ** i)      
    key = hex(key)     
    key = key[2:-1]
    return key  

def decrypt(cipher, key):     
    key = key.decode('hex')     
    aes = AES.new(key,AES.MODE_CBC, iv)
    return aes.decrypt(cipher)
    
for i in range(20):
    for j in range(20):
        for k in range(20):             
            digits = DIGITS             
            digits[5], digits[15], digits[31] = i,j,k
            if 'HackTM' in decrypt(cipher, get_key_from_digits(digits)):
                print decrypt(cipher, get_key_from_digits(digits))

After under a second, the output is:

HackTM{can_1_h@ve_y0ur_numb3r_5yst3m_??}000000000000000000000000

0 comments

Recent Posts

See All

Comments


bottom of page