Как мы взломали шифрование пакетов в BattlEye

Автор оригинала: yousif, namazso, DefCon42, can1357
  • Перевод

Недавно Battlestate Games, разработчики Escape From Tarkov, наняли BattlEye для реализации шифрования сетевых пакетов, чтобы мошенники не могли перехватить эти пакеты, разобрать их и использовать в своих интересах в виде радарных читов или иным образом. Сегодня, в преддверии старта нового потока курса Этичный хакер, на котором мы учим студентов искать уязвимости, делимся с вами кейсом взлома их шифрования за несколько часов.


Анализ EFT

Мы начали с анализа самого "Escape from Tarkov". В игре используется Unity Engine, который, в свою очередь, использует C# — промежуточный язык, а это означает, что можно очень легко просмотреть исходный код игры, открыв его в таких инструментах, как ILDasm или dnSpy. В этом анализе мы работали с dnSpy.

Unity Engine без опции IL2CPP генерирует игровые файлы и помещает их в GAME_NAME_Data\Managed, в нашем случае это EscapeFromTarkov_Data\Managed. Эта папка содержит все использующие движок зависимости, включая файл с кодом игры — Assembly-CSharp.dll, мы загрузили этот файл в dnSpy, а затем искали строку encryption и оказались здесь:

Этот сегмент находится в классе EFT.ChannelCombined, который, как можно судить по переданным ему аргументам, работает с сетью:

Правый клик по переменной channelCombined.bool_2, которая регистрируется как индикатор того, было ли включено шифрование, а затем клик по кнопке Analyze показывают нам, что на эту переменную ссылаются два метода:

Второй из них — тот, в котором мы сейчас находимся, так что, дважды щёлкнув по первому, мы окажемся здесь:

Вуаля! Есть вызов BEClient.EncryptPacket, клик по методу приведёт к классу BEClient, его мы можем препарировать и найти метод DecryptServerPacket. Этот метод вызывает функцию pfnDecryptServerPacket в библиотеке BEClient_x64.dll. Она расшифрует данные в пользовательском буфере и запишет размер расшифрованного буфера в предоставленный вызывающим методом указатель.

pfnDecryptServerPacket не экспортируется BattlEye и не вычисляется EFT, на самом деле он поставляется инициализатором BattlEye, который в какой-то момент вызывается игрой. Нам удалось вычислить RVA (Relative Virtual Address), загрузив BattlEye в свой процесс и скопировав то, как игра инициализирует его. Код этой программы лежит здесь.

Анализ BattlEye

В последнем разделе мы сделали вывод, что, чтобы выполнить все свои криптографические задачи, EFT вызывает BattlEye. Так что теперь речь идёт о реверс-инжинеринге не IL, а нативного кода, что значительно сложнее.

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

Распаковка — это дамп образа процесса во время выполнения; мы сделали дамп, загрузив его в локальный процесс, а затем поработав в Scylla, чтобы сбросить его память на диск.

Открытие этого файла в IDA, а затем переход к процедуре DecryptServerPacket приведут нас к функции, которая выглядит так:

Это называется vmentry, она добавляет на стек vmkey, а затем вызывает обработчика виртуальной машины — vminit. Хитрость вот в чём: из-за того, что инструкции “виртуализированы” VMProtect, они понятны только самой программе.

К счастью для нас, участник Секретного Клуба can1357 сделал инструмент, который полностью ломает эту защиту, — VTIL; его вы найдёте здесь.

Выясняем алгоритм

Созданный VTIL файл сократил функцию с 12195 инструкций до 265, что значительно упростило проект. Некоторые процедуры VMProtect присутствовали в дизассемблированном коде, но они легко распознаются и их можно проигнорировать, шифрование начинается отсюда:

Вот эквивалент в псевдо-Си:

uint32_t flag_check = *(uint32_t*)(image_base + 0x4f8ac);

if (flag_check != 0x1b)
	goto 0x20e445;
else
	goto 0x20e52b;

VTIL использует свой собственный набор инструкций, чтобы ещё больше упростить код. Я перевёл его на псевдо-Си.

Мы анализируем эту процедуру, войдя в 0x20e445, который является переходом к 0x1a0a4a, в самом начале этой функции они перемещают sr12 — копию rcx (первый аргумент в соглашении о вызове x64 по умолчанию) — и хранят его на стеке в [rsp+0x68], а ключ xor — в [rsp+0x58]. Затем эта процедура переходит к 0x1196fd, вот он:

И вот эквивалент в псевдо-Си:

uint32_t xor_key_1 = *(uint32_t*)(packet_data + 3) ^ xor_key;
(void(*)(uint8_t*, size_t, uint32_t))(0x3dccb7)(packet_data, packet_len, xor_key_1);

Обратите внимание, что rsi — это rcx, а sr47 — это копия rdx. Так как это x64, они вызывают 0x3dccb7 с аргументами в таком порядке: (rcx, rdx, r8). К счастью для нас, vxcallq во VTIL означает вызов функции, приостановку виртуального выполнения, а затем возврат в виртуальную машину, так что 0x3dccb7 — не виртуализированная функция! Войдя в эту функцию в IDA и нажав F5, вы вызовете сгенерированный декомпилятором псевдокод:

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

Эта функция расшифровывает пакет в несмежные 4-байтовые блоки, начиная с 8-го байта, с помощью ключа шифра rolling xor.

Примечание от переводчика:

Rolling xor – шифр, при котором операция xor буквально прокатывается [отсюда rolling] по байтам:

  • Первый байт остаётся неизменным.

  • Второй байт — это результат xor первого и второго оригинальных байтов.

  • Третий байт — результат XOR изменённого второго и оригинального третьего байтов и так далее. Реализация здесь.

Продолжая смотреть на ассемблер, мы поймём, что она вызывает здесь другую процедуру:

Эквивалент на ассемблере x64:

mov t225, dword ptr [rsi+0x3]
mov t231, byte ptr [rbx]
add t231, 0xff ; uhoh, overflow

; the following is psuedo
mov [$flags], t231 u< rbx:8

not t231

movsx t230, t231
mov [$flags+6], t230 == 0
mov [$flags+7], t230 < 0

movsx t234, rbx
mov [$flags+11], t234 < 0
mov t236, t234 < 1
mov t235, [$flags+11] != t236

and [$flags+11], t235

mov rdx, sr46 ; sr46=rdx
mov r9, r8

sbb eax, eax ; this will result in the CF (carry flag) being written to EAX

mov r8, t225
mov t244, rax
and t244, 0x11 ; the value of t244 will be determined by the sbb from above, it'll be either -1 or 0 
shr r8, t244 ; if the value of this shift is a 0, that means nothing will happen to the data, otherwise it'll shift it to the right by 0x11

mov rcx, rsi
mov [rsp+0x20], r9
mov [rsp+0x28], [rsp+0x68]

call 0x3dce60

Прежде чем мы продолжим разбирать вызываемую им функцию, мы должны прийти к следующему выводу: сдвиг бессмыслен из-за того, что флаг переноса не установлен, а это приводит к возвращаемому из инструкции sbb значению 0; в свою очередь, это означает, что мы не на правильном пути.

Если поискать ссылки на первую процедуру 0x1196fd, то увидим, что на неё действительно ссылаются снова, на этот раз с другим ключом!

Это означает, что первый ключ на самом деле направлял по ложному следу, а второй, скорее всего, правильный. Хороший Бастиан!

Теперь, когда мы разобрались с реальным ключом xor и аргументами к 0x3dce60, которые расположены в таком порядке: (rcx, rdx, r8, r9, rsp+0x20, rsp+0x28). Переходим к этой функции в IDA, нажимаем F5 — и теперь прочитать её очень легко:

Мы знаем порядок аргументов, их тип и значение; единственное, что осталось, — перевести наши знания в реальный код, который мы хорошо написали и завернули в этот gist.

Заключение

Это шифрование было не самым сложным для реверс-инжиниринга, и наши усилия, безусловно, были замечены BattlEye; через 3 дня шифрование было изменено на TLS-подобную модель, где для безопасного обмена ключами AES используется RSA. Это делает MITM без чтения памяти процесса неосуществимым во всех смыслах и целях.

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

Узнайте, как прокачаться и в других специальностях или освоить их с нуля:

Другие профессии и курсы
SkillFactory
Школа Computer Science. Скидка 10% по коду HABR

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

    +2
    Battlestate или BattleEye вам за это что нибудь заплатили?)
      +2

      Им заплатили читеры...

      –1

      Я являюсь фанатом игры EFT и ничего хорошего не скажу в сторону автора.
      Мы честные игроки устали от читеров которые периодически заполоняют игру. Из-за читеров перестала пользоваться популярностью целая локация — лабаратория.
      Те силы которые тратят разработчики на борьбу с читерами могли бы уйти на доработку функционала и исправление багов. Вместо этого борьба с читерами является приоритетом №1.


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


      В игре нет внутреннего доната. Т.е. один раз купил и играешь.
      Паки расширяющие схрон я не считаю донатом, так как это форма поддержки разработчиков. Изначально игра делается на личные средства без издателя. Было много желающих помочь деньгами на старте альфа версии, для них были придуманы различные пакеты, в качестве благодарности игрокам даются некоторые "плюшки".


      Соответственно появился черный рынок РМТ для желающих получить внутреннюю валюту за реальные деньги. Из-за высокого спроса требуется инструмент для быстрого заработка, и это — читы. Самой богатой на лут локацией является Лабаратория. В итоге её заполонили читеры.
      К моменту бана читер успевает продать свою валюту.


      БСГ и БЕ активно борются с этим. Применяют различные механики. По сравнению с вакханалией которая была на пике хайпа в начале 2020, сейчас читеров значительно меньше и они стараются не мешать честным игрокам из-за системы репортов.


      Все мы знаем истории игр которые погубили читеры.


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


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

        +1

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

          0

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


            +2

            потратил время на просмотр, и огорчился еще больше. т.е. он из РЕЛИЗНОЙ игры сделал многолетнюю бету, а на слайде показал, что многолетняя бета — плохо. у человека речь расходится с поступками. вообще, узнав о стоимости серваков из этого видео, мне подумалось, что с такой монетизацей таркова им очень выгодны читеры, как ни крути

              0

              Если бы внимательно смотрели то обратили бы внимание что доклад идёт про первую F2P игру Contract Wars.
              EFT не было ещё в проекте.

                0

                так я внимательно посмотрел. контракт ворс 2.0 — это тарков. он же показывал картинки.

                  0

                  Нет. Contract Wars 2.0 это Hired Ops сейчас. Она кстати в релизе.

                    0

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

                      0

                      Да. Это вселенная Russia 2028.



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

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

                0
                монетизацей таркова им очень выгодны читеры, как ни крути

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


                Процент выручки от продажи аккаунтов читерам значительно меньше, чем от продаж обычным игрокам. При этом они наносят существенный вред.
                Игру в основном покупают в Европе и США, там самый высокий ценник, в то время как читеры через VPN использую самые дешевые СНГ аккаунты.
                Читеры не покупают расширенные паки, а игроки довольные игрой активно это делают.


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



            0
            Как говорят, nothing personal, just business. Вы сами написали, что появился черный рынок. Так что давайте еще докинем в список плохих людей тех игроков, которые пользуются данным рынком. И их наверное очень много, если читеры для удовлетворения спроса убивают игру в хламину.

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

              Покупателям РМТ сейчас временно блокируют аккаунты.

              0

              Им слишком выгодно не бороться с читерами — очень много денег приносят они.

                0

                Кстати, вопрос, как там балансировщик работает?
                А то периодически смотрю BULLSEYE, так шансов выжить у обычного игрока, скажем так, стремятся эти шансы к нулю. И получается что ты заходишь в игру и уже гарантированно ты проиграл.
                Хотя конечно можно сказать что это подножный корм для более умелых и когда ты станешь более умелым ты будешь питаться такими вот неумёхами, но в ситуации с BULLSEYE шансов вообще нет ни у кого.

                  0
                  Кстати, вопрос, как там балансировщик работает?

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


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


                  Так же есть карты более ориентированные для PvP, например завод. Есть карты куда лучше вообще не соваться новичку, например лабаротория и резерв.


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


                  Лично смотрю из англоязычных: Deadlyslob.
                  Из русских: rasty_airsoft, Mr_Holodos, Sharap и dobbykillstreak (youtube).

                0

                Так вроде есть сервер на nodejs и так.

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

                Самое читаемое