2025-06-21 14:32:54 +03:00

6.6 KiB
Raw Blame History

BS-Dec-Key: Анализ и Реализация Клиента

Этот документ предоставляет детальное техническое описание процесса подключения к серверу, который является модифицированной версией Project Colette V53, использующей криптографическую схему от BSL-V53. Здесь разбирается финальная, рабочая версия handshake, структура пакетов и логика обмена сообщениями.

[*] Основные Концепции

Протокол обмена данными является кастомным, поверх стандартного TCP. Шифрование построено на базе криптографической библиотеки NaCl и использует смешанную, нестандартную схему.

  • Асимметричное шифрование: Curve25519 для вычисления общего секрета по алгоритму Диффи-Хеллмана (ECDH).
  • Симметричное шифрование: XSalsa20-Poly1305 для шифрования сообщений после вычисления общего секрета.
  • Порядок пакетов: В отличие от многих протоколов, здесь порядок не ClientHello -> ServerHello -> LoginMessage, а ClientHello -> LoginMessage -> ServerHello -> LoginOk.

[!] Пошаговый Разбор Процесса Подключения

Процесс подключения от инициации до полного установления зашифрованной сессии включает в себя обмен четырьмя ключевыми пакетами в специфическом порядке.


Шаг 1: ClientHello (ID: 10100)

  • Направление: Клиент -> Сервер
  • Шифрование: Отсутствует

Это самый первый пакет, который клиент отправляет после установки TCP-соединения. Его структура критически важна и должна точно соответствовать ожиданиям сервера (6 целочисленных полей и пустая строка), иначе сервер просто разорвет соединение.


Шаг 2: LoginMessage (ID: 10101)

  • Направление: Клиент -> Сервер
  • Шифрование: Симметричное (SecretBox), но с ключом, полученным асимметрично.

Это ключевой и самый сложный пакет, который отправляется до получения ServerHello.

Подготовка на стороне клиента (перед отправкой):

  1. Обмен ключами и вычисление секрета:
    • Клиент использует статичный публичный ключ сервера (server_public_key), заранее известный из анализа Frida-скрипта.
    • Клиент генерирует свою временную пару ключей (client_public_key и client_private_key).
    • Клиент вычисляет общий секрет (s) с помощью ECDH. Этот s используется только для шифрования/расшифровки LoginMessage и LoginOk.
  2. Формирование Payload:
    • Клиент генерирует свой собственный RNonce (24 байта).
    • Внутренние данные (LoginData) формируются в ByteStream. Они включают в себя ID аккаунта (0-1 для нового), версию клиента (47.365.2) и множество полей с информацией об устройстве, включая валидные по формату идентификаторы (UUID, HEX-строки).
    • Payload для шифрования собирается как RNonce + LoginData.
  3. Шифрование:
    • Ключ: Используется s, вычисленный на шаге 1.
    • Nonce: Вычисляется как hash(client_pk + server_pk).
    • Процесс: (RNonce + LoginData) шифруется с помощью SecretBox(s).encrypt(...).

Структура и отправка пакета:

Финальный пакет 10101 состоит из:

  • Публичный ключ клиента (32 байта, в открытом виде).
  • Зашифрованная полезная нагрузка.

Шаг 3: ServerHello (ID: 20100)

  • Направление: Сервер -> Клиент
  • Шифрование: Отсутствует

Получив и успешно расшифровав LoginMessage, сервер присылает этот пакет в открытом виде. Он содержит серверный Nonce (SNonce), который будет использоваться для дальнейшей связи.


Шаг 4: LoginOk (ID: 20104)

  • Направление: Сервер -> Клиент
  • Шифрование: Симметричное (SecretBox)

Это финальное подтверждение от сервера.

  • Ключ: Сервер использует тот же самый s, который он вычислил ранее.
  • Nonce: Сервер вычисляет nonce как hash(RNonce + client_pk + server_pk).
  • Содержимое: Внутри расшифрованного пакета находится второй, настоящий ключ сессии (session_key), который будет использоваться для шифрования всех последующих сообщений (кроме handshake).

Успешная расшифровка этого пакета означает, что аккаунт создан и сессия полностью установлена. Разрыв соединения сервером сразу после отправки LoginOk является нормальным поведением для простого тестового клиента, который не продолжает общение (например, не шлет KeepAlive).