solved easy

This commit is contained in:
2024-12-02 02:09:27 +09:00
parent 0d6eaf273d
commit ab0cbebefc
9 changed files with 257 additions and 139 deletions

Binary file not shown.

View File

@ -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()

View File

@ -1,79 +0,0 @@
import random
import binascii
from Crypto.Cipher import AES
from Crypto.Hash import CMAC, HMAC, SHA256
import hashlib
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_cbc_mac(message: bytes, iv: bytes, key: bytes) -> bytes:
cipher = AES.new(key, AES.MODE_CBC, iv)
message = pkcs7(message)
last_block = cipher.encrypt(message)[-16:]
return last_block
def calc_hmac(message: bytes, key: bytes) -> bytes:
# Create HMAC object with the key and message using SHA-256
hmac = HMAC.new(KEY, msg=message, digestmod=SHA256)
# Calculate the HMAC
mac = hmac.hexdigest()
return mac
def calc_cmac(message: bytes, key: bytes) -> bytes:
c = CMAC.new(key, ciphermod=AES)
c.update(message)
return c.digest()
def calc_pure_cmac(message: bytes, key: bytes) -> bytes:
def left_shift(k):
"""Perform left shift on a byte string with overflow handling"""
result = bytearray(k)
overflow = result[0] & 0x80
for i in range(len(result)):
result[i] <<= 1
if i > 0:
result[i] |= (1 if result[i-1] & 0x80 else 0)
if overflow:
result[-1] ^= 0x87
return bytes(result)
def xor_bytes(a, b):
"""XOR two byte strings"""
return bytes(x ^ y for x, y in zip(a, b))
def check_challenge(challenge: bytes):
return (
calc_cbc_mac(challenge, b'\x00' * 16, KEY),
calc_cmac(challenge, KEY),
calc_hmac(challenge, KEY)
)
def decode_message(msg):
return binascii.unhexlify(msg)
def main():
challenge = "f681e8625406c40419ae7771eac8f8a2eb6a6fcb1fc0396ab8fdca793a27c93a6dafbb"
challenge = decode_message(challenge)
print(check_challenge(challenge))
if __name__ == "__main__":
main()

27
week05/easy/pwn_utils.py Normal file
View File

@ -0,0 +1,27 @@
import asyncio
class utils:
@staticmethod
async def read_line_safe(reader):
"""
Simple implementation to read a line from an async reader
Mimics the original read_line_safe functionality
"""
try:
line = await reader.readline()
return line.decode().strip()
except Exception:
return None
def log_error(e, client_writer=None):
"""
Basic error logging function
"""
print(f"Error occurred: {e}")
if client_writer:
try:
client_writer.write(f"Error: {str(e)}\n".encode())
except Exception:
print("Could not send error to client")

View File

@ -68,6 +68,7 @@ async def handle_client(client_reader: StreamReader, client_writer: StreamWriter
hmac = base64.b64decode(hmac)
cbc_mac = base64.b64decode(cbc_mac)
cmac = base64.b64decode(cmac)
print(hmac, cbc_mac, cmac)
if check_challenge(challenge, hmac, cbc_mac, cmac):
client_writer.write(subprocess.check_output('flag'))
else:

View File

@ -1,55 +0,0 @@
import random
import binascii
import base64
from Crypto.Cipher import AES
from Crypto.Hash import CMAC, HMAC, SHA256
# Crypto.Hash and hmac modules are forbidden so needs to replace them
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_cbc_mac(message: bytes, iv: bytes, key: bytes) -> bytes:
cipher = AES.new(key, AES.MODE_CBC, iv)
message = pkcs7(message)
last_block = cipher.encrypt(message)[-16:]
last_block = base64.b64encode(last_block)
return last_block
def calc_hmac(message: bytes, key: bytes) -> bytes:
# Create HMAC object with the key and message using SHA-256
hmac = HMAC.new(KEY, msg=message, digestmod=SHA256)
hmac = base64.b64encode(hmac.digest())
return hmac
def calc_cmac(message: bytes, key: bytes) -> bytes:
c = CMAC.new(key, ciphermod=AES)
c.update(message)
cmac = base64.b64encode(c.digest())
return cmac
def check_challenge(challenge: bytes):
return (
calc_cbc_mac(challenge, b'\x00' * 16, KEY),
calc_cmac(challenge, KEY),
calc_hmac(challenge, KEY)
)
def decode_message(msg):
return binascii.unhexlify(msg)
def main():
challenge = "f681e8625406c40419ae7771eac8f8a2eb6a6fcb1fc0396ab8fdca793a27c93a6dafbb"
challenge = decode_message(challenge)
print(check_challenge(challenge))
if __name__ == "__main__":
main()