CTF-Writeups

Here I publish my writeups for CTF challenges (mostly Crypto and Programming)

View on GitHub

435!

Here is the challenge code and Description

I have an encrypted message and the corresponding secret key, but some of their characters are missing. Can you help me find the flag?

Note: Missing characters are shown by *.
import binascii
import hashlib
import sys
from Crypto.Cipher import AES

key = b'*XhN2*8d%8Slp3*v'
key_len = len(key)

def pad(message):
	padding = bytes((key_len - len(message) % key_len) * chr(key_len - len(message) % key_len), encoding='utf-8')
	return message + padding

def encrypt(message, key, iv):
	aes = AES.new(key, AES.MODE_CBC, iv)
	return aes.encrypt(message)

h = hashlib.sha256(key).hexdigest()
hidden = binascii.unhexlify(h)[:10]
message = b'CBC (Cipher Blocker Chaining) is an advanced form of block cipher encryption' + hidden

with open('flag', 'rb') as f:
	IV = f.read().strip(b'TMUCTF{').strip(b'}')
	print(binascii.hexlify(encrypt(pad(message), key, IV)))

and the output

9**********b4381646*****01********************8b9***0485******************************0**ab3a*cc5e**********18a********5383e7f**************1b3*******9f43fd66341f3ef3fab2bbfc838b9ef71867c3bcbb

Pretty output for 32 bit hex (16 bytes) for every block
block1: 9**********b4381646*****01******
block2: **************8b9***0485********
block3: **********************0**ab3a*cc
block4: 5e**********18a********5383e7f**
block5: ************1b3*******9f43fd6634
block6: 1f3ef3fab2bbfc838b9ef71867c3bcbb

Solution

As we know the flag is IV and we can’t bruteforce it because of large state space for it
Also we know some characters are missing in output and the key
We have last block of cipher text and also we have 13 bytes of the key with 3 bytes missing
So we can bruteforce the key with just 16777216 keys possible If we decrypt last block of the message and xor it with last block of the ciphertext we can compare last 5 bytes of the result with 9f43fd6634 which is last 5 bytes of previous block to ensure the key is correct

BruteForce missing characters of the Key

import binascii
import hashlib
import sys
from Crypto.Cipher import AES
from Crypto.Util.number import *

gkey = '*XhN2*8d%8Slp3*v'
key_len = len(gkey)

def brute_key():

    key = gkey
    check = bytes.fromhex('9f43fd6634')

    for i in range(0, 256):

        tindex1 = key.find('*')
        key = key.replace('*', chr(i), 1)

        for j in range(0, 256):

            tindex2 = key.find('*')
            key = key.replace('*', chr(j), 1)

            for k in range(0, 256):

                tindex3 = key.find('*')
                key = key.replace('*', chr(k), 1)

                h = hashlib.sha256(key.encode("latin")).hexdigest()
                hidden = binascii.unhexlify(h)[:10]

                message =  b'CBC (Cipher Blocker Chaining) is an advanced form of block cipher encryption'
                message += hidden
                m = pad(message)


                c1 = bytes.fromhex('1f3ef3fab2bbfc838b9ef71867c3bcbb')
                b1 = m[-16:]

                aes = AES.new(key.encode("latin"), AES.MODE_ECB)
                c2 = repeating_xor_key(aes.decrypt(c1), b1)

                if (c2[-5:] == check):
                    print(key)
                    print(key.encode('latin'))
                    print(c2)


                tlist3 = list(key)
                tlist3[tindex3] = "*"
                key = "".join(tlist3)

            tlist2 = list(key)
            tlist2[tindex2] = "*"
            key = "".join(tlist2)

        tlist1 = list(key)
        tlist1[tindex1] = "*"
        key = "".join(tlist1)

Here is the result, we got a key

key = '0XhN2!8d%8Slp3Ov'

Decrypt previous block

Now we should repeat the steps we did for last block until we reach first block and find IV which is our flag

def find_IV():
    key = "0XhN2!8d%8Slp3Ov"

    h = hashlib.sha256(key.encode("latin")).hexdigest()
    hidden = binascii.unhexlify(h)[:10]

    message =  b'CBC (Cipher Blocker Chaining) is an advanced form of block cipher encryption'
    message += hidden
    message = pad(message)

    cipher = bytes.fromhex('1f3ef3fab2bbfc838b9ef71867c3bcbb')
    block = message[-16:]
    
    # cipher = c1
    for i in range(2, 8):

        print(hex(bytes_to_long(cipher)))
        # print(block)
        aes = AES.new(key.encode("latin"), AES.MODE_ECB)
        cipher = repeating_xor_key(aes.decrypt(cipher), block)
        block = message[i*-16:(i-1)*-16]
        print(cipher)

And here is the result, The last Line is IV and actually the flag !!

0x1f3ef3fab2bbfc838b9ef71867c3bcbb
b'\x9c\x1a\x9d\x16y\\\x1b3Mn\xc4\x9fC\xfdf4'
0x9c1a9d16795c1b334d6ec49f43fd6634
b'^Yi\xdc\xdb\x9b\x18\xac3\x997\x858>\x7f2'
0x5e5969dcdb9b18ac33993785383e7f32
b'\x95\x93I\xe94\x81\x86\x9c\x83m\x90\r\xca\xb3\xa6\xcc'
0x959349e93481869c836d900dcab3a6cc
b'\x8b\xc6z\x00\xc0\xe5\x19\x8b\x9d\x03\x04\x85\x89S\xeb\x83'
0x8bc67a00c0e5198b9d0304858953eb83
b'\x9fJ\xc9\x03\x11\x8bC\x81db\xb3Q\x01\xa7\xb6\xfe'
0x9f4ac903118b43816462b35101a7b6fe
b'Y0U_D3CrYP73D_17'
Flag : TMUCTF{Y0U_D3CrYP73D_17}

solution code

KouroshRZ for AbyssalCruelty