Русский
Русский
English
Статистика
Реклама

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

Недавно 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;elsegoto 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 psuedomov [$flags], t231 u< rbx:8not t231movsx t230, t231mov [$flags+6], t230 == 0mov [$flags+7], t230 < 0movsx t234, rbxmov [$flags+11], t234 < 0mov t236, t234 < 1mov t235, [$flags+11] != t236and [$flags+11], t235mov rdx, sr46 ; sr46=rdxmov r9, r8sbb eax, eax ; this will result in the CF (carry flag) being written to EAXmov r8, t225mov t244, raxand 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 0x11mov rcx, rsimov [rsp+0x20], r9mov [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 без чтения памяти процесса неосуществимым во всех смыслах и целях.

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

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

Другие профессии и курсы
Источник: habr.com
К списку статей
Опубликовано: 20.04.2021 20:11:13
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании skillfactory

C

Unity

Реверс-инжиниринг

Игры и игровые приставки

Skillfactory

Криптография

Battleye

Eft

Xor

Csharp

Виртуализация

Vtil

Il-код

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru