https://app.hackthebox.com/challenges/658

Description

Locked within a cabin crafted entirely from ice, you’re enveloped in a chilling silence. Your eyes land upon an old notebook, its pages adorned with thousands of cryptic mathematical symbols. Tasked with deciphering these enigmatic glyphs to secure your escape, you set to work, your fingers tracing each intricate curve and line with determination. As you delve deeper into the mysterious symbols, you notice that patterns appear in several pages and a glimmer of hope begins to emerge. Time is flying and the temperature is dropping, will you make it before you become one with the cabin?

Exploitation

#!/usr/bin/env python3
from Crypto.Util.number import bytes_to_long as b2l, long_to_bytes as l2b
from Crypto.Util.Padding import unpad
from enum import Enum

class Mode(Enum):
    ECB = 0x01
    CBC = 0x02

class Cipher:
    def __init__(self, key, iv=None):
        self.BLOCK_SIZE = 64
        self.KEY = [b2l(key[i:i+self.BLOCK_SIZE//16]) for i in range(0, len(key), self.BLOCK_SIZE//16)]
        self.DELTA = 0x9e3779b9
        self.IV = iv
        if self.IV:
            self.mode = Mode.CBC
        else:
            self.mode = Mode.ECB
    
    def _xor(self, a, b):
        return b''.join(bytes([_a ^ _b]) for _a, _b in zip(a, b))

    def decrypt_block(self, ct_block):
        ct = b2l(ct_block)
        msk = (1 << (self.BLOCK_SIZE//2)) - 1
        m0 = (ct >> (self.BLOCK_SIZE//2)) & msk
        m1 = ct & msk
        K = self.KEY
        s = self.DELTA * 32
        for i in range(32):
            m1 = (m1 - (((m0 << 4) + K[2]) ^ (m0 + s) ^ ((m0 >> 5) + K[3]))) & msk
            m0 = (m0 - (((m1 << 4) + K[0]) ^ (m1 + s) ^ ((m1 >> 5) + K[1]))) & msk
            s = (s - self.DELTA) & 0xFFFFFFFF
        return l2b(m0) + l2b(m1)

    def decrypt(self, ct):
        blocks = [ct[i:i+self.BLOCK_SIZE//8] for i in range(0, len(ct), self.BLOCK_SIZE//8)]
        pt = b''
        if self.mode == Mode.ECB:
            for block in blocks:
                pt += self.decrypt_block(block)
        try:
            return unpad(pt, self.BLOCK_SIZE//8)
        except:
            return pt

def main():
    key = bytes.fromhex('e25b3dd8f702879cccaec0280a29c66a')
    ct = bytes.fromhex('0ab76ebf55e0957ccaea74b440cb6f2ccef34969bdb22f87c73391d04dbe7fb272d7a6533a38a943449dda8cdce124be429e34e58847243904e8543ef33141d23da518b6bd1800f2')
    cipher = Cipher(key)
    pt = cipher.decrypt(ct)
    print(pt.decode('utf-8', errors='ignore'))

if __name__ == '__main__':
    main()

Summary

Iced Tea: abuse the AES misuse, derive the missing key material, and decrypt the flag.