December 22, 2024

Методы защиты кода - обфускация в javascript

В этой статье я расскажу об обфускации и деобфускации JavaScript-кода.

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

Цели обфускации:

Защита интеллектуальной собственности:

Обфускация помогает защитить уникальные алгоритмы и логику приложения от копирования и несанкционированного использования без упоминания авторства.

Сокрытие уязвимостей:

Усложнение кода затрудняет поиск и использование потенциальных уязвимостей злоумышленниками.

Защита от реверс-инжиниринга:

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

Примеры потенциального «абуза»:

Модификация кода для обхода лицензий:

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

Внедрение вредоносных компонентов:

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

Перепрофилирование кода:

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

Методы обфускации:

Переименование переменных и функций:

Использование непонятных имен для переменных и функций.

Удаление пробелов и комментариев:

Минимизация кода для затруднения его чтения.

Внедрение ложного кода:

Добавление бесполезных, вредных или запутанных инструкций.

Использование сложных структур управления:

Применение вложенных условий и циклов для усложнения логики.

Использование шифрования строк и данных:

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

Включение проверок на режим отладки:

Предотвращение анализа кода злоумышленниками путем остановки выполнения при попытке отладки или реверс-инжиниринга.

Злоупотребление API браузера:

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

Про вредоносные функции в обфусцированном коде

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

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

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

Примеры реализации вредоносных функций

Функция, вызывающая сбой приложения при деобфускации

(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. Поиск связей между разработчиком текущего проекта и предыдущими проектами (и плохими, и хорошими). Детект на скам.
  2. Поиск вредоносного кода: клиппер (перехват данных из буфера обмена на сервер разработчика), майнер (работающий на разработчика, а не клиента)
  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.

Этот момент чаще всего применяется путем анализа кода самостоятельно экспертным методом.

Динамический анализ (пока Саня)

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

Примеры сразу скопом:

  1. Деббагер (браузерный или VSCODE встроенный)
  2. Мониторинг сетевого трафика (network inspector)
  3. Memory Control

Все эти инструменты запускаются совместно и для всего приложения.

Кого я обманываю? console.log тоже применяется!
Пример: network inspector в браузере для отлова нужных запросов из скам игры.

Автоматизированные инструменты деобфускации

Этот пункт чаще всего применяется, как самый первый и самый полезный. Далее идет стат анализ и динамический анализ.

Существуют специализированные инструменты, которые автоматизируют процесс деобфускации, применяя различные техники для восстановления читаемого кода.

Что умеют такие инструменты?

  • Распаковка Arrays и удаление пустых.
  • Удаление прокси функций
  • Переименование hex ascii переменных в человеческие + понятные
  • Разбиение кода на логические функции с применением стилей (бьютифай)
  • Поиск Eval и удаление его после вызова

Что не умеет автоматический деобфускатор (онлайн или оффлайн)?

  • При столкновении с "вредным" кодом, инструмент падает т.е. удалить "вредный" код инструмент не сможет.
  • Инструмент не понимает назначение сложных функций с нечитаемыми названиями, поэтому восстановить человекочитаемые функции инструмент не сможет.
  • Онлайн инструмент, как правило, ограничен или временем запроса или длинной кода. Результат может и не отобразиться. Только для небольших кусков кода, онлайн инструмент действительно полезен.

Советы

Используй комбинацию методов:

Часто деобфускация требует применения нескольких методов и инструментов для полного восстановления кода.

Изучай шаблоны обфускации:

Понимание распространённых техник обфускации поможет быстрее распознавать и декодировать их.

Автоматизируй процессы:

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

Документируй свои действия:

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

Статья принадлежит автору канала: https://t.me/bruce_club

Автор: https://t.me/pancakeboy