УДК 004.056.5

Проектирование обфускатора для языка JavaScript

Авторы: Медгаус С.В., Чернышова А.В.

Источник: Информатика, управляющие системы, математическое и компьютерное моделирование в рамках II форума «Инновационные перспективы Донбасса» (ИУСМКМ – 2016): VII Международная научно-техническая конференция, 26 мая 2016, г. Донецк: / Донец. национал. техн. ун-т; редкол. А.Ю. Харитонов и др. – Донецк: ДонНТУ, 2016. с. 167 – 173. [ссылка на сборник]

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

Общая постановка проблемы

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

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

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

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

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

Существующие обфускаторы

На данный момент существует несколько обфускаторов для JavaScript, но необходимо отметить, что все обфускаторы кроме Google Closure Compiler являются в первую очередь упаковщиками или минификаторами (программы, которые минимизируют размер исходного кода, выполняют оптимизацию для увеличения производительности), а уже как следствие, они являются обфускаторами. Были рассмотрены такие популярные упаковщики как YUI Compressor [2] и Packer [3].

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

Проектирование собственного обфускатора

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

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

UML диаграмма прецедентов
Рисунок 1 – UML диаграмма прецедентов

Исходя из диаграммы прецедентов, была разработана диаграмма классов (см. рис. 2), на которой отображена основная структура проектируемого приложения.

Пользователь будет напрямую взаимодействовать с классом MainForm, так как все методы для манипуляции исходным файлом (загрузка в программу, обфускация и сохранение) будут находиться в нём. Также в этом классе будет предоставлена возможность пользователю выбрать режим обфускации с помощью флажков, расположенных на форме. Класс MainForm содержит в себе класс Obfuscator, который и предоставляет возможность обфусцировать исходный код.

Класс Obfuscator содержит список объектов, реализующих функциональный интерфейс Mangler, который содержит всего один метод – обфусцировать исходный код, а уже реализации этого интерфейса конкретизируют, как именно они будут запутывать код. Этот подход обеспечивает унифицированность при работе с объектами-запутывателями, позволяя вызывать один метод для каждого объекта при разной реализации (принцип полиморфизма). Более того, полиморфизм позволяет с лёгкостью добавлять новые алгоритмы обфускации, что намного упрощает процесс разработки.

UML диаграмма классов
Рисунок 2 – UML диаграмма классов

Далее была разработана диаграмма состояний для демонстрации состояний главной формы приложения, в которых она может находиться в процессе функционирования (см. рис. 3). Таких состояний несколько: ожидание действий пользователя, загрузка исходного кода из файла, обфускация исходного кода и сохранение обфусцированного кода в файл.

UML диаграмма состояний
Рисунок 3 – UML диаграмма состояний

Для того чтобы проводить обфусцирующие преобразования с кодом необходимо получить абстрактное синтаксическое дерево (АСД). Эту задачу отлично выполняет библиотека от JQuery Esprima [4]. Она позволяет получить АСД из исходного кода JavaScript в формате JSON (см. рис. 4). Эту библиотеку можно использовать и для генерации кода по АСД, что значительно упрощает проведение обфускации.

Пример разбора исходного кода
Рисунок 4 – Пример разбора исходного кода

Способы обфускации

Планируется реализовать следующие алгоритмы запутывания:

  • подстановка константных переменных в коде;
  • запутывание условных конструкций;
  • преобразование циклов;
  • кодирование строковых и числовых констант.

Подстановка константных переменных заключается в том, чтобы заменить использованные константы в коде на их значение, таким образом появятся «магические числа», которые затрудняют понимание кода.

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

Преобразование циклов включает в себя несколько различных видов преобразований. Первый вид – это трансформация циклов, заключающаяся в том, чтобы один цикл разбить на несколько, просто разделив между ними итерации. Второй – это развёртка циклов. Суть этого вида преобразования в том, что если на этапе разбора кода мы знаем, сколько итераций цикл будет выполняться, то в процессе обфускации мы можем вынести инструкции тела цикла за цикл и повторить там несколько раз, уменьшив при этом итерации самого цикла. И последний вид преобразований циклов – это разделение циклов. Это преобразование заключается в том, чтобы разделить инструкции исходного цикла и поместить в два цикла с исходным количеством итераций. Для большего эффекта запутывания рекомендуется применять все виды преобразований для циклов [5].

Кодирование строковых констант может включать в себя: преобразование констант в кодировку BASE64; добавление новых функций, которые могут «собирать по частям» константы; записывание строк в виде кодов Unicode-символов, которые можно представлять в виде целых чисел и впоследствии можно запутать.

Кодирование числовых констант достаточно сложное преобразование. Это преобразование рационально разделить на преобразование целых и вещественных чисел. Алгоритм кодирования числовых констант представлен на рисунке 5.

Алгоритм кодирования числовых констант
Рисунок 5 – Алгоритм кодирования числовых констант

Выводы

В данной работе рассмотрены понятия обфускатора и обфускации. Также спроектированы UML диаграммы прецедентов, классов и состояний для разрабатываемого обфускатора. Рассмотрена возможность использования вспомогательной библиотеки Esprima для разбора исходного кода и генерации кода по АСД. Уточнены алгоритмы обфускации, а также способы их реализации.

Литература

  1. Википедия. Обфускация [электронный ресурс]. – Режим доступа: https://ru.wikipedia.org/wiki/Обфускация
  2. YUI Compressor [электронный ресурс]. – Режим доступа: https://github.com/yui/yuicompressor
  3. Packer [электронный ресурс]. – Режим доступа: http://dean.edwards.name/packer/
  4. Esprima [электронный ресурс]. – Режим доступа: http://esprima.org/
  5. LynX. Обфускация и защита программных продуктов // CITForum. [электронный ресурс]. – Режим доступа: http://citforum.ru/security/articles/obfus/