From 022291f5af7b7ea61ab5e5a0aa33aec664e7ef64 Mon Sep 17 00:00:00 2001 From: Dongho Kim Date: Tue, 10 Dec 2024 00:51:04 +0900 Subject: [PATCH] just for now --- .../__pycache__/pwn_utils.cpython-312.pyc | Bin 0 -> 1476 bytes week06/easy/client.py | 33 ++++-- week06/easy/pwn_utils.py | 27 +++++ week06/easy/server.py | 7 +- week06/easy/test.py | 36 +++++++ .../__pycache__/insecurelib.cpython-312.pyc | Bin 0 -> 11197 bytes .../__pycache__/pwn_utils.cpython-312.pyc | Bin 0 -> 1476 bytes week06/hard/alice.py | 41 ++++++-- week06/hard/alice_private.pem | 3 + week06/hard/alice_public.pem | 3 + week06/hard/bob.py | 40 +++++-- week06/hard/bob_private.pem | 3 + week06/hard/bob_public.pem | 3 + week06/hard/client.py | 17 ++- week06/hard/generate_sig_keys.py | 2 + week06/hard/insecurelib.py | 3 +- week06/hard/pwn_utils.py | 27 +++++ week06/hard/test.py | 98 ++++++++++++++++++ 18 files changed, 311 insertions(+), 32 deletions(-) create mode 100644 week06/easy/__pycache__/pwn_utils.cpython-312.pyc create mode 100644 week06/easy/pwn_utils.py create mode 100644 week06/easy/test.py create mode 100644 week06/hard/__pycache__/insecurelib.cpython-312.pyc create mode 100644 week06/hard/__pycache__/pwn_utils.cpython-312.pyc create mode 100644 week06/hard/alice_private.pem create mode 100644 week06/hard/alice_public.pem create mode 100644 week06/hard/bob_private.pem create mode 100644 week06/hard/bob_public.pem create mode 100644 week06/hard/pwn_utils.py create mode 100644 week06/hard/test.py diff --git a/week06/easy/__pycache__/pwn_utils.cpython-312.pyc b/week06/easy/__pycache__/pwn_utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3bf0b118501164d9976205f8cb43c77e7fdc452a GIT binary patch literal 1476 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 (reader, writer) @@ -73,20 +96,20 @@ class AuthenticatedChannel: return None # calculate shared key + print("calculating key now") key = str(pow(Y, a, mod=p)) key = KDRV256(key.encode()) - # decrypt and verify signature decrypted_sig = decrypt(key, s) if not verify(bob_public, message=f'{Y},{X}'.encode(), signature=decrypted_sig): self.writer.write('Signature verification failed\n'.encode()) await self.writer.drain() return None - # sign X and Y and send signature sig = sign(privKey, f'{X},{Y}'.encode()) sig = encrypt(key, sig) self.writer.write(sig + b'\n') + print("finished the do_STS_key_exchange") await self.writer.drain() self.shared_key = key @@ -111,7 +134,7 @@ async def do_session_key_DH_exchange(channel: AuthenticatedChannel) -> bytes | N return p, g, X = map(int, pgX.split(',')) - + print("p, g, x is here: ", (p,g,X)) # two checks to prevent DOSes and improve performance if not check_int_range(p): await channel.send_encrypted(f'{p} must be in [{0}..{MAX_PRIME}]'.encode()) @@ -119,7 +142,7 @@ async def do_session_key_DH_exchange(channel: AuthenticatedChannel) -> bytes | N if not check_int_range(g): await channel.send_encrypted(f'{g} must be in [{0}..{MAX_PRIME}]'.encode()) return - + print("two checks to prevent doses and improve performance finished") # check if parameters are valid if not is_prime(p): await channel.send_encrypted(f'{p} is not a prime number!'.encode()) @@ -132,13 +155,13 @@ async def do_session_key_DH_exchange(channel: AuthenticatedChannel) -> bytes | N if X >= p: await channel.send_encrypted(f"X ({X} can't be larger or equal to p {p}!".encode()) return - + print("check if parameters are valid finished") # create own public/private key parts: b = random.randint(1, p - 1) Y = pow(g, b, mod=p) - + print("sending encryption") await channel.send_encrypted(f'{Y}'.encode()) - + print("sending encyrption finished") # calculate shared key key = str(pow(X, b, mod=p)) key = KDRV256(key.encode()) @@ -165,7 +188,7 @@ async def handle_client(client_reader: StreamReader, client_writer: StreamWriter msg = 'Hey Bob, plz send me my f14g :-)' encrypted_msg = encrypt(session_key, msg.encode()) - + print("sending encypretd message about igving me flag") await authenticated_channel.send_encrypted(encrypted_msg) data = await authenticated_channel.recv_encrypted() diff --git a/week06/hard/alice_private.pem b/week06/hard/alice_private.pem new file mode 100644 index 0000000..0d6204e --- /dev/null +++ b/week06/hard/alice_private.pem @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIEeMyeJI/JBSKPBQVfaOY/T6Ew9fH5JwVrievvcX85V7 +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/week06/hard/alice_public.pem b/week06/hard/alice_public.pem new file mode 100644 index 0000000..6455eb8 --- /dev/null +++ b/week06/hard/alice_public.pem @@ -0,0 +1,3 @@ +-----BEGIN PUBLIC KEY----- +MCowBQYDK2VwAyEAcn6Y7i8GkW0KvMTIaPWj+axVBY29ki2bdAmxza2X6EU= +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/week06/hard/bob.py b/week06/hard/bob.py index a5f5f1d..7a208af 100644 --- a/week06/hard/bob.py +++ b/week06/hard/bob.py @@ -8,7 +8,31 @@ import random from asyncio import StreamReader, StreamWriter from insecurelib import * -from pwn_utils.utils import read_line_safe + + + +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") log = logging.getLogger(__name__) clients = {} # task -> (reader, writer) @@ -51,16 +75,16 @@ class AuthenticatedChannel: async def do_STS_key_exchange(self): # receive p,q and public keypart to other server (over the client) and wait for response pgX = await read_line_safe(self.reader) - if pgX is None: return - if pgX.count(',') != 2: self.writer.write('Invalid amount of arguments (expected 3; p,g,X)\n'.encode()) await self.writer.drain() return p, g, X = map(int, pgX.split(',')) + print(p,g,X) + # primality and size checks not necessary since fixed values from RFC 3526 are used for STS key exchange @@ -105,8 +129,7 @@ async def do_session_key_DH_exchange(channel: AuthenticatedChannel) -> bytes | N # send p,q and public keypart pgX = f'{p},{g},{X}' - await channel.send_encrypted(pgX.encode()) - + await channel.send_encrypted(pgX.encode()) # Start debuggin from here bob Y = await channel.recv_encrypted() log.info(f'received "{Y}" as Y (public key)') @@ -121,6 +144,7 @@ async def do_session_key_DH_exchange(channel: AuthenticatedChannel) -> bytes | N # calculate shared key key = str(pow(Y, a, mod=p)) key = KDRV256(key.encode()) + print("do seession dh is finished") return key @@ -140,9 +164,9 @@ async def handle_client(client_reader: StreamReader, client_writer: StreamWriter # do session key DH exchange session_key = await do_session_key_DH_exchange(authenticated_channel) - + print("session key obtained") message = await authenticated_channel.recv_encrypted() - + print("message received for last: ", message) if message is None: return @@ -155,7 +179,7 @@ async def handle_client(client_reader: StreamReader, client_writer: StreamWriter ) return - flag = subprocess.check_output('flag') + flag = "flaggy".encode() encrypted_flag = encrypt(session_key, flag) await authenticated_channel.send_encrypted(encrypted_flag) diff --git a/week06/hard/bob_private.pem b/week06/hard/bob_private.pem new file mode 100644 index 0000000..270bb38 --- /dev/null +++ b/week06/hard/bob_private.pem @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIBT9LU2Gd571saJkzcQzxwdfmejkLeKjsJy1WhVOjxY2 +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/week06/hard/bob_public.pem b/week06/hard/bob_public.pem new file mode 100644 index 0000000..9381f15 --- /dev/null +++ b/week06/hard/bob_public.pem @@ -0,0 +1,3 @@ +-----BEGIN PUBLIC KEY----- +MCowBQYDK2VwAyEAeI+vbbnxM+olxPgHiYZUuvOFM6WpWBt7CvNuLSioCxQ= +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/week06/hard/client.py b/week06/hard/client.py index bf6c422..80737af 100644 --- a/week06/hard/client.py +++ b/week06/hard/client.py @@ -7,9 +7,9 @@ import socket from insecurelib import KDRV256, HMAC, encrypt, decrypt # Fill in the right target here -HOST = 'this.is.not.a.valid.domain' # TODO -PORT1 = 20008 -PORT2 = 20108 +HOST = 'netsec.net.in.tum.de' +PORT1 = 20206 +PORT2 = 20306 # note the numbers you encounter may be small for demonstration purposes. @@ -25,7 +25,7 @@ def debug_secure_channel(s1, s2, data: str): else: print(f"from {s1} to {s2}: '{data}...'") - iv, ciphertext, mac = data.split(',') + iv, ciphertext, mac = data.split(';') assert len(iv) == 16 * 2 # a hexlified byte is two bytes long, the IV should be 16 bytes assert ( len(ciphertext) % (16 * 2) == 0 @@ -52,9 +52,18 @@ def main(): data = s1f.readline().rstrip('\n') print(f"from s1 to s2: '{data}'") p, g, X = map(int, data.split(',')) + p = int(p) + g = int(g) + X = int(X) + print("p: {} g: {} X: {}".format(p, g, X)) # TODO: get the flag + s2f.write(data) + s2f.flush() + # Receive answer (second step of DH) + data = s2f.readline().rstrip('\n') + print("from s2 to s1: `{}'".format(data)) s1f.close() s2f.close() s1.close() diff --git a/week06/hard/generate_sig_keys.py b/week06/hard/generate_sig_keys.py index 6408687..4d75950 100644 --- a/week06/hard/generate_sig_keys.py +++ b/week06/hard/generate_sig_keys.py @@ -18,6 +18,8 @@ def write_keys(name: str, private_key: str, public_key: str): if __name__ == '__main__': privA, pubA = generate_keys() privB, pubB = generate_keys() + privC, pubC = generate_keys() write_keys('alice', privA, pubA) write_keys('bob', privB, pubB) + write_keys('mitm', privC, pubC) print('Keys generated and written to files') diff --git a/week06/hard/insecurelib.py b/week06/hard/insecurelib.py index d7c3709..dfa9b75 100644 --- a/week06/hard/insecurelib.py +++ b/week06/hard/insecurelib.py @@ -214,12 +214,13 @@ def decrypt(key: bytes, message: str) -> bytes: key_int = key[16:] assert not message.endswith('\n'), 'message should not end with a newline!' - + print("message is: ", message) try: iv, ciphertext, mac = message.split(';') iv = unhexlify(iv) ciphertext = unhexlify(ciphertext) mac = unhexlify(mac) + print(len(mac)) assert len(mac) == 16 except Exception as e: diff --git a/week06/hard/pwn_utils.py b/week06/hard/pwn_utils.py new file mode 100644 index 0000000..a0d1c2f --- /dev/null +++ b/week06/hard/pwn_utils.py @@ -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") diff --git a/week06/hard/test.py b/week06/hard/test.py new file mode 100644 index 0000000..b0511d1 --- /dev/null +++ b/week06/hard/test.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 + +import socket +from Crypto.Cipher import AES +from binascii import hexlify, unhexlify +import random + +from Crypto.PublicKey import ECC +HOST = 'localhost' +PORT1 = 20206 +PORT2 = 20306 + + + +def debug_secure_channel(s1, s2, data): + data = data.rstrip('\n') # remove trailing newline + if len(data) >= 1024: + print("from {} to {}: `{}...'".format(s1, s2, data[:1024])) + else: + print("from {} to {}: `{}'".format(s1, s2, data)) + + iv, ciphertext, mac = data.split(";") + assert (len(iv) == 16 * 2) # a hexlified byte is two bytes long, the IV should be 16 bytes + assert (len(ciphertext) % (16 * 2) == 0) # a hexlified byte is two bytes long, AES block size is 128 bit (16 byte) + assert (len(mac) == 16 * 2) # a quite short MAC. Hint: you still don't want to brute force it! + print("relayed {} encrypted blocks of payload".format(len(unhexlify(ciphertext)) // AES.block_size)) + + +def main(): + s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s1.connect((HOST, PORT1)) + s1f = s1.makefile("rw") # file abstraction for the sockets + + s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s2.connect((HOST, PORT2)) + s2f = s2.makefile("rw") + + # First step of Diffie Hellman (compare slides) + data = s1f.readline() + print("from s1 to s2: '{}'".format(data)) # you should see the newline at the end printed + + p, g, X = data.split(",") + p = int(p) + g = int(g) + X = int(X) + print("p: {} g: {} X: {}".format(p, g, X)) + a = random.randint(1, p-1) + eve_X = pow(g, a, mod=p) + eve_data = f"{p},{g},{eve_X}\n" + # # forward to Bob + s2f.write(eve_data) + s2f.flush() + + # # # Receive answer (second step of DH) + data = s2f.readline() + print("from s2 to s1: '{}'".format(data)) + + # # # Forward received + # s1f.write(data) # the data should still have a b'\n' at the end + # s1f.flush() + + # # # Alice sends something to Bob + # data = s1f.readline() + # print("S1f {}".format(data)) + # debug_secure_channel("Alice", "Bob", data) + + # # # Forward received data to Bob + # s2f.write(data) + # s2f.flush() + # data = s2f.readline() + # debug_secure_channel("Bob", "Alice", data) + # print(f"get data from bob: {data}") + # s1f.write(data) + # s1f.flush() + # data = s1f.readline() + # debug_secure_channel("Bob", "Alice", data) + # print(f"get data from alice: {data}") + # # "alice sending hey bob, plz send me my f14g" + # s2f.write(data) + # s2f.flush() + # data = s1f.readline() + # print(f"get data from alice: {data}") + # s2f.write(data) + # s2f.flush() + # data = s2f.readline() + # print(f"get data from bob :{data}") + # s1f.write(data) + # s1f.flush() + # data = s1f.readline() + # print(f"get data from alice again: {data}") + s1f.close() + s2f.close() + s1.close() + s2.close() + + +if __name__ == "__main__": + main()