Анализ безопасности сетевых Unity3D игр в VKontakte



    Привет. Надеюсь этот пост не приведет к плохим последствиям и все будет хорошо и мир наполнится светом! Почему все настолько плохо в социальных unity3d играх ВКонтакте?

    Выдались свободные выходные и посвятил я их одному интересному делу — выявить слабые места в безопасности приложений. Т.к. работаю в основном с юнити, то брал игры, созданные на этом движке. Сразу замечу, что я не профессионал и опыта подобного анализа у меня не было. Имелись знания о том, как происходит авторизация пользователя и проверка валидности его id(в документации вк есть) + c#(без него никак). В руки попали 4 приложения, и во всех четырех нашлись дыры, причем в последнем такая, что можно было получить доступ к "серверным методам". Как это получилось?



    1. Инструменты

    Бродя по просторам паутины встречал программу Unity 3D Obfuscator, имеющую следующие фичи:
    -защита от декомпиляции;
    -обфускация (переименование в бессмысленный набор символов) имен объектов (классы, функции, свойства и т.п.);
    -запутывание графа потока выполнения;
    -распаковка Unity3D проектов;
    -удаление метаданных событий и свойств.

    Как раз распаковка .unity3d(веб билд) файла позволит достать .dll-ки, которые пригодятся в дальнейшем. Так что первым делом скачал и установил Unity 3D Obfuscator.

    Для дизассемблирования нарыл ILSpy(free). Возможность смотреть C#<->IL коды очень пригодилась, но об этом позже…

    Unity3d + VS2012 позволили быстро написать маленькое приложение для тестов.

    2. Процесс

    Первым делом достал из HTML-исходника страницы viewer_id и auth_key для конкретного приложения. Последний, кстати, уникален для каждой пары юзер+приложение. Там же можно найти url для iframe, в котором можно узнать путь до .unity3d файла. Copy/Paste to NotePad++.


    (html исходник)

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

    Далее, с помощью Unity 3D Obfuscator распаковал билд и получил на выходе dll-ки. Assembly-CSharp.dll — то, что нам нужно! Сделав 0.5л кофе, продолжил заниматься рукоблудием…


    (Unity 3D Obfuscator)


    Теперь предстояла задача найти в коде точки пересылки данных. Если есть подпись, то и в механизме подписывания содержимого.

    ILSpy проглотил сборку очень шустро и выдал полотно классов. Подключив смекалку, забил в поиск Network, однако поиск привел лишь к классам, относившимся к Photon Cloud. Не то, идем дальше. Через несколько минут нашел чью-то пару id-auth_key(как оказалось, админа приложения). Еще через какое-то время — адрес сервера, к которому нужно отсылать запросы.

    Использую ссылки «Used By» нашел место применения — методы, дергающие апи игрового сервера.

    Если с первым приложением все было просто(бери и подставляй свои данные), то с другими нужно было повозиться больше, т.к. попытка отослать запрос оканчивалась ответом «Hello Mazafacka» со стороны сервера.

    Чего-то не хватает… Смотрю на метод с названием Md5Sum и понимаю, что не хватает хеша! Но как его строить? Смотрим в код:

    private IEnumerator UpdateScor(string vid, ...)
    {
    df.c__Iterator20 c__Iterator = new df.c__Iterator20();
    c__Iterator.viewer_id = vid;
    ...
    return c__Iterator;
    }


    К такому жизнь меня не готовила. Полез в инет...

    Все оказалось просто - компилятор для инструкций yield return делает класс, в котором реализован конечный автомат, поэтому нужно было найти этот класс и посмотреть, что же там за логика. Однако поиски df.c__Iterator20 оказались безуспешными... Пошел гуглить. Фишка оказалось в просмотре IL кода. Как раз в нем нашел реализацию того самого класса, в котором была логика. Потратив еще пол часика разобрался с тем, как собирается запрос(string.concat) и создается хеш(MD5(string.concat)). Теперь запросы проходили на ура!

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

    Итого:
    0. Суммарно затраченное время - ~6 часов.
    1. Спокойно можно изменять статы в 3 играх - деньги, опыт и т.д.
    2. В одной нашел App_Secret! Я не могу передать словами, насколько это эпично держать эту строку на клиенте...

    Как лечить?(сугубо мое мнение)
    1. Клиент - читер. Всегда. Только серверные проверки смогут внести спокойствие в игровой мир.
    2. НИКОГДА не всовывать в продакшн билд важные данные. К ним относятся: различные ключи(если только не паблик), тестовые данные аккаунтов.
    3. Можно попробовать блокировать пользователя после пару неудачных попыток обращения к АПИ, чтобы нельзя было бесконечно пробовать подобрать что-либо.

    Напоследок

    Целью не было создать чит или напакостить проектам. Чистый анализ и ничего более. Хотя, если попробовать взять проект по-серьезнее(>1 000 000 установок), то может быть времени уйдет в разы больше, или вовсе ничего не выйдетПроверил, хрен редьки не слаще.

    Вообще очень понравилось заниматься анализом, подумываю работать в этой сфере. Только одного понять не могу - почему администрация не реагирует? Проекты живые, люди играют. Может настали времена, когда использовать ArtMoney для взлома это предел возможностей игроков?(я был бы рад) Или игроки стали честнее и не используют чит-программы?(Радость х5)

    А что вы думаете, дорогие жители Хабра, по поводу защиты?

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 37

      +1
      Хорошая статья! :)

      pdf — обычно для того чтобы cloudflare корректно кешировал билд и бандли, еще можно юзать swf.

      почему авторы где-то не закрыли ту или иную дырку? наверное тупо из-за нехватки времени и заняты остальной частью продукта :).
        0
        Спасибо, буду знать теперь про pdf и swf

        Тоже пилил игру(сервер) и на первом месте стояла безопасность(не путать с паранойей). Видимо подход к выпуску продукта у всех разный.
          +4
          На первом месте должна стоять миссия проекта. У них — денег заработать. А у вас в безопасности попрактиковаться.
          Есть много аудит. компаний, анализ безопасности стоит дешево около 20-40 тыщ, но никто не покупает, потому что финансовых потерь от этих дыр у владельцев нет. А программисты.. ну да нынче такие программисты.
            0
            знаем мы этот аудит за 20 тысяч, скажут что надо ssl 2ой версии поставить, убрать пару старых шифров оттуда же и капчу на авторизацию — все, секурити окончено
              +1
              ну вообще-то нет. Я являюсь руководителем проектов и часто по долгу службы вынужден сдавать работу, при этом один из этапов завершения проекта является аудит безопасности. Мне часто пишут очень не тривиальные штуки и вещи связанные с XSS и инъекциями. Все находят, пишут отчет обычно страниц на 20-30 какие вещи проверяют. Я рекламировать субподрядчиков не буду, как минимум потому что нет постоянных и работают с затягиванием сроков, но в целом услуга на рынке существует и дефицита особого нет
                –1
                скрипткиддисы, прогоняющие сайты сканерами не в счет, максимум что они могут — вставить или кавычки в гет параметры)
                хотя если это аудит сайта на готовом жвижке, то почему бы и не взять 20-30 тысяч и ничего не делать)
                0
                ssl 2ой версии поставить

                Э?
                0
                просто чтобы вы представляли масштаб: Анализ юзабилити обойдется в 100-300 тыщ. за проект а в Юзабилити Лаб и во все 400-600 тыщ. Это рынок.
                  0
                  замечательная фраза про миссию :)
              –3
              Я конечно извиняюсь, но может не стоит тестировать игры которые сделаны на коленке? Почему бы не протестировать действительно профессиональные продукты?
                +3
                Это «игры вконтакте», у которых даже сервак зачастую является прослойкой между БД и клиентом, а сами игры ломаются модификацией памяти. О каком «анализе безопасности» может идти речь?
                  0
                  Что вы имеете ввиду под «прослойкой между БД и клиентом»? Т.е. есть вариант сервер<->БД<->клиент?)

                  Кстати о модификации памяти — в 3 из 4 игр была защита вида cryptValue=value^cryptoKey(XOR) и насколько я понял, это спасает от простого поиска «видимых пользователю» значений в памяти, так что прощай ArtMoney(поправьте, если ошибаюсь).
                    0
                    прослойкой между БД и клиентом

                    Думаю имелось в виду ситуация, когда сервак сейвит данные напрямую в БД вместо обработки информации о действиях, а вся логика реализована на клиенте.
                      +1
                      >>Что вы имеете ввиду под «прослойкой между БД и клиентом»?

                      Если сказано что «A» стоит между «B» и «C», то, как ни странно, «A» находится между «B» и «С». Вы же изобразили всё в порядке расположения слов, проигнорировав слово, указывающее на другой порядок расположения этих объектов. Почему? Как ещё можно понять слово «между», кроме как «между»?

                      p.s. Даже XOR не катит, ибо среди детей находятся умельцы, которые находят такие вещи, и выкладывают маны с тем, какие адреса менять, или как находить (по какому-то другому значению, например, которое статично относительно поксоренного). Иногда доходит даже до хардварных бряков и изменения инструкций.
                        +2
                        Дело в том, что сервер всегда будет прослойкой между БД и клиентом, а не «зачастую». Потому автор и спросил — есть разве другие варианты?
                          –4
                          Как ни странно, другие варианты есть. Проявите фантазию. Как вариант, можно иметь конструкцию, в которой есть игровые сервера, которые получают информацию с сервера баз данных, а не из БД напрямую. Прослойкой же я назвал сервер, который совершает минимум манипуляций с данными (как вариант — собирает запрос из популярного для этих целей JSON), т.о. клиент абсолютно авторитарен.
                            +4
                            Не нужно дерзить мне.
                            Мне не нужно знать, что вы подразумевали под прослойкой, этот вопрос задал автор, и получил хамский ответ.
                            Также не нужно притягивать за уши аналогии — ваши слова «сервак зачастую является прослойкой между БД и клиентом» в корне неверны, так как между БД и клиентом всегда будет сервер, обзывайте его как хотите — «сервер баз данных», «сервер, дающий из базы клиенту JSON».
                            Клиент-серверные приложения так потому и называются — там может не быть БД или быть много чего еще, но клиент и сервер всегда.
                            Пока от вас много воды и мало по делу. Что вы мне пытаетесь доказать? Ответьте, что может быть между БД и клиентом, как не сервер?
                              –4
                              >>Что вы мне пытаетесь доказать?

                              Вы спрашиваете, я отвечаю, и никто никому ничего не доказывает.

                              >> Ответьте, что может быть между БД и клиентом, как не сервер?

                              Сервер, несколько серверов, другие клиенты.

                              >>Мне не нужно знать, что вы подразумевали под прослойкой, этот вопрос задал автор, и получил хамский ответ.

                              Вы спросили какие варианты есть — я назвал возможный, что вас не устраивает?
                          0
                          (по какому-то другому значению, например, которое статично относительно поксоренного)


                          Скрываемые значения вместо поля value хранятся как пара (pad, encryptedValue), откуда value рассчитывается перексориванием. Так вот, pad не обязан быть статичным, можешь его менять случайно хоть в каждом кадре (пересчитывая и encryptedValue).
                          0
                          еще есть клевый пакадж в ассет сторе от русского автора (Anti Cheat Toolkit) где есть практически полный фарш, в том числе и для защиты памяти.
                            0
                            Спасибо за отзыв! =)
                          0
                          Таким играм очень способствуют «быстроклепательные» сервисы к Unity, на подобии photon cloud. Когда ты по тутору и готовому комплекту из стора буквально за вечер, «ни о чем не думая», собираешь сетевую игру. В которой этот самый сервер, вовсе не сервер, а просто роутер передающий пакеты между клиентами. На которых и крутится вся логика. И как результат, игра ломается буквально пальцем.
                          С одной стороны, вроде как клево. Любой может на коленке собрать игру. А с другой имеем тонны треша и устойчивый миф (который некоторые компании постоянно культивируют), что «делать игры это очень просто». И вот уже простейший платформер или раннер требует не меньше гигабайта памяти и тормозит на 4-х ядрах по 2ГГц…
                            0
                            «Делать игры» — не так уж сложно. Так же просто, как и «писать программы», и «делать книги», да и что там, как и «писать тексты».
                            Делать — просто.
                            Делать хорошо — уже не так уж просто…
                              0
                              да, вот про хорошо согласен.
                              Сложновато даже со всеми упрощалками жизни типа юнити, фотон клауда, фотон чата, ассет стора, итд.
                              0
                              Я бы не сказал, что игры или сервисы плохие. Вы правильно заметили, что

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


                              Т.е. можно конечно передавать данные без проверки, которые не очень критичны(голосовой чат, к примеру). А вот что касается игровой логики, то лучше ее реализовывать на сервере.

                              Еще эти «быстроклепательные» сервисы к Unity позволяют быстро прототипировать игры. Однако есть практика прототип выкидывать в продакшн)

                              Сервисы призваны упростить жизнь разработчикам, но к делу нужно всегда подходить с умом.
                                0
                                фотон клауд отличная тема,
                                не надо ).
                                  0
                                  Не надо чего?
                                  0
                                  «ни о чем не думая» — это ж круто,
                                  или принцип по жизни должен быть «в любой непонятной ситуации надо много подумать»? :)
                                    0
                                    Да никто вам не запрещает вообще не думать.
                                    Большинство людей так и поступает.
                                    Кстати, по исследваниям раличных учены, глупые люди, не думающие о том, что проиходит во круг, живут на много счастливее тех, кто задумываеся о том, что проиходит во круг)
                                    Так что живите счастливо…
                                      0
                                      А я не говорю про вообще не думать.
                                      Вон developer правильно говорит про миссию — миссия сделать хороший продукт или думать/делать упор на безопасность/whatever?

                                      Если я могу не думать про сетевое решение и вместо этого потратить время чтобы игра получилась более качественная и интересная игроку — я лично рад :)
                                        0
                                        Как это не говорите? А вот это "«ни о чем не думая» — это ж круто" чьи слова?
                                        Ну и если для вас «миссия, качество и интерес» = «толпа читеров и как следствие унылый геймлей с ботами»
                                        То да, можете не думать про сетевое решение. Как я уже говорил, так действует большинство.
                                        Нормальные разработчики, для которых все это не пустые слова. Да и вообще, просто нормальные, адекватные люди, не выключают мозг в процессе любой деятельности. И находят баланс между «закопаться в код на 10 лет» и «сделать интересный продукт для игроков».

                                        Хотя всегда есть люди, которые предпочитают не думать над тем, что делают. И почему то считают, что если они тупо не будут думать над сетевым решением, то игра автоматом получится шедевром. Откуда такая логика берется неопнятно…
                                        Ведь сетевое взаимодействие для многопользовательской игры это большая и неотъемлемая часть ее.
                                          0
                                          я не совсем понимаю как связан фотонклауд и унылый геймплей, если честно.

                                          умеешь, хочешь и есть время-деньги — свое сетевое решение это ок.
                                          нету каких-то составляющих — фотон клауд тоже ок.

                                          для 99.9% команд — свои велосипеды фейл проекта ).

                                0
                                Интересно услышать мнения о способах защиты в ситуациях когда приложение предает на сервер не свою пару id-auth_key.
                                  0
                                  Если кто-то знает чужие viewer_id и auth_key это уже не излечимо. Разве что сменить app_secret, что в итоге должно привести к образованию нового auth_key для данного viewer_id в этом приложении(и вообще для всех игроков).
                                  0
                                  >2. В одной нашел App_Secret! Я не могу передать словами, насколько это эпично держать эту строку на клиенте…
                                  А где вы посоветуете её держать? На сервере? Так клиент все-равно должен её получить каким то образом, чтобы собрать хеш-сумму, а перехватить пакеты от сервера, тоже как известно никакого труда не представляет.
                                    0
                                    App Secret нужен для проверки ключа авторизации, который передаётся при запуске приложения. Выдержка из документации:

                                    auth_key вычисляется на сервере ВКонтакте следующим образом: auth_key = md5(api_id + '_' + viewer_id + '_' + api_secret). Чтобы не производить дополнительную авторизацию пользователя на своем сервере, всегда проверяйте ключ auth_key на правильность.


                                    На клиенте App Secret не нужен.

                                    0
                                    Там же можно найти url для iframe, в котором можно узнать путь до .unity3d файла.

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

                                    Only users with full accounts can post comments. Log in, please.