just for now
This commit is contained in:
BIN
week06/easy/__pycache__/pwn_utils.cpython-312.pyc
Normal file
BIN
week06/easy/__pycache__/pwn_utils.cpython-312.pyc
Normal file
Binary file not shown.
@ -1,25 +1,44 @@
|
|||||||
import socket
|
import socket
|
||||||
|
from Crypto.Util.number import getPrime, inverse
|
||||||
|
import re
|
||||||
# Fill in the right target here
|
# Fill in the right target here
|
||||||
HOST = 'this.is.not.a.valid.domain' # TODO
|
HOST = 'netsec.net.in.tum.de' # TODO
|
||||||
PORT = 0 # TODO
|
PORT = 20106 # TODO
|
||||||
|
|
||||||
|
|
||||||
def int_to_bytes(m):
|
def int_to_bytes(m):
|
||||||
return m.to_bytes((m.bit_length() + 7) // 8, 'big').decode()
|
return m.to_bytes((m.bit_length() + 7) // 8, 'big').decode()
|
||||||
|
|
||||||
|
def modular_inverse(p, phi_q):
|
||||||
|
x = inverse(p, phi_q)
|
||||||
|
return x % phi_q
|
||||||
|
|
||||||
|
def decrypt_message(encrypted, p, q):
|
||||||
|
phi_q = q - 1
|
||||||
|
d = modular_inverse(p, phi_q)
|
||||||
|
message = pow(encrypted, d, q)
|
||||||
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_flag():
|
def get_flag():
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
|
||||||
s.connect((HOST, PORT))
|
s.connect((HOST, PORT))
|
||||||
sf = s.makefile('rw') # we use a file abstraction for the sockets
|
sf = s.makefile('rw') # we use a file abstraction for the sockets
|
||||||
|
m = sf.readline().rstrip('\n')
|
||||||
message1 = sf.readline().rstrip('\n')
|
bit_len = int(re.search(r"[0-9]+", m).group())
|
||||||
# TODO
|
print(f"bit_len is {bit_len}")
|
||||||
|
p = getPrime(bit_len*2)
|
||||||
|
q = getPrime(bit_len*2)
|
||||||
|
sf.write(f'{p};{q}\n')
|
||||||
|
sf.flush()
|
||||||
|
c_m = int(sf.readline().rstrip('\n'))
|
||||||
|
print("C_M: ", c_m)
|
||||||
|
d_m = decrypt_message(c_m, p, q)
|
||||||
sf.close()
|
sf.close()
|
||||||
s.close()
|
s.close()
|
||||||
|
print(int_to_bytes(d_m))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
27
week06/easy/pwn_utils.py
Normal file
27
week06/easy/pwn_utils.py
Normal 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")
|
@ -46,18 +46,19 @@ async def handle_client(client_reader: StreamReader, client_writer: StreamWriter
|
|||||||
return
|
return
|
||||||
match resp.split(';'):
|
match resp.split(';'):
|
||||||
case [e, n]:
|
case [e, n]:
|
||||||
if not e.isdigit() or not n.isdigit():
|
if not e.isdigit() or not n.isdigit(): # has to be not
|
||||||
client_writer.write('Invalid input\n'.encode())
|
client_writer.write('Invalid input\n'.encode())
|
||||||
await client_writer.drain()
|
await client_writer.drain()
|
||||||
return
|
return
|
||||||
e, n = int(e), int(n)
|
e, n = int(e), int(n)
|
||||||
if not (no_bits * 2 - 1 <= n.bit_length() <= no_bits * 2):
|
if not (no_bits * 2 - 1 <= n.bit_length() <= no_bits * 2): # has to be not
|
||||||
client_writer.write('Wrong bit count\n'.encode())
|
client_writer.write('Wrong bit count\n'.encode())
|
||||||
await client_writer.drain()
|
await client_writer.drain()
|
||||||
return
|
return
|
||||||
flag = subprocess.check_output('flag').decode().strip()
|
flag = "flaggy"
|
||||||
m = int.from_bytes(flag.encode(), 'big')
|
m = int.from_bytes(flag.encode(), 'big')
|
||||||
c = pow(m, e, n)
|
c = pow(m, e, n)
|
||||||
|
print(c)
|
||||||
client_writer.write(f'{c}\n'.encode())
|
client_writer.write(f'{c}\n'.encode())
|
||||||
case _:
|
case _:
|
||||||
client_writer.write('Invalid input\n'.encode())
|
client_writer.write('Invalid input\n'.encode())
|
||||||
|
36
week06/easy/test.py
Normal file
36
week06/easy/test.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import random
|
||||||
|
from Crypto.Util.number import getPrime, inverse
|
||||||
|
from Crypto.Util.number import inverse
|
||||||
|
|
||||||
|
|
||||||
|
def moc_encryption_message(p, q):
|
||||||
|
message = int.from_bytes("flaggy".encode(), 'big')
|
||||||
|
print("original message: ", message)
|
||||||
|
c = pow(message,p,q)
|
||||||
|
return c
|
||||||
|
|
||||||
|
|
||||||
|
def modular_inverse(p, phi_q):
|
||||||
|
x = inverse(p, phi_q)
|
||||||
|
return x % phi_q
|
||||||
|
|
||||||
|
def decrypt_message(encrypted, p, q):
|
||||||
|
phi_q = q - 1
|
||||||
|
d = modular_inverse(p, phi_q)
|
||||||
|
message = pow(encrypted, d, q)
|
||||||
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
bit_length = 992
|
||||||
|
o = getPrime(bit_length*2)
|
||||||
|
q = getPrime(bit_length*2)
|
||||||
|
e, n = int(o), int(q)
|
||||||
|
if not (bit_length * 2 - 1 <= n.bit_length() <= bit_length * 2): # has to be not
|
||||||
|
print("wrong bit count")
|
||||||
|
c = moc_encryption_message(o, q)
|
||||||
|
m = decrypt_message(c, o, q)
|
||||||
|
print("decrypted message: ", m)
|
||||||
|
byte_length = (m.bit_length() + 7) // 8
|
||||||
|
decoded_string = m.to_bytes(byte_length, 'big').decode()
|
||||||
|
print("Decrypted_message_to_string: ", decoded_string)
|
BIN
week06/hard/__pycache__/insecurelib.cpython-312.pyc
Normal file
BIN
week06/hard/__pycache__/insecurelib.cpython-312.pyc
Normal file
Binary file not shown.
BIN
week06/hard/__pycache__/pwn_utils.cpython-312.pyc
Normal file
BIN
week06/hard/__pycache__/pwn_utils.cpython-312.pyc
Normal file
Binary file not shown.
@ -6,7 +6,30 @@ import logging
|
|||||||
from asyncio import StreamReader, StreamWriter
|
from asyncio import StreamReader, StreamWriter
|
||||||
|
|
||||||
from insecurelib import *
|
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__)
|
log = logging.getLogger(__name__)
|
||||||
clients = {} # task -> (reader, writer)
|
clients = {} # task -> (reader, writer)
|
||||||
@ -73,20 +96,20 @@ class AuthenticatedChannel:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
# calculate shared key
|
# calculate shared key
|
||||||
|
print("calculating key now")
|
||||||
key = str(pow(Y, a, mod=p))
|
key = str(pow(Y, a, mod=p))
|
||||||
key = KDRV256(key.encode())
|
key = KDRV256(key.encode())
|
||||||
|
|
||||||
# decrypt and verify signature
|
# decrypt and verify signature
|
||||||
decrypted_sig = decrypt(key, s)
|
decrypted_sig = decrypt(key, s)
|
||||||
if not verify(bob_public, message=f'{Y},{X}'.encode(), signature=decrypted_sig):
|
if not verify(bob_public, message=f'{Y},{X}'.encode(), signature=decrypted_sig):
|
||||||
self.writer.write('Signature verification failed\n'.encode())
|
self.writer.write('Signature verification failed\n'.encode())
|
||||||
await self.writer.drain()
|
await self.writer.drain()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# sign X and Y and send signature
|
# sign X and Y and send signature
|
||||||
sig = sign(privKey, f'{X},{Y}'.encode())
|
sig = sign(privKey, f'{X},{Y}'.encode())
|
||||||
sig = encrypt(key, sig)
|
sig = encrypt(key, sig)
|
||||||
self.writer.write(sig + b'\n')
|
self.writer.write(sig + b'\n')
|
||||||
|
print("finished the do_STS_key_exchange")
|
||||||
await self.writer.drain()
|
await self.writer.drain()
|
||||||
|
|
||||||
self.shared_key = key
|
self.shared_key = key
|
||||||
@ -111,7 +134,7 @@ async def do_session_key_DH_exchange(channel: AuthenticatedChannel) -> bytes | N
|
|||||||
return
|
return
|
||||||
|
|
||||||
p, g, X = map(int, pgX.split(','))
|
p, g, X = map(int, pgX.split(','))
|
||||||
|
print("p, g, x is here: ", (p,g,X))
|
||||||
# two checks to prevent DOSes and improve performance
|
# two checks to prevent DOSes and improve performance
|
||||||
if not check_int_range(p):
|
if not check_int_range(p):
|
||||||
await channel.send_encrypted(f'{p} must be in [{0}..{MAX_PRIME}]'.encode())
|
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):
|
if not check_int_range(g):
|
||||||
await channel.send_encrypted(f'{g} must be in [{0}..{MAX_PRIME}]'.encode())
|
await channel.send_encrypted(f'{g} must be in [{0}..{MAX_PRIME}]'.encode())
|
||||||
return
|
return
|
||||||
|
print("two checks to prevent doses and improve performance finished")
|
||||||
# check if parameters are valid
|
# check if parameters are valid
|
||||||
if not is_prime(p):
|
if not is_prime(p):
|
||||||
await channel.send_encrypted(f'{p} is not a prime number!'.encode())
|
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:
|
if X >= p:
|
||||||
await channel.send_encrypted(f"X ({X} can't be larger or equal to p {p}!".encode())
|
await channel.send_encrypted(f"X ({X} can't be larger or equal to p {p}!".encode())
|
||||||
return
|
return
|
||||||
|
print("check if parameters are valid finished")
|
||||||
# create own public/private key parts:
|
# create own public/private key parts:
|
||||||
b = random.randint(1, p - 1)
|
b = random.randint(1, p - 1)
|
||||||
Y = pow(g, b, mod=p)
|
Y = pow(g, b, mod=p)
|
||||||
|
print("sending encryption")
|
||||||
await channel.send_encrypted(f'{Y}'.encode())
|
await channel.send_encrypted(f'{Y}'.encode())
|
||||||
|
print("sending encyrption finished")
|
||||||
# calculate shared key
|
# calculate shared key
|
||||||
key = str(pow(X, b, mod=p))
|
key = str(pow(X, b, mod=p))
|
||||||
key = KDRV256(key.encode())
|
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 :-)'
|
msg = 'Hey Bob, plz send me my f14g :-)'
|
||||||
encrypted_msg = encrypt(session_key, msg.encode())
|
encrypted_msg = encrypt(session_key, msg.encode())
|
||||||
|
print("sending encypretd message about igving me flag")
|
||||||
await authenticated_channel.send_encrypted(encrypted_msg)
|
await authenticated_channel.send_encrypted(encrypted_msg)
|
||||||
|
|
||||||
data = await authenticated_channel.recv_encrypted()
|
data = await authenticated_channel.recv_encrypted()
|
||||||
|
3
week06/hard/alice_private.pem
Normal file
3
week06/hard/alice_private.pem
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MC4CAQAwBQYDK2VwBCIEIEeMyeJI/JBSKPBQVfaOY/T6Ew9fH5JwVrievvcX85V7
|
||||||
|
-----END PRIVATE KEY-----
|
3
week06/hard/alice_public.pem
Normal file
3
week06/hard/alice_public.pem
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MCowBQYDK2VwAyEAcn6Y7i8GkW0KvMTIaPWj+axVBY29ki2bdAmxza2X6EU=
|
||||||
|
-----END PUBLIC KEY-----
|
@ -8,7 +8,31 @@ import random
|
|||||||
from asyncio import StreamReader, StreamWriter
|
from asyncio import StreamReader, StreamWriter
|
||||||
|
|
||||||
from insecurelib import *
|
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__)
|
log = logging.getLogger(__name__)
|
||||||
clients = {} # task -> (reader, writer)
|
clients = {} # task -> (reader, writer)
|
||||||
@ -51,16 +75,16 @@ class AuthenticatedChannel:
|
|||||||
async def do_STS_key_exchange(self):
|
async def do_STS_key_exchange(self):
|
||||||
# receive p,q and public keypart to other server (over the client) and wait for response
|
# receive p,q and public keypart to other server (over the client) and wait for response
|
||||||
pgX = await read_line_safe(self.reader)
|
pgX = await read_line_safe(self.reader)
|
||||||
|
|
||||||
if pgX is None:
|
if pgX is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
if pgX.count(',') != 2:
|
if pgX.count(',') != 2:
|
||||||
self.writer.write('Invalid amount of arguments (expected 3; p,g,X)\n'.encode())
|
self.writer.write('Invalid amount of arguments (expected 3; p,g,X)\n'.encode())
|
||||||
await self.writer.drain()
|
await self.writer.drain()
|
||||||
return
|
return
|
||||||
|
|
||||||
p, g, X = map(int, pgX.split(','))
|
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
|
# 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
|
# send p,q and public keypart
|
||||||
pgX = f'{p},{g},{X}'
|
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()
|
Y = await channel.recv_encrypted()
|
||||||
log.info(f'received "{Y}" as Y (public key)')
|
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
|
# calculate shared key
|
||||||
key = str(pow(Y, a, mod=p))
|
key = str(pow(Y, a, mod=p))
|
||||||
key = KDRV256(key.encode())
|
key = KDRV256(key.encode())
|
||||||
|
print("do seession dh is finished")
|
||||||
return key
|
return key
|
||||||
|
|
||||||
|
|
||||||
@ -140,9 +164,9 @@ async def handle_client(client_reader: StreamReader, client_writer: StreamWriter
|
|||||||
|
|
||||||
# do session key DH exchange
|
# do session key DH exchange
|
||||||
session_key = await do_session_key_DH_exchange(authenticated_channel)
|
session_key = await do_session_key_DH_exchange(authenticated_channel)
|
||||||
|
print("session key obtained")
|
||||||
message = await authenticated_channel.recv_encrypted()
|
message = await authenticated_channel.recv_encrypted()
|
||||||
|
print("message received for last: ", message)
|
||||||
if message is None:
|
if message is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -155,7 +179,7 @@ async def handle_client(client_reader: StreamReader, client_writer: StreamWriter
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
flag = subprocess.check_output('flag')
|
flag = "flaggy".encode()
|
||||||
encrypted_flag = encrypt(session_key, flag)
|
encrypted_flag = encrypt(session_key, flag)
|
||||||
await authenticated_channel.send_encrypted(encrypted_flag)
|
await authenticated_channel.send_encrypted(encrypted_flag)
|
||||||
|
|
||||||
|
3
week06/hard/bob_private.pem
Normal file
3
week06/hard/bob_private.pem
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MC4CAQAwBQYDK2VwBCIEIBT9LU2Gd571saJkzcQzxwdfmejkLeKjsJy1WhVOjxY2
|
||||||
|
-----END PRIVATE KEY-----
|
3
week06/hard/bob_public.pem
Normal file
3
week06/hard/bob_public.pem
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MCowBQYDK2VwAyEAeI+vbbnxM+olxPgHiYZUuvOFM6WpWBt7CvNuLSioCxQ=
|
||||||
|
-----END PUBLIC KEY-----
|
@ -7,9 +7,9 @@ import socket
|
|||||||
from insecurelib import KDRV256, HMAC, encrypt, decrypt
|
from insecurelib import KDRV256, HMAC, encrypt, decrypt
|
||||||
|
|
||||||
# Fill in the right target here
|
# Fill in the right target here
|
||||||
HOST = 'this.is.not.a.valid.domain' # TODO
|
HOST = 'netsec.net.in.tum.de'
|
||||||
PORT1 = 20008
|
PORT1 = 20206
|
||||||
PORT2 = 20108
|
PORT2 = 20306
|
||||||
|
|
||||||
|
|
||||||
# note the numbers you encounter may be small for demonstration purposes.
|
# note the numbers you encounter may be small for demonstration purposes.
|
||||||
@ -25,7 +25,7 @@ def debug_secure_channel(s1, s2, data: str):
|
|||||||
else:
|
else:
|
||||||
print(f"from {s1} to {s2}: '{data}...'")
|
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(iv) == 16 * 2 # a hexlified byte is two bytes long, the IV should be 16 bytes
|
||||||
assert (
|
assert (
|
||||||
len(ciphertext) % (16 * 2) == 0
|
len(ciphertext) % (16 * 2) == 0
|
||||||
@ -52,9 +52,18 @@ def main():
|
|||||||
data = s1f.readline().rstrip('\n')
|
data = s1f.readline().rstrip('\n')
|
||||||
print(f"from s1 to s2: '{data}'")
|
print(f"from s1 to s2: '{data}'")
|
||||||
p, g, X = map(int, data.split(','))
|
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
|
# 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()
|
s1f.close()
|
||||||
s2f.close()
|
s2f.close()
|
||||||
s1.close()
|
s1.close()
|
||||||
|
@ -18,6 +18,8 @@ def write_keys(name: str, private_key: str, public_key: str):
|
|||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
privA, pubA = generate_keys()
|
privA, pubA = generate_keys()
|
||||||
privB, pubB = generate_keys()
|
privB, pubB = generate_keys()
|
||||||
|
privC, pubC = generate_keys()
|
||||||
write_keys('alice', privA, pubA)
|
write_keys('alice', privA, pubA)
|
||||||
write_keys('bob', privB, pubB)
|
write_keys('bob', privB, pubB)
|
||||||
|
write_keys('mitm', privC, pubC)
|
||||||
print('Keys generated and written to files')
|
print('Keys generated and written to files')
|
||||||
|
@ -214,12 +214,13 @@ def decrypt(key: bytes, message: str) -> bytes:
|
|||||||
key_int = key[16:]
|
key_int = key[16:]
|
||||||
|
|
||||||
assert not message.endswith('\n'), 'message should not end with a newline!'
|
assert not message.endswith('\n'), 'message should not end with a newline!'
|
||||||
|
print("message is: ", message)
|
||||||
try:
|
try:
|
||||||
iv, ciphertext, mac = message.split(';')
|
iv, ciphertext, mac = message.split(';')
|
||||||
iv = unhexlify(iv)
|
iv = unhexlify(iv)
|
||||||
ciphertext = unhexlify(ciphertext)
|
ciphertext = unhexlify(ciphertext)
|
||||||
mac = unhexlify(mac)
|
mac = unhexlify(mac)
|
||||||
|
print(len(mac))
|
||||||
assert len(mac) == 16
|
assert len(mac) == 16
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
27
week06/hard/pwn_utils.py
Normal file
27
week06/hard/pwn_utils.py
Normal 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")
|
98
week06/hard/test.py
Normal file
98
week06/hard/test.py
Normal file
@ -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()
|
Reference in New Issue
Block a user