Как лучше всего остановить людей, которые взламывают таблицу рекордов Flash-игры на основе PHP?

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

Что мне действительно нужно, так это самое надежное шифрование, возможное во Flash / PHP, и способ не допустить, чтобы люди вызывали страницу PHP, кроме как через мой файл Flash. В прошлом я пробовал несколько простых методов выполнения нескольких вызовов для одной оценки и выполнения последовательности контрольной суммы / фибоначчи и т. д., А также обфускации SWF с помощью Amayeta SWF Encrypt, но в конечном итоге все они были взломаны.

Благодаря ответам StackOverflow я теперь нашел дополнительную информацию от Adobe - http://www.adobe.com/devnet/flashplayer/articles/secure_swf_apps_12.html и https://github.com/mikechambers/as3corelib, - которую, как мне кажется, я могу использовать для шифрования. Не уверен, что это поможет мне освоить CheatEngine.

Мне нужно знать лучшие решения для AS2 и AS3, если они разные.

Основными проблемами кажутся такие вещи, как заголовки TamperData и LiveHTTP, но я понимаю, что есть и более продвинутые инструменты взлома, такие как CheatEngine (спасибо Mark Webster)

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

mpm 07.03.2012 01:01

Первая ссылка больше не доступна

Mike 15.09.2012 00:32
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
213
2
29 280
17

Ответы 17

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

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

Это метод, который я использовал в прошлом для системы голосования. Невозможно предотвратить обман людей, однако вы можете записывать их поведение, чтобы вы могли проверить, есть ли обман. Для нашей системы голосования мы использовали для хранения отметок времени и IP-адресов. [продолжение]

Luke 06.01.2009 00:10

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

Luke 06.01.2009 00:11

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

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

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

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

Возможно, стоит разработать скаляр, чтобы узнать, каков максимальный счет за секунду / минуту игры.

Ни одну из этих вещей нельзя избежать, но будет полезно иметь некоторую логику не во Flash, где люди могут ее видеть.

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

Tom Ritter 16.09.2008 20:13

Всякий раз, когда ваша система рекордов основана на том факте, что приложение Flash отправляет незашифрованные / неподписанные данные рекордов через сеть, их можно перехватить и обработать / воспроизвести. Ответ следует из этого: зашифровать (прилично!) Или криптографически подписать данные рекордов. Это, по крайней мере, затрудняет взлом вашей системы рекордов, потому что им нужно будет извлечь секретный ключ из вашего SWF-файла. Многие люди, вероятно, сразу же сдадутся. С другой стороны, достаточно одного человека, чтобы извлечь ключ и куда-нибудь отправить его.

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

Невозможно сделать его полностью защищенным от взлома, поскольку SWF-файлы легко декомпилировать, и опытный хакер-разработчик может затем проследить ваш код и решить, как обойти любую зашифрованную систему, которую вы можете использовать.

Если вы просто хотите остановить обман детей с помощью простых инструментов, таких как TamperData, вы можете сгенерировать ключ шифрования, который вы передадите в SWF при запуске. Затем используйте что-то вроде http://code.google.com/p/as3crypto/, чтобы зашифровать высокий балл, прежде чем передавать его обратно в код PHP. Затем расшифруйте его на стороне сервера перед сохранением в базе данных.

На самом деле невозможно достичь того, чего вы хотите. Внутреннее устройство Flash-приложения всегда частично доступно, особенно когда вы знаете, как использовать такие вещи, как CheatEngine, а это означает, что независимо от того, насколько безопасны ваш веб-сайт и связь с сервером <-> в браузере, это все равно будет относительно просто преодолеть.

Легкий способ сделать это - предоставить криптографический хэш вашего рекорда вместе с самим счетом. Например, при публикации результатов через HTTP GET: http://example.com/highscores.php?score=500&checksum=0a16df3dc0301a36a34f9065c3ff8095

При вычислении этой контрольной суммы следует использовать общий секрет; этот секрет никогда не должен передаваться по сети, но должен быть жестко закодирован как в бэкэнде PHP, так и во флеш-интерфейсе. Контрольная сумма, приведенная выше, была создана путем добавления строки «секрет» к счету «500» и ее прогона через md5sum.

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

Чтобы предотвратить повторные атаки любой, необходимо будет создать систему типа запрос-ответ, например следующую:

  1. Флэш-игра («клиент») выполняет HTTP GET http://example.com/highscores.php без параметров. Эта страница возвращает два значения: случайно сгенерированное значение соль и криптографический хэш этого значения соли в сочетании с общим секретом. Это значение соли должно храниться в локальной базе данных ожидающих запросов и иметь связанную с ним временную метку, чтобы срок его действия мог «истечь» примерно через одну минуту.
  2. Флэш-игра объединяет значение соли с общим секретом и вычисляет хэш, чтобы убедиться, что он соответствует хеш-функции, предоставленной сервером. Этот шаг необходим для предотвращения подделки значений соли пользователями, поскольку он проверяет, действительно ли значение соли было сгенерировано сервером.
  3. Флеш-игра объединяет значение соли с общим секретом, значением рекорда и любой другой важной информацией (псевдоним, IP-адрес, временная метка) и вычисляет хэш. Затем он отправляет эту информацию обратно в серверную часть PHP через HTTP GET или POST вместе со значением соли, высоким баллом и другой информацией.
  4. Сервер объединяет полученную информацию так же, как и на клиенте, и вычисляет хэш, чтобы убедиться, что он соответствует хеш-функции, предоставленной клиентом. Затем он также проверяет, действительно ли значение соли по-прежнему актуально, как указано в списке ожидающих запросов. Если оба эти условия верны, он записывает высокий балл в таблицу рекордов и возвращает клиенту подписанное «успешное» сообщение. Он также удаляет значение соли из списка ожидающих запросов.

Имейте в виду, что безопасность любого из вышеперечисленных методов будет поставлена ​​под угрозу, если общий секрет будет когда-либо доступен пользователю.

В качестве альтернативы, некоторых из этих возвратов можно избежать, заставив клиента взаимодействовать с сервером через HTTPS и убедившись, что клиент предварительно настроен на доверие только к сертификатам, подписанным определенным центром сертификации, к которому только вы имеете доступ. .

Вы говорите о том, что называется проблемой «доверия клиентов». Потому что клиент (в данном случае SWF-файл, работающий в браузере) делает то, для чего он предназначен. Сохраните высокий балл.

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

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

Мне нравится то, что сказал tpqf, но вместо того, чтобы отключать учетную запись при обнаружении мошенничества, внедрите приманку, чтобы каждый раз, когда они входят в систему, они видят свои взломанные оценки и никогда не подозревают, что они были отмечены как тролль. Погуглите по запросу "phpBB MOD Troll", и вы увидите гениальный подход.

Проблема с этим подходом в том, что эти читы хвастаются друг перед другом на досках объявлений и т. д., Так что на самом деле это их не отпугнет.

Iain 17.09.2008 14:15

Я не согласен. Это звучит как очень умный подход.

bzlm 12.03.2009 23:42

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

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

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

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

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

Chris Garrett 11.09.2009 16:41

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

Это кажется довольно хорошим решением, если вы спросите меня, есть ли у кого-нибудь проблемы с использованием этого метода? Или возможные способы обойти это?

Wireshark. Wireshark - это всегда дыра.

aehiilrs 23.07.2010 20:14

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

Sigtran 01.03.2011 19:24

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

mkto 07.12.2011 06:53

В принятом ответе tqbf упоминает, что вы можете просто выполнить поиск в памяти для переменной оценки («Моя оценка 666, поэтому я ищу число 666 в памяти»).

Есть способ обойти это. У меня здесь класс: http://divillysausages.com/blog/safenumber_and_safeint

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

Также посмотрите видео от некоторых разработчиков движка PushButton, которые рассказывают о различных способах борьбы со взломом: http://zaa.tv/2010/12/the-art-of-hacking-flash-games/. Они были источником вдохновения для класса.

Я думаю, что самым простым способом было бы вызывать такую ​​функцию, как RegisterScore (score), каждый раз, когда игра регистрирует счет, который нужно добавить, а затем кодировать его, упаковывать и отправлять в скрипт php в виде строки. Сценарий php знает, как его правильно декодировать. Это остановит любые вызовы прямо в php-скрипт, поскольку любая попытка принудительного подсчета очков приведет к ошибке декомпрессии.

Это возможно только при сохранении вся игровая логика на стороне сервера, который также хранит счет внутри без ведома пользователя. По экономическим и научным причинам человечество не может применить эту теорию ко всем типам игр, кроме пошаговых. Например, Сохранение физики на стороне сервера требует больших вычислительных ресурсов и трудностей для быстрого реагирования. Даже возможно, играя в шахматы, любой может сопоставить игровой процесс AI в шахматах с противником. Следовательно, лучший многопользовательские игры должен также содержать творчество по требованию.

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

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

Я сделал своего рода обходной путь ... У меня было указано, где увеличиваются баллы (вы всегда получаете +1 балл). Во-первых, я начал считать со случайного числа (скажем, 14), и когда я показываю результаты, просто показываю их var минус 14. Это было так, что если взломщики ищут, например, 20, они его не найдут (это будет 34 в памяти). Во-вторых, поскольку я знаю, какой должна быть следующая точка ... Я использовал криптографическую библиотеку Adobe, чтобы создать хэш следующей точки должно быть. Когда мне нужно увеличить баллы, я проверяю, равен ли хэш увеличенных баллов тому, который должен быть. Если взломщик поменял точки в памяти, хеши не равны. Я провожу некоторую проверку на стороне сервера, и когда я получаю разные баллы от игры и от PHP, я знаю, что имел место читерство. Вот фрагмент моего кода (я использую класс Adobe Crypto libraty MD5 и случайную криптографическую соль. CallPhp () - моя проверка на стороне сервера)

private function addPoint(event:Event = null):void{
            trace("expectedHash: " + expectedHash + "  || new hash: " + MD5.hash( Number(SCORES + POINT).toString() + expectedHashSalt) );
            if (expectedHash == MD5.hash( Number(SCORES + POINT).toString() + expectedHashSalt)){
                SCORES +=POINT;
                callPhp();
                expectedHash = MD5.hash( Number(SCORES + POINT).toString() + expectedHashSalt);
            } else {
                //trace("cheat engine usage");
            }
        }

Используя эту технику + обфустацию SWF, я смог остановить взломщики. Кроме того, когда я отправляю оценки на сервер, я использую свою небольшую функцию шифрования / дешифрования. Примерно так (код на стороне сервера не включен, но вы можете увидеть алгоритм и написать его на PHP):

package  {

    import bassta.utils.Hash;

    public class ScoresEncoder {

        private static var ranChars:Array;
        private static var charsTable:Hash;

        public function ScoresEncoder() {

        }

        public static function init():void{

            ranChars = String("qwertyuiopasdfghjklzxcvbnm").split("")

            charsTable = new Hash({
                "0": "x",
                "1": "f",
                "2": "q",
                "3": "z",
                "4": "a",
                "5": "o",
                "6": "n",
                "7": "p",
                "8": "w",
                "9": "y"

            });

        }

        public static function encodeScore(_s:Number):String{

            var _fin:String = "";

            var scores:String = addLeadingZeros(_s);
            for(var i:uint = 0; i< scores.length; i++){
                //trace( scores.charAt(i) + " - > " + charsTable[ scores.charAt(i) ] );
                _fin += charsTable[ scores.charAt(i) ];
            }

            return _fin;

        }

        public static function decodeScore(_s:String):String{

            var _fin:String = "";

            var decoded:String = _s;

            for(var i:uint = 0; i< decoded.length; i++){
                //trace( decoded.charAt(i) + " - > "  + charsTable.getKey( decoded.charAt(i) ) );
                _fin += charsTable.getKey( decoded.charAt(i) );
            }

            return _fin;

        }

        public static function encodeScoreRand(_s:Number):String{
            var _fin:String = "";

            _fin += generateRandomChars(10) + encodeScore(_s) + generateRandomChars(3)

            return _fin;
        }

        public static function decodeScoreRand(_s:String):Number{

            var decodedString:String = _s;
            var decoded:Number;

            decodedString = decodedString.substring(10,13);         
            decodedString = decodeScore(decodedString);

            decoded = Number(decodedString);

            return decoded;
        }

        public static function generateRandomChars(_length:Number):String{

            var newRandChars:String = "";

            for(var i:uint = 0; i< _length; i++){
                newRandChars+= ranChars[ Math.ceil( Math.random()*ranChars.length-1 )];
            }

            return newRandChars;
        }

        private static function addLeadingZeros(_s:Number):String{

            var _fin:String;

            if (_s < 10 ){
                 _fin = "00" + _s.toString();
            }

            if (_s >= 10 && _s < 99 ) {
                 _fin = "0" + _s.toString();
            }

            if (_s >= 100 ) {
                _fin = _s.toString();
            }           

            return _fin;
        }


    }//end
}

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

Привет, ИКО

Было бы неплохо связаться с серверной частью через AMFPHP. Это должно удерживать по крайней мере ленивых от попыток продвигать результаты через консоль браузера.

Другие вопросы по теме