6.6 KiB
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
.
Подготовка на стороне клиента (перед отправкой):
- Обмен ключами и вычисление секрета:
- Клиент использует статичный публичный ключ сервера (
server_public_key
), заранее известный из анализа Frida-скрипта. - Клиент генерирует свою временную пару ключей (
client_public_key
иclient_private_key
). - Клиент вычисляет общий секрет (
s
) с помощью ECDH. Этотs
используется только для шифрования/расшифровкиLoginMessage
иLoginOk
.
- Клиент использует статичный публичный ключ сервера (
- Формирование Payload:
- Клиент генерирует свой собственный
RNonce
(24 байта). - Внутренние данные (
LoginData
) формируются вByteStream
. Они включают в себя ID аккаунта (0-1 для нового), версию клиента (47.365.2
) и множество полей с информацией об устройстве, включая валидные по формату идентификаторы (UUID, HEX-строки). - Payload для шифрования собирается как
RNonce
+LoginData
.
- Клиент генерирует свой собственный
- Шифрование:
- Ключ: Используется
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
).