import socket
import json
import re
import time
HOST = 'tasks.duckerz.ru'
PORT = 30009
def try_full_message(A_value, label):
"""Отправляет полное сообщение с подмененным A."""
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(15.0)
try:
s.connect((HOST, PORT))
data = b""
while b"Send to Bob:" not in data:
chunk = s.recv(4096)
if not chunk:
break
data += chunk
text = data.decode('utf-8', errors='ignore')
match = re.search(r'\{.*\}', text)
alice = json.loads(match.group())
# Формируем сообщение с подмененным A
if isinstance(A_value, int):
A_str = hex(A_value)
else:
A_str = A_value
payload = json.dumps({
"p": alice['p'],
"g": alice['g'],
"A": A_str
})
s.sendall((payload + "\n").encode())
s.settimeout(10.0)
resp = b""
try:
while True:
chunk = s.recv(4096)
if not chunk:
resp += b"<CLOSED>"
break
resp += chunk
except socket.timeout:
resp += b"<TIMEOUT>"
return f"[{label}] {resp.decode('utf-8', errors='ignore')[:200]}"
except Exception as e:
return f"[{label}] EXCEPTION: {e}"
finally:
s.close()
# Получаем свежие данные
s_temp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s_temp.settimeout(10.0)
s_temp.connect((HOST, PORT))
data = b""
while b"Send to Bob:" not in data:
data += s_temp.recv(4096)
text = data.decode('utf-8', errors='ignore')
match = re.search(r'\{.*\}', text)
alice = json.loads(match.group())
s_temp.close()
p = int(alice['p'], 16)
g = int(alice['g'], 16)
A = int(alice['A'], 16)
print(f"[*] p = {p}")
print(f"[*] g = {g}")
print(f"[*] A = {A}")
# Пробуем подменить A
c = 1337
C = pow(g, c, p) # наш публичный ключ
C_from_A = pow(A, c, p) # перешифрованный ключ
candidates = [
(C, "Наш C = g^c mod p"),
(C_from_A, "C = A^c mod p"),
(A + 1, "A + 1"),
(A * 2, "A * 2"),
(A ^ g, "A XOR g"),
(1, "1"),
(0, "0"),
]
print("\n[*] Пробуем отправить полное сообщение с подмененным A. Пауза 20 сек.\n")
for val, label in candidates:
result = try_full_message(val, label)
print(result)
time.sleep(20)
print("\n[*] Готово.")