Skip to content

Instantly share code, notes, and snippets.

@minhtt159
Last active November 26, 2022 17:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save minhtt159/caa71b9f039a46d979fd86fdffff076f to your computer and use it in GitHub Desktop.
Save minhtt159/caa71b9f039a46d979fd86fdffff076f to your computer and use it in GitHub Desktop.
MeePwn CTF Final 2018 - ESOR
#!/usr/bin/python2
from Crypto.Cipher import AES
import hmac, hashlib
import os
import sys
menu = """Choose one:
1. encrypt data
2. decrypt data
3. quit
"""
class Unbuffered(object):
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)
sys.stdout = Unbuffered(sys.stdout)
sys.stderr = None
# quals
encrypt_key = '\xff' * 32
# final
encrypt_key = os.urandom(32)
secret = 'MeePwnCTF{###FLAG_H###}'
hmac_secret = ''
blocksize = 16
hmac_size = 20
def pad(msg):
padlen = blocksize - (len(msg) % blocksize) - 1
return os.urandom(padlen) + chr(padlen)
def unpad(msg):
return msg[:-(ord(msg[-1]) + 1)]
def compute_hmac(msg):
return hmac.new(hmac_secret, msg, digestmod=hashlib.sha1).digest()
def encrypt(prefix='', suffix=''):
_enc = prefix + secret + suffix
_enc+= compute_hmac(_enc)
_enc+= pad(_enc)
iv = os.urandom(16)
_aes = AES.new(encrypt_key, AES.MODE_CBC, iv)
return (iv + _aes.encrypt(_enc)).encode('hex')
def decrypt(data):
data = data.decode('hex')
try:
iv = data[:blocksize]
_aes = AES.new(encrypt_key, AES.MODE_CBC, iv)
data = _aes.decrypt(data[blocksize:])
data = unpad(data)
plaintext = data[:-hmac_size]
mac = data[-hmac_size:]
if mac == compute_hmac(plaintext): return True
else: return False
except: return False
print """Welcome to our super secure enc/dec server.
We use hmac, so, plz don't hack us (and you can't). Thanks."""
while True:
choice = int(raw_input(menu))
if choice == 1:
_pre = raw_input('prefix: ')
_suf = raw_input('suffix: ')
print encrypt(prefix=_pre, suffix=_suf)
elif choice == 2:
_data = raw_input('data: ')
if decrypt(_data):
print 'OK'
else:
print 'KO'
elif choice == 3:
sys.exit(0)
else:
choice = int(raw_input(menu))
# general code to solve poodle challange
suf_length = 0
flag_length = 0
for i in range(1,17):
tmp_length = len(encrypt('a'*i,'').decode('hex'))
if flag_length == 0:
flag_length = tmp_length
if tmp_length > flag_length:
suf_length = i - 1
flag_length = flag_length - 16 - i - 20 # -len(IV) - len(padding) - len(HMAC)
break
print 'Flag length:', flag_length
flag = ""
for block_i in range(1, flag_length/blocksize + 1):
for index in range(1,17):
prefix = 'a'*(16 - index)
suffix = 'a'*(index + suf_length)
enc = encrypt(prefix,suffix).decode('hex')
inject_block = enc[block_i*16:(block_i+1)*16]
xor_byte = enc[block_i*16-1]
for char in range(1,256):
data = (enc + '\xff'*15 + chr(char) + inject_block).encode('hex')
if decrypt(data):
num = char ^ 32 ^ ord(xor_byte)
flag += char(num)
break
print flag
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment