Методы защиты кода - обфускация в javascript
В этой статье я расскажу об обфускации и деобфускации JavaScript-кода.
Разработчики используют этот метод для значительного усложнения высокоуровневого кода, чтобы предотвратить его чтение, модификацию и альтернативное использование третьими лицами.
Цели обфускации:
Защита интеллектуальной собственности:
Обфускация помогает защитить уникальные алгоритмы и логику приложения от копирования и несанкционированного использования без упоминания авторства.
Усложнение кода затрудняет поиск и использование потенциальных уязвимостей злоумышленниками.
Сложный и запутанный код усложняет процесс восстановления исходного кода, что защищает исходный код от модификаций с целью обхода или эксплуатации тех или иных функций.
Примеры потенциального «абуза»:
Модификация кода для обхода лицензий:
Злоумышленники могут пытаться изменить код для удаления ограничений или платных функций на стороне клиента или модифицировать сетевые запросы в js с целью обмана серверной части приложения (если такова есть).
Внедрение вредоносных компонентов:
Обфусцированный код сложнее проверить на наличие вредоносных элементов, что может быть использовано для скрытого внедрения вредоносных функций автором.
Использование обфусцированного кода в других проектах или в том же проекте, но с целью оптимизации или внедрением модифицированного кода без разрешения автора.
Методы обфускации:
Переименование переменных и функций:
Использование непонятных имен для переменных и функций.
Удаление пробелов и комментариев:
Минимизация кода для затруднения его чтения.
Добавление бесполезных, вредных или запутанных инструкций.
Использование сложных структур управления:
Применение вложенных условий и циклов для усложнения логики.
Использование шифрования строк и данных:
Шифрование строковых данных и других констант, чтобы их было сложно прочитать в обфусцированном коде.
Включение проверок на режим отладки:
Предотвращение анализа кода злоумышленниками путем остановки выполнения при попытке отладки или реверс-инжиниринга.
Сбор и отправка пользовательских данных без согласия с целью проверки включенного режима разработчика.
Про вредоносные функции в обфусцированном коде
В некоторых случаях разработчики используют вредоносные функции не для нанесения вреда пользователям (клиппер, майнинг), а как средство защиты кода.
Такие функции активируются при попытке деобфускации или обнаружения режима отладки, что может приводить к сбою программы или другим нежелательным последствиям.
Вредоносные функции — это специально внедренные в код функции, которые выполняют разрушительные действия, если код подвергается анализу, деобфускации или отладке. Их цель — отпугнуть любопытных лиц от попыток взлома или копирования кода путем создания негативного опыта при попытке изучения кода.
Примеры реализации вредоносных функций
Функция, вызывающая сбой приложения при деобфускации
(function() { function checkObfuscation() { // Проверка на простое форматирование кода const formatted = /[A-Z]/.test(function(){}.toString()); if (formatted) { // Запуск вредоносного кода при деобфускации while(true) {} } } checkObfuscation(); })();
Такая функция проверяет, форматирован ли код (например, легко читается ли он). Если обнаруживается, что код не обфусцирован, запускается бесконечный цикл (while true), что приводит к зависанию приложения.
Функция, завершающая выполнение при обнаружении режима отладки
(function() { function detectDebugging() { const start = Date.now(); debugger; const end = Date.now(); if (end - start > 100) { // Если отладчик замедляет выполнение // Запуск вредоносного кода document.body.innerHTML = ''; alert('Код защищен!'); // Дополнительно можно добавить бесконечный цикл или другие действия while(true) {} } } detectDebugging(); })();
Такая функция использует debugger
для проверки задержки в выполнении кода, что может указывать на наличие отладчика. Если обнаружен отладчик, происходит очистка содержимого страницы и запуск бесконечного цикла, что делает анализ кода затруднительным. Данная функция используется при проверке включенного devTools в браузере или debug mode в VSCode
Функция, вызывающая утечку памяти при попытке деобфускации
(function() { function induceMemoryLeak() { const leakyArray = []; setInterval(() => { leakyArray.push(new Array(1000000).fill('*')); }, 100); } induceMemoryLeak(); })();
Эта функция постоянно добавляет большие массивы в leakyArray
, вызывая утечку памяти. В результате браузер может замедлиться или даже зависнуть, что усложняет процесс анализа кода.
Инструменты для обфускации
Помимо методов, разработанных самостоятельно разрабтчиком, существуют и готовые инструменты для обфускации кода:
JavaScript Obfuscator: Популярный инструмент для обфускации кода.
UglifyJS: Используется для минимизации и обфускации JavaScript-кода.
Babel: Может применяться в сочетании с плагинами для обфускации.
Минимизер: инструмент удаления комментариев и пробелов из всего кода. Полезен и для сжатия кода, если код передается очень часто от сервера к клиенту.
Хочу отметить, что существуют и вовсе простые онлайн инструменты для быстрой обфускации кода.
Обфускация - плохо ли это?
Во-первых, обфускация не гарантирует полной защиты:
Опытные разработчики всё равно могут разобрать обфусцированный код вручную или с применением нейросетей.
Во-вторых, обфускация влияет на производительность:
Излишняя обфускация может негативно сказаться на скорости выполнения кода. Особенно, если обфускация используется в браузере в играх, а игра рассчитана на широкий круг пользователей, использующих зоопарк устройств, в том числе и "слабые" устройства.
Излишняя обфускация в принципе вредна при использовании в браузере, добавляя лишний слой сложной абстракции между выполнением кода и самим устройством. Особенно, при майнинге =) Да, разраб мемхеша?
Деобфускация
Деобфускация — это процесс обратного преобразования обфусцированного (запутанного) кода в более человеко читаемую и понятную форму.
Цель деобфускации — восстановить исходную структуру и логику кода, чтобы облегчить его анализ, понимание и дальнейшую модификацию, если требуется.
Для меня лично деобфускация имеет под собой 3 цели:
- Поиск связей между разработчиком текущего проекта и предыдущими проектами (и плохими, и хорошими). Детект на скам.
- Поиск вредоносного кода: клиппер (перехват данных из буфера обмена на сервер разработчика), майнер (работающий на разработчика, а не клиента)
- Поиск уязвимостей в коде на стороне клиента или сервера или способа оптимизировать код. Ну и для абуза конечно же, если есть заказ.
Про пункт 1: таким образом выявлена одна очень серьезная проблема в проекте starshash. Об этом я написал в BruceStars. ССЫЛКА
Методы деобфускации
Статический анализ (привет Саня)
Статический анализ подразумевает изучение кода без его выполнения. Это включает в себя чтение и понимание кода, поиск паттернов и использование инструментов для упрощения анализа.
Для этого применяется форматирование кода с использованием инструментов форматирования (beautifiers). Например, автоматические инструменты такого рода есть в VSCODE. тот же преттир.
// Обфусцированный код var _0x1a2b="\x62\x72\x75\x63\x65\x20\x63\x6C\x75\x62F"];console.log(_0x1a2b[0]); // После форматирования var _0x1a2b = ["bruce club"]; console.log(_0x1a2b[0]);
Далее, необходимо восстановить осмысленные имена вместо случайных или непонятных:
// Обфусцированный function _0xabc() { /* код */ } // Деобфусцированный function initializeApp() { /* код */ }
Здесь нам помогут нейросеточки.
И наконец: удаление ложного кода т.е. поиск и удаление ненужных или бесполезных участков кода, добавленных для усложнения анализа.
Например вызовы console.log с выводом случайных символов из math random.
Этот момент чаще всего применяется путем анализа кода самостоятельно экспертным методом.
Динамический анализ (пока Саня)
Динамический анализ предполагает выполнение кода в контролируемой среде для наблюдения за его поведением. Это может помочь понять логику кода и выявить его функциональность.
- Деббагер (браузерный или VSCODE встроенный)
- Мониторинг сетевого трафика (network inspector)
- Memory Control
Все эти инструменты запускаются совместно и для всего приложения.
Кого я обманываю? console.log тоже применяется!
Автоматизированные инструменты деобфускации
Этот пункт чаще всего применяется, как самый первый и самый полезный. Далее идет стат анализ и динамический анализ.
Существуют специализированные инструменты, которые автоматизируют процесс деобфускации, применяя различные техники для восстановления читаемого кода.
- Распаковка Arrays и удаление пустых.
- Удаление прокси функций
- Переименование hex ascii переменных в человеческие + понятные
- Разбиение кода на логические функции с применением стилей (бьютифай)
- Поиск Eval и удаление его после вызова
Что не умеет автоматический деобфускатор (онлайн или оффлайн)?
- При столкновении с "вредным" кодом, инструмент падает т.е. удалить "вредный" код инструмент не сможет.
- Инструмент не понимает назначение сложных функций с нечитаемыми названиями, поэтому восстановить человекочитаемые функции инструмент не сможет.
- Онлайн инструмент, как правило, ограничен или временем запроса или длинной кода. Результат может и не отобразиться. Только для небольших кусков кода, онлайн инструмент действительно полезен.
Советы
Часто деобфускация требует применения нескольких методов и инструментов для полного восстановления кода.
Понимание распространённых техник обфускации поможет быстрее распознавать и декодировать их.
Используй скрипты и инструменты для автоматизации повторяющихся задач, таких как форматирование и переименование переменных. Для этого создай папочку в каждом проекте под названием tools или даже отдельный репозиторий со сниппетами.
Ведение записей о шагах деобфускации поможет сохранить структуру и логику процесса. Это полезно, если деобфускация требуется не часто или для восстановления логики и подхода к определенным проектам.
Статья принадлежит автору канала: https://t.me/bruce_club
Автор: https://t.me/pancakeboy