We played ApoorvCTF


Crypto

kowareta cipher

THe question is about AES-ECB Plaintext Recovery. It is a cryptographic attack that exploits the weaknesses of the ECB mode. In ECB mode, identical plaintext blocks are encrypted into identical ciphertext blocks, making it vulnerable to pattern recognition and chosen-plaintext attacks.

Chall.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import sys
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from random import randbytes

def main():
key = randbytes(16)
cipher = AES.new(key, AES.MODE_ECB)
flag = b'apoorvctf{fake_flag_123}'

print("Welcome to the ECB Oracle challenge!")
print("Enter your input in hex format.")

try:
while True:
print("Enter your input: ", end="", flush=True)
userinput = sys.stdin.readline().strip()

if not userinput:
break

try:
userinput = bytes.fromhex(userinput)
ciphertext = cipher.encrypt(pad(userinput + flag + userinput, 16))
print(ciphertext)
print("Ciphertext:", ciphertext.hex())

except Exception as e:
print(f"Error: {str(e)}")

except KeyboardInterrupt:
print("Server shutting down.")

if __name__ == "__main__":
main()

main()

I’m using a script from John Hammond’s YT video here

solve.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

from pwn import *
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from string import printable

host = "chals1.apoorvctf.xyz"
port = 4001

p = remote(host,port)

def get_block(encrypted):
new = []
for i in range(0, len(encrypted), block_length):
new.append(encrypted[i:i+block_length])
return new

def encrypt(payload):
p.sendline(payload)
p.recvuntil(b'Ciphertext: ')
blocks = p.recvline().strip().decode('utf-8')
p.recvuntil(b': ')
return blocks

encrypted_length = 32
block_length = 32

flag = 'apoorvctf{3cb_345y_crypt0_br34k'
start_length = 31 + 16

while True:
payload = b"A" * (start_length - len(flag))
testblock = encrypt(payload.hex().encode())
blocks = get_block(testblock)
print("expected: ", blocks[2])

for c in printable:
print("testing: ", c)
inp ="A" * (start_length - len(flag)) + flag + c
print("testing: ", inp)
result = encrypt(inp.encode().hex().encode())
result_block = get_block(result)
if result_block[2] == blocks[2]:
print("found: ", c)
flag += c
print(flag)
break

if flag.endswith('}'):
print(f'{flag=}')
break
#apoorvctf{3cb_345y_crypt0_br34k}