Загрузка данных


import socket
import json
import re

HOST = 'tasks.duckerz.ru'
PORT = 30009

def solve_math(expr):
    """Решает математическое выражение вида '123 + 456' или '123*456'."""
    expr = expr.replace(' ', '')
    match = re.match(r'^(\d+)([\+\-\*\/])(\d+)$', expr)
    if not match:
        return None
    a, op, b = match.groups()
    a, b = int(a), int(b)
    if op == '+': return a + b
    if op == '-': return a - b
    if op == '*': return a * b
    if op == '/': return a // b
    return None

def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))
    
    # 1. Получаем первое сообщение (от Алисы)
    data = s.recv(4096).decode('utf-8').strip()
    print(f"[*] Получено от Алисы: {data}")
    
    json_match = re.search(r'\{.*\}', data)
    if not json_match:
        print("[-] Не удалось найти JSON в сообщении")
        return
        
    alice_data = json.loads(json_match.group())
    p = int(alice_data['p'], 16)
    g = int(alice_data['g'], 16)
    A = int(alice_data['A'], 16)
    
    print(f"[*] p = {p}")
    print(f"[*] g = {g}")
    print(f"[*] A (Alice) = {A}")
    
    # 2. Генерируем свой ключ
    c = 1337 
    C = pow(g, c, p)
    
    # 3. Отправляем Бобу наш ключ (в формате JSON с десятичным числом)
    payload = json.dumps({"C": C})
    print(f"[*] Отправляем Бобу наш ключ: {payload}")
    s.sendall((payload + "\n").encode())
    
    # 4. Получаем ответ от Боба
    data2 = s.recv(4096).decode('utf-8').strip()
    print(f"[*] Получено от Боба: {data2}")
    
    # Пытаемся найти публичный ключ Боба (hex или десятичное число)
    hex_match = re.search(r'0x[0-9a-fA-F]+', data2)
    if hex_match:
        B = int(hex_match.group(), 16)
    else:
        num_match = re.search(r'\d+', data2)
        if num_match:
            B = int(num_match.group())
        else:
            print("[-] Не удалось найти публичный ключ Боба")
            return
    
    print(f"[*] B (Bob) = {B}")
    
    # 5. Вычисляем общий секрет с Бобом
    S_bob = pow(B, c, p)
    print(f"[*] Общий секрет S_bob = {S_bob}")
    
    # 6. Отправляем Алисе наш ключ (подменяем Боба)
    payload_alice = json.dumps({"C": C})
    print(f"[*] Отправляем Алисе наш ключ: {payload_alice}")
    s.sendall((payload_alice + "\n").encode())
    
    # 7. Цикл обмена зашифрованными сообщениями
    s.settimeout(3.0)
    while True:
        try:
            data3 = s.recv(4096).decode('utf-8').strip()
            if not data3:
                break
            print(f"[*] Получено: {data3}")
            
            # Проверяем, не флаг ли это в открытом виде
            if "DUCKERZ{" in data3:
                print(f"\n[!!!] ФЛАГ НАЙДЕН: {data3}\n")
                break
            
            # Пытаемся найти зашифрованное выражение (hex)
            hex_match = re.search(r'0x[0-9a-fA-F]+', data3)
            if hex_match:
                encrypted_hex = hex_match.group()
                encrypted_int = int(encrypted_hex, 16)
                
                # Расшифровка XOR с секретом
                decrypted_int = encrypted_int ^ S_bob
                
                try:
                    decrypted_str = decrypted_int.to_bytes((decrypted_int.bit_length() + 7) // 8, 'big').decode('utf-8')
                    print(f"[*] Расшифровано: {decrypted_str}")
                    
                    if "DUCKERZ{" in decrypted_str:
                        print(f"\n[!!!] ФЛАГ НАЙДЕН: {decrypted_str}\n")
                        break
                    
                    # Если это математическое выражение
                    if re.search(r'\d+[\+\-\*\/]\d+', decrypted_str):
                        result = solve_math(decrypted_str)
                        if result is not None:
                            print(f"[*] Решаем: {decrypted_str} = {result}")
                            enc_result = result ^ S_bob
                            # Отправляем ответ (пробуем hex)
                            s.sendall((hex(enc_result) + "\n").encode())
                            print(f"[*] Отправлен ответ: {hex(enc_result)}")
                            
                except Exception as e:
                    print(f"[-] Ошибка расшифровки: {e}")
                    # Если XOR не сработал, пробуем сложение/вычитание
                    try:
                        decrypted_int = encrypted_int - S_bob
                        decrypted_str = decrypted_int.to_bytes((decrypted_int.bit_length() + 7) // 8, 'big').decode('utf-8')
                        print(f"[*] Расшифровано (вычитание): {decrypted_str}")
                    except:
                        pass
                
        except socket.timeout:
            print("[-] Таймаут. Сервер не отвечает.")
            break
        except Exception as e:
            print(f"[-] Ошибка: {e}")
            break

if __name__ == '__main__':
    main()