-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchallenge35_eve.py
More file actions
129 lines (107 loc) · 3.62 KB
/
challenge35_eve.py
File metadata and controls
129 lines (107 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/usr/bin/env python3
# Implement DH with negotiated groups
# and break with malicious "g" parameters
# server/client modified from https://www.neuralnine.com/tcp-chat-in-python/
'''
to run, start the eve server first, then bob then alice.
then type anything in alice or bob terminals to chat
'''
import threading
import socket
from hashing import sha1
from aes import aes_cbc_decrypt, aes_cbc_encrypt
from padding import pkcs7_pad, pkcs7_unpad
p = 0
shared_key = b''
fake_key = b''
# Connection Data
host = '127.0.0.1'
port = 10000
clientnames = 'AB'
def decrypt(msg, shared_key):
iv = msg[-16:]
pt_padded = aes_cbc_decrypt(msg[:-16], shared_key, iv)
return pkcs7_unpad(pt_padded), iv
def encrypt(msg, shared_key, iv):
pt_padded = pkcs7_pad(msg)
ct = aes_cbc_encrypt(pt_padded, shared_key, iv)
return ct + iv
def relay(message, clientA):
if type(message) is str:
message = message.encode()
for client in clients:
if clientA != client:
client.send(message)
def handle(client):
global p
global shared_key
while True:
try:
# Broadcasting Messages
message = client.recv(1024)
# initiation of dh and encryption
if message[:8] == b"[p, g] =":
print("\U00002705 Received DH parameters...")
msg = message.decode()
p, g = [n.strip(',') for n in msg.split()[3:]]
# When g = 1, pow(g,a,p) = 1
# When g = p, pow(g,a,p) = 0
# when g = p-1, pow(g,a,p) = 1
msg = f"[p, g] = {p}, {p}".encode()
shared_key = sha1('0'.encode()).bytes()[0:16]
# receive other's public key
elif b'B =' in message:
print("\U00002705 received public key B")
msg = message
elif b'A =' in message:
print("\U00002705 received public key A")
msg = "A = " + p
msg = msg.encode()
elif message == b"ACK":
msg = message
elif message == b'':
shutoff(client)
break
else:
pt, iv = decrypt(message, shared_key)
index = clients.index(client)
nickname = nicknames[index]
print(f'\033[32m[Decrypted]\033[0m {nickname} -> {nicknames[(index+1)%2]}: {pt.decode()}')
msg = encrypt(pt, shared_key, iv)
relay(msg, client)
except:
shutoff(client)
break
def shutoff(client):
# Removing And Closing Clients
index = clients.index(client)
clients.remove(client)
client.close()
nickname = nicknames[index]
relay(f'{nickname} left!', client)
nicknames.remove(nickname)
# Receiving / Listening Function
def receive():
while True:
# Accept Connection
client, address = server.accept()
print(f"Connected with {str(address)}")
# Set Nickname
nickname = clientnames[(len(clients) + 1) % 2]
nicknames.append(nickname)
clients.append(client)
# Print And Broadcast Nickname
print(f"Nickname is {nickname}")
relay(f"{nickname} joined!".encode(), nickname)
# Start Handling Thread For Client
thread = threading.Thread(target=handle, args=(client,))
thread.start()
# Starting Server
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen()
# Lists For Clients and Their Nicknames
clients = []
nicknames = []
print(f'Starting server at {host}:{port}')
receive()