Как стать автором
Обновить

Комментарии 17

Как-то совсем простенько.
Ожидал увидеть криптографический ад или хотя бы сжатие данных, которое сбило бы всех с толку. Сейчас вроде уже нечасто встречаются приложения/игры без шифрования трафика?
Так же ожидал увидеть заворачивание трафика на свой MITM, чтобы трафик расшифровывать… Но если нет шифрования, то и свой MITM не нужен…
Может быть стоило добавить свой диссектор для wireshark?
А в мобильных играх с постоянным обменом данных уже используют шифрование? Мне кажется это бы слишком сказалось на производительности…

Шифрование здесь только SSL на этапе получения информации о серверах для подключения, что будет описано в последней части.

Как по мне, сделать свой инструмент намного удобнее (часть 2), чем писать диссектор.
Используют. Сколько раз не заглядывал в трафик — почти всегда видел байты с энтропией под 100%. Но случалось и много нулей подряд видеть, — тогда делался mitm + замена нужных байтиков (например вместо поражения в бою отправить победу).

Хотя бы минимально добавить XOR уже отобьёт 99% желающих попортить трафик и совершенно не скажется на производительности (ну если не совсем в лоб сделать). SSL обычно снимается в mitmproxy + ssl kill switch на устройстве, он в принципе интереса не представляет.
Кроме того частой практикой является добавлять контрольную сумму к каждому пакету, но возможно в мобильных приложениях это действительно применяется реже.

Свой инструмент — это хорошо, но и диссектор для wireshark тоже интересно. По уму свой инструмент можно научить использовать диссектор wireshark, — прибить двух зайцев одним махом. Посмотрим, что будет во второй части.
В последней части предполагается, что пользователь далек от всего вот этого вот и у него нет «особого» доступа к устройству (т.е. без Jailbreak-а или root-а), а значит ssl kill switch уже не катит.
Ну это всё полумеры и от слишком люботыного и умного спасёт плохо. Достаточно одного человека, который расковыряет шифрование на стороне клиента и сможет в поток впихнуть свои данные, а дальше это пойдёт гулять.
Из вариантов вижу только античит by design на стороне сервера, который проверяет корректность приходящих от пользователя команд управления. Всё формируется на сервере, а пользователю отправляется уже результат действий. Конечно, в определённых рамках применимо. Т.к., например, я слабо представляю, как можно озвученное мной выше применить к шутеру.
Но посыл, в общем-то, всё равно остаётся. Нельзя довчерять данным, пришедшим от пользователя. Не важно, шифрованными они шли, или плэинтекстом, т.к. ничто не мешает особо умным вмешиваться не в сам поток трафика, а мождифицировать сам клиент, например.
Другое дело, что разработка серверной части усложняется. Но это уже на совести разработчка.
Да, разумеется так и должно быть, мне всегда казалось это настолько очевидным, что нет нужды говорить об этом (хотя мне встречалась игра, которая всё хранила на клиенте и пересылала на сервер целиком, т.е. сообщения были не «подобрал голду, добавилось 100 голды», а «подобрал голду, теперь у меня её 10000», там были какие-то проверки на сервере, но не очень жёсткие). Но то что вы говорите — не отменяет шифрование. Даже если вы всё проверяете на сервере, — вы не защищены таким образом от ботов.

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

Да, это, пожалуй, разумный довод, чтобы ботоводство не цвело сильно.

Внутренности пакетов подозрительно напоминают формат protobuf — https://developers.google.com/protocol-buffers/docs/encoding. 0x08 обозначает "поле с идентификатором 1 типа varint", дальше следует собственно varint, как вы его расшифровали. Потом следующее поле, и следующее и т.д.

А ведь не додумался погуглить это, хотя даже не знаю какими ключевыми словами искал бы. Спасибо большое! При возможности обновлю статью с указанием этого.
habr.com/ru/post/321790
Вот сюда загляните, сильно упростит жизнь. Через protodec сразу получите .proto файл, поправите имена полей для читабельности, подключите библиотеку protobuf к своему приложению и жизнь станет прекрасна.

Обновлять статью скорее всего смысла нет, — тут половину статьи менять придётся. Вы говорили про вторую часть, — оно туда отлично подойдёт.

Я тоже делал подобное с Clash Royale, но только тогда было где подсмотреть и скопировать, но много пакетов доводилось разбирать самому. Там было шифрование (libsodium), во время игры соединение вообще перебрасывались на UDP, но использовался обычный TCP, если первый не смог. А чтобы подключится, вообще надо было изменить APK игры (подсунуть свой адрес сервера, который кстати должен быть фиксированной длины и свой публичный ключ). Потом они изменили протокол (номера пакетов) и шифрование и уже не хотелось продолжать работу над проектом.
Вообще, против ботов легко бороться — ввести так называемую "чексумму", которая может быть посчитана как на сервере, так и на клиенте, клиент должен отсылать её серверу, если не совпадает — гнать клиента подальше.

Если бы всё так легко было… Ничто же не заставляет хакнутый клиент считать контрольную сумму хакнутого клиента — он может исполнять одни файлы, а контрольные суммы считать от оригинальных.

Контрольная сумма, зависящая от состояния мира. Я говорю про бот, поэтому там будет не хакнутый клиент, а просто свой клиент. Найти алгоритм подсчёта чексуммы в бинарнике (особенно с обфусцированными символами) не так просто, как кажется (например если мы заюзаем в чексумме детерминированный рандом, синхронизированный с сервером во время соединения, время с начала игры, ещё взять туда позиции игроков и всё это приправить ксором). Конечно, можно вытянуть это из бинаря, но на это уйдет немалое количество времени и сил, при этом ничего не мешает разработчикам изменить этот алгоритм на сервере и обновить клиент.

Когда я ботами баловался, я никогда не писал полностью свою реализацию клиента. Клиент у меня всегда работал оригинальный, а я его просто патчил, чтобы перехватывать пакеты и от сервера и отправлять свои пакеты в ответ. Любые проверки достоверности симуляции всегда выполнялись оригинальным кодом, а чтобы нельзя было обнаружить внедрение, я перехватывал OpenFile и ещё несколько функций заинжекченной dll, и если игра пыталась открывать свои собственные исполнимые файлы, путь подменялся на каталог с оригиналами, т.е. защита думала, что все файлы в порядке.

Защита от этого есть — сервер должен искать запущенные процессы, проверять таблицу распределения памяти и искать несоответствия, но самое важное, что код для этих проверок должен приходить во время каждой сессии с сервера, и он должен периодически меняться. Это всё постоянная работа команды безопасности, и понятно, что этот подход оправдан, только если вред от хакерства в игре больше зарплаты этих людей, что только в больших проектах происходит.

А если игра на Android? Патчить тоже не все умеют. И в чем смысл такого подхода? Например, я попробую открыть сундук. Чексумму мне взять неоткуда, и даже если смогу достать, то клиент не будет знать, что он открывает.

Не знаю, я только на Винде это делал. Если я пытаюсь открыть сундук, я найду код в игре, который команду формирует, и вызову его. Нехай сам считает, какие там контрольные суммы куда надо.

Вообще, в Clash Royale было две контрольные суммы:


  • контрольная сумма от клиента во время любых действий в меню (открыть сундук, купить что-то в магазине и т.д.), не представляет проблем при разработке кастомного сервера. Отбивает желание делать кастомный клиент сразу (хотя её потом научились считать и делать ботов. Многих, кто их попробовал заюзать — перебанили).
  • контрольная сумма от сервера во время игры. Вообще, во время игры сервер и клиент обмениваются только действиями (только поставить такой юнит в такой позиции, ещё смайлики). Там просто детерминированный локстеп. При этом сервер должен прикрепить чексумму игрового состояния (а там количество живих юнитов, их хп, позиции и это приправлено вроде crc32). Если она не совпала, то клиент останавливает игру и запрашивает у сервера полное состояние игры (в продакшене замечал такое только тогда, когда было плохое соединение, или оно пропадало на несколько секунд).
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории