imaginaryctf october 2024
1. Wrong Hex (Crypto)
A fun frequency analysis challenge.
plaintext = '''REDACTED'''
assert 'ictf{' in plaintext
cipher = [*'123456789abcdef']
shuffle(cipher)
cipher = '0'+''.join(cipher)+'0'
def encrypt(string):
return ''.join(cipher[cipher.index(c)+1] for c in string)
print(encrypt(plaintext.encode().hex()))
# ed303ea1b53e34b5383ca13833a134bebdbe373ca132b5a1b53237b139b2a1bb383c3d3eba33be39aca1d4b5a1bd303ea13d34b2b5a13b3ebda13538393d3ebaa9a1d2a135343ca13934b23ebaa1beb1a1323ca137b2a137343cb2a7b13835363ebd3e3da13f3435363ebdb5a1343c3da1353834bdb5a9a13e3c3f38b2323c3ba1bd303ea130be3eb5a13833a1bd303ea1393e34b33eb5acacaca1ed303ea1343c3c38b2343c353eb5a13833a1b5b1ba323c3ba1343c3da1b5be37373ebaa1a7a13439393eba3b323eb5a9a13738b5b4be32bd383eb5a9a1303e34bda1a7a1bd303eb2a1343939a133343d3ea134bb34b2aca1ed303ea13a3e34bebd3233be39a9a13538393da13a3932b5b5a13833a1bb323cbd3ebaa1b5bd34babdb5a1bd38a1b53ebda1323caca1ed303ea13339343ba132b5a13235bd33b6335dd939e8543c5b51e8d1e8e1555d3555d3be54e8b539ee375055bab7ac
From the ciphertext, we can do some frequency analysis to get the mappings. A nifty trick in CTFs is to get the mapping through the fixed characters in the flag (usually the first few characters) like ictf{.
mappings = {
'b': '7',
'6': 'b',
'3': '6',
'5': '3',
'd':'4',
'2': '9',
'9' : 'c',
'4': '1',
'a': '2',
'1': '0',
'8': 'f',
'7': 'd',
'c': 'e',
'e': '5',
'0': '8',
'f': 'a',
}
partial = decrypt(ciphertext, mappings)
partial2 = ""
for i in range(0, len(partial), 2):
if "_" not in partial[i:i+2]:
hex_pair = partial[i:i+2]
ascii_char = bytes.fromhex(hex_pair).decode('ascii')
partial2 += ascii_char
else:
partial2 += "(" + partial[i:i+2] + ")"
print(partial2)