Искал на днях мессенджер под Android, имеющий end-to-end-шифрование и маскировку. GPT посоветовал идеального кандидата — некий disguise.chat. Приложение выглядит как обычный калькулятор, но при вводе секретного кода открывается мессенджер. Слепо доверять подобным приложениям я не привык, поэтому решил подробнее изучить его код в дизассемблере.
Приложение написано на Flutter. Java-код приложения интереса не представляет, код приложения хранится в libapp.so. Беглый анализ показал, что схема шифрования просто смехотворна. Так называемый «секретный» ключ от переписки получается из SHA-256-хеша от склеенных вместе идентификаторов общающихся пользователей. Таким образом, владелец серверов может читать любую переписку, независимо от выбранной схемы шифрования.
Для проверки своей гипотезы я попросил GPT-6 собрать минимально рабочий клиент на Python. Через него я проверил регистрацию и отправку\получение сообщений. Криптографическая схема подтвердилась.
Регистрация происходит следующим образом:
POST /api/signup HTTP/1.1Host: api.disguise.chatContent-Type: application/x-www-form-urlencoded; charset=utf-8user_id=alice123&password=EXAMPLE_PASSWORD
Во всех запросах пароль передаётся в открытом виде. Формально общение с сервером происходит по HTTPS, но, естественно, для владельца сайта переписка полностью открыта. Сертификат, разумеется, выдан Let’s Encrypt.
Сам APK подписан сертификатом Android Debug от 14 августа 2026 года. Пакет называется com.example.calculater, а в метаданных фигурирует строка file:///media/bikram/Data/Projects/DisguiseChat/. Домен зарегистрирован 1 июня 2026 года, связанный с ним GitHub-аккаунт mmsanjay096-cloud — 25 июня.
Судя по всему, разработчик из Индии. А его проекту уже полгода!
import sysimport base64import hashlibimport jsonimport secretsimport timefrom datetime import datetime, timezonefrom urllib.parse import urlencodefrom urllib.request import Request, urlopenfrom cryptography.hazmat.primitives.ciphers.aead import AESGCMBASE = "https://api.disguise.chat"USER_ID = "alice123"PASSWORD = "REPLACE_WITH_YOUR_PASSWORD"RECIPIENT_ID = "bob456"MESSAGE = "Привет! Проверка связи."def main(): # Вход: ID и пароль в form-urlencoded. В исследованном протоколе # последующие запросы не используют возвращаемый токен или cookie. login_request = Request( BASE + "/api/login", data=urlencode({"user_id": USER_ID.strip(), "password": PASSWORD}).encode(), method="POST", headers={"Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json"}, ) with urlopen(login_request, timeout=20) as response: login = json.load(response) if login.get("success") is not True: raise RuntimeError("Login rejected") own_id = str(login.get("user_id") or USER_ID).strip().lower() recipient = RECIPIENT_ID.strip().lower() # Реальная формула приложения: ключ зависит только от публичных ID. ids = sorted([own_id, recipient], key=lambda s: s.encode("utf-16-be")) key = hashlib.sha256(("conv-v1:" + ":".join(ids)).encode("utf-8")).digest() message_id = str(time.time_ns() // 1000) nonce = secrets.token_bytes(12) aad = f"{own_id}:{recipient}:{message_id}" encrypted = AESGCM(key).encrypt( nonce, MESSAGE.encode("utf-8"), aad.encode("utf-8") ) envelope = { "message_id": message_id, "from_user_id": own_id, "to_user_id": recipient, "cipher_text": base64.b64encode(encrypted).decode("ascii"), "nonce": base64.b64encode(nonce).decode("ascii"), "aad": aad, "sent_at": datetime.now(timezone.utc).isoformat( timespec="microseconds").replace("+00:00", "Z"), } request = Request( BASE + "/api/messages/send", data=json.dumps(envelope).encode("utf-8"), method="POST", headers={"Content-Type": "application/json", "Accept": "application/json"}, ) with urlopen(request, timeout=20) as response: result = json.load(response) if result.get("success") is False: raise RuntimeError("Message rejected")if __name__ == "__main__": main()
Так выглядит реальная схема отправки сообщения. Комментировать здесь — только портить.
Неясной остаётся только цель этого мероприятия. Я склоняюсь к мнению, что приложение создано разработчиком-одиночкой, охочим до чужих секретов. Учитывая, что приложение позволяет отправлять фото и видео, ситуация обретает пикантный оттенок.
Хотя это и выглядит как Sting-Operation (наподобие нашумевшего An0m из операции «Троянский щит»), кажется, тут обошлось без участия государства.
ссылка на оригинал статьи https://habr.com/ru/articles/1104000/