solved easy
This commit is contained in:
@ -1,8 +1,79 @@
|
||||
import socket
|
||||
|
||||
import base64
|
||||
import hashlib
|
||||
from Crypto.Cipher import AES
|
||||
import binascii
|
||||
# Fill in the right target here
|
||||
HOST = 'this.is.not.a.valid.domain' # TODO
|
||||
PORT = 0 # TODO
|
||||
HOST = 'netsec.net.in.tum.de' # TODO
|
||||
PORT = 20105 # TODO
|
||||
KEY = b'1337133713371337'
|
||||
|
||||
def pkcs7(message: bytes, block_size: int = 16) -> bytes:
|
||||
gap_size = block_size - (len(message) % block_size)
|
||||
return message + bytes([gap_size] * gap_size)
|
||||
|
||||
def calc_hmac(key: bytes, message: bytes ) -> bytes:
|
||||
block_size = 64
|
||||
if len(key) > block_size:
|
||||
key = hashlib.sha256(key).digest()
|
||||
if len(key) < block_size:
|
||||
key += b'\x00' * (block_size - len(key))
|
||||
|
||||
o_key_pad = bytes([k ^ 0x5C for k in key])
|
||||
i_key_pad = bytes([k ^ 0x36 for k in key])
|
||||
|
||||
inner_hash = hashlib.sha256(i_key_pad + message).digest()
|
||||
return hashlib.sha256(o_key_pad + inner_hash).digest()
|
||||
|
||||
def calc_cbc_mac( key: bytes, iv: bytes, message: bytes) -> bytes:
|
||||
message = pkcs7(message)
|
||||
cipher = AES.new(key, AES.MODE_CBC, iv)
|
||||
encrypted_message = cipher.encrypt(message)
|
||||
return encrypted_message[-16:]
|
||||
|
||||
def cmac_padding(message: bytes, block_size: int = 16) -> bytes:
|
||||
if len(message) % block_size == 0:
|
||||
return message # Full block, no padding needed
|
||||
else:
|
||||
padded_message = message + b'\x80' # Add the 0x80 byte
|
||||
return padded_message.ljust((len(message) // block_size + 1) * block_size, b'\x00')
|
||||
|
||||
def calc_cmac(key: bytes, message: bytes) -> bytes:
|
||||
from Crypto.Cipher import AES
|
||||
|
||||
def shift_left(block: bytes) -> bytes:
|
||||
result = int.from_bytes(block, byteorder="big") << 1
|
||||
return (result & ((1 << 128) - 1)).to_bytes(16, byteorder="big")
|
||||
|
||||
const_rb = 0x87
|
||||
cipher = AES.new(key, AES.MODE_ECB)
|
||||
zero_block = b'\x00' * 16
|
||||
l_block = cipher.encrypt(zero_block)
|
||||
|
||||
k1 = shift_left(l_block)
|
||||
if l_block[0] & 0x80:
|
||||
k1 = (int.from_bytes(k1, byteorder="big") ^ const_rb).to_bytes(16, byteorder="big")
|
||||
|
||||
k2 = shift_left(k1)
|
||||
if k1[0] & 0x80:
|
||||
k2 = (int.from_bytes(k2, byteorder="big") ^ const_rb).to_bytes(16, byteorder="big")
|
||||
|
||||
padded_message = cmac_padding(message)
|
||||
if len(message) % 16 == 0:
|
||||
last_block = bytes([b ^ k1[i] for i, b in enumerate(padded_message[-16:])])
|
||||
else:
|
||||
last_block = bytes([b ^ k2[i] for i, b in enumerate(padded_message[-16:])])
|
||||
|
||||
previous_block = zero_block
|
||||
for i in range(0, len(padded_message) - 16, 16):
|
||||
block = padded_message[i:i + 16]
|
||||
previous_block = cipher.encrypt(bytes([b ^ p for b, p in zip(block, previous_block)]))
|
||||
|
||||
cmac_result = cipher.encrypt(bytes([b ^ p for b, p in zip(last_block, previous_block)]))
|
||||
return cmac_result
|
||||
|
||||
def decode_message(msg):
|
||||
return binascii.unhexlify(msg)
|
||||
|
||||
|
||||
def get_flag():
|
||||
@ -12,8 +83,16 @@ def get_flag():
|
||||
sf = s.makefile('rw') # we use a file abstraction for the sockets
|
||||
|
||||
message1 = sf.readline().rstrip('\n')
|
||||
# TODO
|
||||
|
||||
print(message1)
|
||||
challenge = decode_message(message1)
|
||||
hmac = base64.b64encode(calc_hmac(KEY, challenge)).decode()
|
||||
cmac = base64.b64encode(calc_cmac(KEY, challenge)).decode()
|
||||
cbc_mac = base64.b64encode(calc_cbc_mac(KEY, b'\x00' * 16, challenge)).decode()
|
||||
answer = f"{hmac};{cbc_mac};{cmac}"
|
||||
print(f"Calcualted the answer {answer}")
|
||||
sf.write(f"{answer}\n")
|
||||
sf.flush()
|
||||
print(sf.readline().rstrip('\n'))
|
||||
sf.close()
|
||||
s.close()
|
||||
|
||||
|
Reference in New Issue
Block a user