This commit is contained in:
2024-12-09 18:22:38 +09:00
parent ab0cbebefc
commit c4c4547706
959 changed files with 174888 additions and 6 deletions

Binary file not shown.

44
week05/hard/bruteforec.py Normal file
View File

@ -0,0 +1,44 @@
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import base64
import itertools
# Function to compute the CBC-MAC of a given message, IV, and key
def cbc_mac(message: bytes, iv: bytes, key: bytes) -> bytes:
cipher = AES.new(key, AES.MODE_CBC, iv)
padded_message = pad(message, 16) # Ensure the message is padded to the block size
return cipher.encrypt(padded_message)[-16:]
# Brute-force the key by trying all possible 16-byte keys
def brute_force_keys(target_mac, iv, message, key_size=16):
"""
Attempts to brute-force the key used for CBC-MAC, given the target MAC.
:param target_mac: The target MAC we're trying to guess.
:param iv: The IV used for CBC-MAC.
:param message: The plaintext message used to generate the MAC.
:param key_size: The size of the key (16 bytes for AES-128).
:return: The correct key if found, otherwise None.
"""
# Loop through all possible 16-byte keys (this is feasible since there are only 2^128 keys)
# For demonstration purposes, we're assuming a small brute-force keyspace (e.g., 256^16)
for candidate_key in itertools.product(range(256), repeat=key_size):
candidate_key = bytes(candidate_key)
computed_mac = cbc_mac(message, iv, candidate_key)
if computed_mac == target_mac:
return candidate_key
return None
# Example usage:
message = b"type=secrets&number=1337"
iv = base64.b64decode('00000000000000000000000000000000') # Controlled IV (could be any IV)
# Assume the target MAC is obtained from the server for this message and IV
# In a real attack, you'd receive this MAC from the server
target_mac = base64.b64decode('e0f8b77b2ac5fa872f5646ac90b056ac') # Example MAC
# Attempt to brute-force the key
guessed_key = brute_force_keys(target_mac, iv, message)
if guessed_key:
print(f"Found key: {guessed_key.hex()}")
else:
print("Failed to brute-force the key.")

View File

@ -1,18 +1,20 @@
import socket
import random
from Crypto.Cipher import AES
import base64
import time
# Fill in the right target here
HOST = 'this.is.not.a.valid.domain' # TODO
PORT = 0 # TODO
HOST = 'localhost' # TODO
PORT = 20205 # TODO
correct_message = "dHlwZT1zZWNyZXRzJm51bWJlcj0xMzM3;AAAAAAAAAAAAAAAAAAAAAA==;OpDnZaDSwwbQ7YoFg16Q3Q=="
def get_flag():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
sf = s.makefile('rw') # we use a file abstraction for the sockets
# TODO
sf.close()
s.close()

27
week05/hard/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

@ -77,6 +77,7 @@ async def handle_client(client_reader: StreamReader, client_writer: StreamWriter
return
match message.split(';'):
case [m, iv, mac]:
print(m,iv,mac)
m = base64.b64decode(m)
iv = base64.b64decode(iv)
mac = base64.b64decode(mac)
@ -104,6 +105,7 @@ def accept_client(client_reader: StreamReader, client_writer: StreamWriter):
def main():
print(KEY)
# start server
loop = asyncio.get_event_loop()
f = asyncio.start_server(accept_client, host=None, port=20205)

36
week05/hard/test.py Normal file
View File

@ -0,0 +1,36 @@
import base64
import random
from Crypto.Cipher import AES
KEY = random.randbytes(16)
# KEY =b'\xaab\xa65z"\xac\xb1,a\xff1\xdb6}\xb0' # The key should match the server's key
IV = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" # The IV can be random
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 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
# Craft the message
message = b"type=recrets&number=1337"
# Calculate the MAC
mac = cbc_mac(message, IV, KEY)
# Base64 encode the message, IV, and MAC
encoded_message = base64.b64encode(message).decode('utf-8')
encoded_iv = base64.b64encode(IV).decode('utf-8')
encoded_mac = base64.b64encode(cbc_mac(message, IV,KEY)).decode('utf-8')
# Final request to send
final_message = f"{encoded_message};{encoded_iv};{encoded_mac}"
print(final_message)
# MAC verification failed: expected afb7f5f307ea507b631d964e089a820a, got a0b0b48844a7deaf9d917a5f11ae0359