Как я могу предотвратить сообщения о ложных результатах в глобальных таблицах рекордов?

44

Браузерные и мобильные игры обычно имеют глобальные таблицы рекордов. Обычно в этих таблицах содержатся оценки 2 147 483 647 человек, где люди выяснили вызов веб-службы, который сообщает о результатах, и использовали его для записи фиктивных результатов.

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

Однако это быстро становится невозможным для чего-то большего, чем Pac-Man.

Как еще можно избежать обмана такого рода?

teedyay
источник
У меня был точно такой же вопрос относительно игр для iPhone, использующих ту же технику для создания глобальной таблицы рекордов.
deft_code
Вы уверены, что было бы невозможно отправить повтор?
о0 '.
Да, я уверен. :)
teedyay

Ответы:

9

Внутренняя система, которую мы использовали для Moblox (позже замененная на OpenFeint), работала так:

  • Отправьте сообщение JSON по обычному HTTP (не HTTPS). Включите MD5-хэш всех полей плюс волшебную строку.
  • На сервере проверьте целостность сообщения с помощью той же операции.

Чтобы взломать систему, вам нужно найти эту волшебную строку. Это возможно с реверс-инжинирингом, но больно.

OpenFeint, ScoreLoop и CocosLive используют один и тот же прием, но с HTTPS. Очень легко реализовать.

Эллис
источник
29
Я весьма сомневаюсь, что реверс-инжиниринг, чтобы найти вашу волшебную нить, был бы таким сложным.
Kylotan
4
Это приложение для Android на родном C ++. Нет ни символа, ни хорошего отладчика. Таким образом, вы можете прочитать код ARM, но не легко отследить его. Ключ состоит из нескольких операций, поэтому найти все строки недостаточно. Это не идеально, но довольно больно.
Эллис
3
Стандартное упражнение для студентов, по крайней мере, в университетах США, состоит в том, чтобы перепроектировать пароли, сконструированные, как вы описали, читая код сборки y86 ( cgi2.cs.rpi.edu/~hollingd/comporg-spring2007/notes/Y86/… ).
12
Это ужасно слабая техника, которая даст разработчикам ложное чувство безопасности.
о0 '.
2
Это очень хороший пример en.wikipedia.org/wiki/Security_through_obscurity
kaoD
21

Хотя вы правы в том, что отправка целых повторов на сервер для сложных игр не всегда возможна, аналогичную систему можно использовать, периодически запрашивая у сервера некоторую часть его состояния, а сервер игра запущена

Например, в FPS каждую минуту вы можете спросить «Сколько у вас убийств?», «Где все враги?» И т. Д. Если клиент не возвращается с разумным ответом на вызов в разумное количество времени они обманывают.

Конечно, это работает только в том случае, если игра включена в течение всей игровой сессии. Поскольку цель здесь состоит в том, чтобы иметь возможность загружать данные в онлайн-таблицу лидеров, я думаю, что это разумно - не выгоняйте игрока из игры, если он ответит неправильно, просто не позволяйте ему попадать в список результатов.

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


источник
10

Вы можете ограничить наиболее вопиющие нарушения, отслеживая самые высокие результаты в таблице лучших результатов. В зависимости от вашей игры у вас может быть «идеальный счет», выше которого любой счет должен быть мошенническим. Если нет, вы можете рассчитать наименьшую «невозможную оценку»; может ли игрок сделать 10 выстрелов в секунду, игра длится 1 минуту, и каждый убитый враг приносит 100 очков? Тогда любой результат выше 60 000 должен быть мошенническим.

Вы также можете помочь решить проблему, отправив некоторые метаданные; не полная история игры, как вы описываете, а только компоненты, которые составляют счет. Скажите: наберите 60000, убито 500 врагов и захвачен один бонусный предмет. Затем вы можете выполнить простые проверки. Это «безопасность через неизвестность», и, следовательно, вовсе не безопасная, но она помогает устранить самых наивных атакующих.

Грегори Эйвери-Вейр
источник
Вы также можете пометить пользователя (возможно, по IP), если он отправляет оценку, которая не соответствует метаданным. Затем, если они снова попытаются отправить оценку, которая имеет правильные метаданные, вы можете изучить ее и, возможно, просто запретить их вообще. Вы также можете отправить оттуда дерзкое сообщение и отправить запрос на оценку :)
Адам Харт
Я думаю, что этот ответ лучше, чем принятый ответ. Просто выясните, какое количество является максимальным для ваших игроков. Все, что выше, просто выбросить.
6
Так что, если один игрок, который учится в университете, обманывает, все в сети теперь являются «обманщиком»
AttackingHobo
6

В конечном счете, вы можете исключить только невероятно высокие оценки, потому что остальные (по определению) просто неправдоподобны и, следовательно, могут быть законным (и потрясающим) игроком.

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

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

В конечном счете, кто-то найдет способ сломать это, так что не убивайте себя, пытаясь остановить их.

JasonD
источник
6

Некоторое время назад я добавил таблицу быстрых / грязных рекордов в свой проект, и совсем не разбираясь в интернет-безопасности и т. Д., Это оказалось своего рода недостатком. Удивительно, но с почти 1 200 000 записанных результатов у меня было всего лишь 5 или 6 случаев, когда партии явно неверных результатов достигли вершины доски. Большинство результатов даже больше напоминало сбой в игре, чем настоящий «взлом».

Поэтому я думаю, что важный момент: убедитесь, что система подсчета очков в вашей игре герметична , или, по крайней мере, проведите действительно хорошую проверку выполнимости результатов; Теперь, эта игра, о которой я говорю, была Ludum Dare 48hr, так что это не самая стабильная вещь вокруг ... но в целом я думаю, что чаще всего случайный игрок обнаружит / использует игровой глюк, чем иметь кого-то непосредственно "взломать" таблицу лидеров.

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

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

Да, это оказалось немного долго, но, надеюсь, это поможет ...

Райли Адамс
источник
Конечно, есть. Похоже, соленый хеш - хороший способ. Я не думал, что они отправят один и тот же действительный счет много раз. GUID и временная метка, включенные в пакет (и в хэш), должны быть оплачены - я могу проверить наличие дубликатов на сервере. Спасибо.
teedyay
3

Я не эксперт в этой области, но на вашем месте я постараюсь зашифровать счет ключом, встроенным в ваш код. Этим людям нужно будет применить реверс-инжиниринг над вашим кодом вместо простого текста, используемого для веб-сервисов.


источник
2
Я бы пошел еще дальше. Генерируйте хеш из кода, хэшируя исполняемый файл (или его часть). При отправке результатов отправьте номер версии, и сервер сможет проверить, используя таблицу с простыми константами номер версии -> хеш-код. Затем вы получаете дополнительный бонус: если кто-то изменяет программе, его высокий балл не будет учитываться.
конфигуратор
7
Если кто-то модифицирует программу, он уже может отправить любой ключ по своему усмотрению.
2
@Joe Wreschnig, они могут отправлять любые ключи, но сервер должен быть настроен на прием только действительных ключей.
AttackingHobo
5
Я думаю, что Джо утверждал, что им не нужно использовать хэш недавно измененной программы, а можно просто отправить любой предыдущий хэш.
Kylotan
1
@ gd1: как это поможет?
Kylotan
1

Speedruns в основном записывают каждое нажатие клавиши, и они записывают о ВЕСЬ игре. Так что, да, вы можете записать всю игру, это не невозможно. Любой другой способ сделать это можно взломать с помощью реверс-инжиниринга (не могу не подчеркнуть это: вы не добавляете безопасность, вы добавляете неясность).

Тем не менее, даже если вы сделаете это таким образом, они могли бы на самом деле представить SpeedRun. Вы ничего не можете сделать, чтобы предотвратить это.

о0' .
источник
2
Обычно воспроизведение, а не запись, является частью, недоступной для сервера. Если клиент играл в игру пару часов, переимуляция на стороне сервера может занять много минут процессора или даже хуже. Это не совсем приемлемо, если у вас много людей, отправляющих баллы.
2
Размер пакета данных станет проблемой для мобильных игр, особенно если игрок платит за пропускную способность байта.
teedyay
О, то, что вы оба говорите, правда. Тем не менее, нет другого «реального» решения.
о0 '.
11
Вам не нужно проверять каждую представленную запись, вы просто должны подтвердить те, которые попали в топ-10. Нет смысла обманывать, чтобы стать # 11. И вам не нужно делать это в реальном времени. Периодический пакетный процесс будет в порядке.
серый
@teedyay Скажем, игрок выполняет в среднем 5 действий в секунду, и каждое действие может быть полностью описано в 32 битах. Это 20 байт в секунду или 72 кБ в час. Типичная цена мобильной передачи данных в США составляет 10 долларов США за ГБ или 1 цент за 1000 КБ.
Дамиан Йеррик
1

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

Чтобы отличить хак от игрового эксплойта, было бы неплохо загрузить хотя бы некоторые игровые данные. По крайней мере, это поможет вам исправить подвиги.

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

Ян Шрайбер
источник
1

Сделать все происхождение случайности из одного семени и сохранить входные данные для каждого кадра. Всякий раз, когда у вас заявлен высокий балл (скажем, 50 лучших), отправьте начальное значение и полный ввод на сервер. Переиграйте игру на сервере и обновите таблицу лидеров, если вы получите высокий балл.

Если вы считаете, что это невозможно для более сложных игр из-за размера запроса, посмотрите на этот пример.

Скажем, игра имеет 8 кнопок ввода (1 пэд и 4 кнопки) и работает со скоростью 60 кадров в секунду. Один час игрового ввода может быть передан с 3,6 КБ без сжатия. Ваш сеанс, вероятно, будет длиться менее одного часа, и сжатие должно значительно его уменьшить, потому что вклад человека имеет большую избыточность.

Задача состоит в том, чтобы сделать игру детерминированной, воспроизводимой с записанного ввода и исполняемой на сервере.

Виниций Канаа
источник
0

Никогда не реализовывал это раньше, но ...

Отправить оценки постепенно с отметками времени. Это дает вам журнал, чтобы увидеть, как часто улучшается счет, а также способ отследить «импульс» рекорда.

Затем вы должны установить вехи / критерии для ваших результатов.

Например: счет, превышающий 20 000, не может быть получен в первые 20 секунд игры. Счет, превышающий 250 000, не может быть получен без записи, превышающей 200 000.

Это не то же самое, что отправка игрового состояния, но близко к нему.

Дополнительное преимущество: Подумайте обо всей полезной статистике игрового процесса, которую вы получите из этого. Кто-то, вероятно, заплатит хорошие деньги за это.

Markus
источник