Исходники.Ру - Программирование
Исходники
Статьи
Книги и учебники
Скрипты
Новости RSS
Магазин программиста

Главная » Статьи по программированию » .NET - Framework »

Обсудить на форуме Обсудить на форуме

Защита .NET приложений от просмотра.

Проблемы защищенности интелектальной собственности стояли в мире с незапамятных времен. С появлением Java и его промежуточного языка, который в момент выполнения компилируется в машинный код, перед разработчиками встала проблема обеспечения защиты своих алгоритмов.
ВВЕДЕНИЕ
ПОНЯТИЕ ОБФУСКАЦИИ
ГРУППЫ .NET ОБФУСКАТОРОВ
ОБЗОР .NET ОБФУСКАТОРОВ
ЗАКЛЮЧЕНИЕ
СПИСОК ЛИТЕРАТУРЫ

Введение

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

 

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

В последнее время интерес к задаче обфускации резко возрос. Появились попытки формализации и теоретического обоснования задачи. Повышенный интерес к проблеме обфускации в значительной степени обусловлен появлением в 2000 году технологии .Net от Microsoft. Основными понятиями, с которыми оперирует данная технология - понятие "Assembly" и MSIL(промежуточный язык).

Assembly(сборка) - это набор ресурсов и типов, а также метаданные, описывающие типы и методы, реализованные в сборке. Таким образом сборка - это самоописанный компонент.

MSIL - это процессоронезависимый промежуточный язык, созданный Microsoft. MSIL - язык более высокого уровня, чем большинство машинных языков. Он понимает типы объектов и имеет инструкции для создания и инициализации объектов, вызова виртуальных методов и непосредственной манипуляции элементами массива. Он даже имеет инструкции, которые оперируют исключениями. Как и любой другой машинный язык, MSIL может быть написан на ассемблере. Microsoft предоставляет ассемблер и дизассемблер для MSIL.

Таким образом можно понять, что любой "гениальный" алгоритм, который Вы сотворите на C#, VB.Net, Managed C++, J# простой школьник за пять минут (например при помощи .Net Reflector) сможет посмотреть, изучить и использовать в дальнейшем по своему усмотрению.

Существует несколько путей решения проблемы защищенности Вашего кода. Во-первых - это обфускация. Именно этому способу и посвящен мой доклад. Также, помимо обфускации существует возможность конвертирования в процессе установки программы кода в native. Помимо обфускаторов существуют оптимизирующие компиляторы, они позволяют избавиться от бесполезной информации (debug информации), некоторые из них также заменяют вызовы методов непосредственно их телами, что несомненно затрудняет восприятие кода. В большинстве случаев обфускатор является также и оптимизирующим компилятором. Также, в качестве альтернативного решения можно написать свои CORExeMain/CORDllMain - то есть свой загрузчик, однако это решение, на мой взгляд, никак нельзя назвать адекватным.

Компания Microsoft предоставляет для защиты .Net сборок от просмотра две утилиты:

  1. ngen - утилита, превращающая Вашу сборку в native
  2. DotFuscator - обфускатор, поставляемый вместе с Visual Studio .Net 2003

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

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

Понятие обфускации

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

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

 

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

Символьная обфускация

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

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

  • Переименование методов, переменных и т.д. в набор бессмысленных символов
    Например: был у Вас метод класса GetPassword(), после обфускации данный метод будет иметь имя KJHS92DSLKaf(). Несомненно такая бессмыслится откинет взломщика на пару часов от заведомой цели. Однако существует одна проблема - многие декомпиляторы, встречая на своем пути подобного рода имена заменяют их на более читабельные (method_1, method_2), тем самым сводя всю работу обфускатора на нет.
  • Переименование в более краткие имена
    Некоторые обфускаторы поступают еще проще. Проходя по всем классам, методам, параметрам, они заменяют имена на их порядковые номера. Например, был у Вас метод - GetConnectionString(), а стал 0(). К тому же, в связи с тем, что символьной информации теперь в сборке будет храниться меньше, размер самой сборки, соответстенно, тоже значительно сократится. Подобные обфускаторы можно также использовать как оптимизирующие компиляторы. Также подобное решение хорошо тем, что существует вероятность того, что одно и то же имя будет использовано для именование класса, методов класса (например отличающихся только типом возвращаемого значения). Это позволит также заблокировать работу некоторых дизассемблеров, таких как ildasm, например.
  • Использование для имен переменных нечитаемых символов
    Часть обфускаторов вставляют в имена нечитаемые символы, например символы японского языка. Хотя .Net и работает с кодировкой UTF8, не все декомпиляторы адекватно обрабатывают ее символы. Некоторые заменяют имена с такими символами на более понятные, некоторые проставляют вместо непонятных символов их код, некоторые просто отказываются работать с данными символами.
  • Использование ключевых слов языков программирования
    Этот вид символьной обфускации позволит защититься от самых примитивных декомпиляторов, которые увидив в качестве имени зарезервированное слово считают, что сборка не валидна и отказываются с ней работать.
  • Использование имен, меняющих смысл
    Этот тип обфускации скорее использует психологический фактор. Допустим был у Вас класс SecurityInformation с методом GetInformation, а стал Car, с методом Wash. Конечно, это может запутать голову неопытному взломщику, но процессу декомпиляции никак не повредит.

Обфускация символьных данных

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

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

Обфускация данных

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

Обфускация данных состоит из таких методов, как:

  • Изменение местоположения данных
    Перемещение данных подразумевает объединение нескольких сущностей в одну или наоборот разделение одной сущности на несколько. Например: две строки могут быть объединены в массив строк.
  • Кодирующие преобразования
    Некоторые данные кодируются и в процессе выполнения или загрузки программы декодируются
  • Замена статических членов на вызовы методов
    Некоторые статические члены замеяются на вызовы методов.
  • Добавление неиспользуемых данных
    На основе неиспользуемых данных в дальнейшем формируют ложные условия.
  • Изменение способа хранения данных
    Некоторые открытые члены делаются закрытыми и наоборот.
  • Выполнение финализации (finalization)
    Для определенных полей и методов класса может быть выполнена финализация
    (finalization), т.е. данные могут быть защищены от переопределения в классах
    потомков, созданных от класса, которому принадлежит данный член. Данный процесс уменьшает время выполнения программы.

Обфускация графа потока управления

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

  • Преобразование вычислений
    Данный метод заключается во вставке в алгоритмы ложных условий.
    "Например, перед входом в цикл можно вставить ложное условие вроде
    следующего "if (3 == 2) {} else {}", при этом дугу, которая соответствует истине бросить во внутрь цикла, а дугу, которая соответствует лжи бросить на начало цикла. Но, скорее всего, этот прием не собьет с толку многие декомпиляторы. Можно сделать цикл с двумя и более входами, например перед началом цикла вставить условие, которое всегда истинно, истинную дугу бросить на начало цикла, ложную на базовый блок (basic block), который помещается в конец физической
    последовательности, представляющий данный граф, а выходную дугу из этого блока на начало цикла. Таким образом можно получить цикл с несколькими входами. Проводя манипуляции с графом исключительных ситуаций также можно добиться неплохих результатов, например если в графе потока управления исключения отсутствуют (метод не выбрасывает никаких исключений), те мне менее можно наделить этот граф некоторыми исключениями. "[3]
  • Удаление или добавление абстракций кода
    Удаление абстракций кода позволяет помимо решения задачи обфускации также оптимизировать работу программы. Например: обфускатор может заменить вызов какой-нибудь функции непосредственно телом функции, либо наоборот одну функцию заменить на несколько маленьких функций.
  • Перемешивание случайным образом линейных участков

Цикл работы символьного обфускатора

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

Рассмотрим цикл работы символьного .Net обфускатора.

 

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

Подготовка сборки к обфускации

Прежде чем подвергнут свою сборку обфускации можно немного облегчить работу обфускатора - подготовить сборку. Это позволит также достичь более высоких результатов обфускации. Например, с целью защиты алгоритмов, реализованных в Вашей программе можно вынести все интересные, с точки зрения взломщика, реализации из публичных методов в отдельный, например internal класс с protected методами. Этот класс может быть в дальнейшем подвергнут обфускации, что позволит скрыть детали реализации от любопытных глаз. Также, если Ваш новый класс поддеживает сериализацию могут возникнуть проблемы с десериализацией после обфускации класса. Вообще существует множество способов запутать свой код, сделать его более "obfuscation friendly", более подробно эти методы описаны в [2].

Группы .Net обфускаторов

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

 

  1. Парсеры
    Данные обфускаторы работают с IL - кодом, который они предварительно получают используя ildasm. Далее такие обфускаторы производят какие-либо изменения, в зависимости от методов, которые они применяют, и в конце, при помощи утилиты ilasm, получают новую обфусцированную сборку. Основным минусом подобных обфускаторов, помимо времени работы, является то, что они завязаны на ildasm и ilasm, что зачастую не позволяет им работать с вручную сгенерированной сборкой. Также, данные обфускаторы не могут работать с embedded native code
  2. Обфускаторы, знающие формат PE-файла и метаданных в нем.
    Данные обфускаторы анализируют структуру метаданных. Эти продукты между собой подразделяются на продукты, которые вручную анализируют метаданные и продукты, которые используют некоторые интерфейсы, предоставляемые MSCOREE.DLL. Обфускаторов второго типа гораздо больше чем первого, в связи с тем что большинство обфусктаоров написано на Visual C, так как в C# работать с IMetadataDispenserEx интерфейсом достаточно трудно.
  3. Компиляторы и линковщики
    Подобные обфускаторы дают наиболее хороший, устойчивый от взлома результат, однако я подобных обфускаторов не встречал.
  4. Защищающие только exe-сборки
    Обфускаторы данного типа формируют exe-сборку, куда включают в виде managed resource зашифрованные сборки и ресурсы. При запуске программа расшифровывает сборки, загружает в свой домен (AppDomain) и передает управление "родной" Main функции. Также шифруются и обфусцируются ресурсы сборок.
    Также, возможны случаи, когда программа забирает TypeResolve, AssemblyResolve, ResourceResolve события, генерируемые доменом при возникающих затруднениях с типами, сборками, ресурсами, и переназначает их. По мере необходимости, программа динамически подгружает данные. К сожалению, скорость инициализации подобных обфускаторов достаточно мала, также могут возникнуть проблемы с безопасностью, некоторые виды сборок, например managed C++ сборки не смогут быть загружены Assembly.Load(byte[]) путем.

Обзор .Net обфускаторов

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

 

Demeanor .Net

На первое место, среди всех представленных на сегодняшний день на рынке обфускаторов, по степени предоставляемой защиты можно поставить "Demeanor .Net" от компании Wise Owl.

 

 

Ее руководитель - Brent Rector, опубликовал свою книгу - "Introducing Longhorn for Developers" при содействии Microsoft. Авторитет данной програмы достаточно велик, как, в принципе, и ее цена. За одну лицензию Вам придется заплатить 799 долларов. При этом, чтобы получить триальную версию программы, Вам необходимо написать письмо в компанию, которая рассмотрев причины Вашего интереса с их продукту, примет решение об отправке вам триальной версии программы. Мне в этом плане повезло. Господин Brent Rector с легкостью прислал мне версию "Demeanor .Net" для изучения. К сожалению, триальная версия программы является по сути своей консольным приложением, что определенно является большим минусом при ее изучении. Данный обфускатор предоставляет довольно широкие возможности для защиты Вашей .Net сборки. "Demeanor .Net" удаляет ненужную информацию из метаданных, позволяет шифровать строковые переменные, а также работает с мультимодульными сборками. Также из описания следует, что он интегрируется с Visual Studio .Net.

XenoCode 2005

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

 

 

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

Каким образом "XenoCode 2005" позволяет защитить Вашу программу от просмотра:

  1. обработка символьной информации
    "XenoCode 2005" переименовывает классы, методы, параметры и т. д. в бессмысленные наборы символов
  2. обфускация управляющей логики
    "XenoCode 2005" манипулирует управляющей логикой путем добавления новых ложных веток в графе управления, тем самым запутывая последовательность инструкций
  3. Шифрование строковых данных
    "XenoCode 2005" шифрует строковые данные, используемые в коде программы.
  4. Защита от ildasm
    "XenoCode 2005" добавляет в метаданные заведомо неверные данные, которые приводят к краху ildasm.
  5. Удаление debug информации
    "XenoCode 2005" удаляет всю debug информацию из сборки

 

Помимо непосредственно защиты от просмотра, "XenoCode 2005" обладает широким возможностями по оптимизации сборок, защиты от несанкционированного распространения программы (водяные знаки) и т. п.

 

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

RemoteSoft Salamander Obfuscator

RemoteSoft Salamander Obfuscator - это продукт, с очень хорошо проработнным интерфейсом и позволяющий просматривать не только метаданные, но и структуру PE-файла, анализировать ресурсы, бинарные данные. Символьный обфускатор применяет максимально короткие и часто используемые названия для членов сборки. Также, данный продукт содержит Protector, который преобразует методы в "native embedded code" - не поддаются дизассемблированию, но зависимы от текущей версии .Net Framework.

 

 

Preemptive Solution DotFuscator

Preemptive Solution DotFuscator - этот продукт широко известен разработчикам .Net, так как он входит в стандартный пакет Visual Studio .Net 2003.

 

 

Данный обфускатор является одним из немногих, позволяющих обфусцировать поток управления. Однако бедный интерфейс и, порой, не понятные настройки делают его сложным для работы. Одним из его плюсов является интеграция с Visual Studio .Net.

9Rays .Net ILObfuscator (ver 4.1.3)

9Rays .Net ILObfuscator (ver 4.1.3) - более известный как Spices .Net, это хороший продукт, с проработанным интерфейсом. Данный обфускатор имеет большое количество различных настроек, как то коллекция замен и исключений, варианты именования обфусцированных классов, функция оптимизации сборки после обфускации (для managed code), генерация карт обфускации и т.д.

С точки зрения процесса обфускации Spices .Net предоставляет следующие возможности:

  1. Защита от дизассемблеров ILDASM, Anakrino, Reflector, Remotesoft Salamander Decompiler
  2. Два режима обработки строк : скрытие строк в "обертках" и шифрование строк.
  3. Поддержка работы с satellite сборками
  4. Несколько режимов переименования классов, методов, и т.п.
  5. Несколько режимов переименования namespace
  6. Использование технологии генерации наиболее коротких имен для замены.
  7. Реализация cross-obfuscation - работа с набором сборок.

Надо сказать, что Spices .Net - это один из немногих обфускаторов, проверяющих сборку после обфускации. Также Spices .Net выполняет функции оптимизатора и позволяет защитить сборку от несанкционированного распространения (цифровая подпись).

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

Lesser Software LSW IL-Obfuscator

Lesser Software LSW IL-Obfuscator - это достаточно удобная, с точки зрения интерфейса и работы программа, предоставляющая весьма не плохие средства для обфускации.

Из основных достоинств данной программы можно выделить поддержку ANSI и UNICODE и поддержку различных форматов файлов, содержащих MSIL (exe, dll, Netmodule).

 

 

 

С точки зрения процесса обфускации данный продукт позволяет:

  1. Удалить неиспользуемые данные
  2. Применять различные способы именования
  3. Перемещать структуры данных

Thinstall.Net

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

 

 

С точки зрения обфускации данный продукт позволяет:

  1. Шифровать IL байт код, строки и метаданные
    При запуске программы байт код будет дешифрован во временный буфер, где он будет конвертирован в native код ассемблером от Microsoft
  2. Уменьшить размер программы.

Заключение

В заключение мне хотелось бы подвести черту под всем выше изложенным.

Несомненно, представленная выше информация демонстрирует довольно большие плюсы обфускации:

  1. Полученная сборка с трудом поддается дизассемблированию (зачастую не поддается вообще)
  2. Запутывание графа управления позволяет затруднить работу дизассемблера
  3. На рынке ИТ существует огромное количество обфускаторов, которые предоставляют широчайшие возможности по защите вашего кода
  4. Процесс обфускации уменьшает размер программы

К сожалению, существуют и некоторые негативные стороны обфускации:

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

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

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

Список литературы

  1. Викторов В. "Защита Netпродуктов от подглядывания и воспроизведения"
  2. Викторов В. "Обфускация - есть такое слово"
  3. Винников "Обфускаторы для защиты программ"


Может пригодится:


Автор: sieben
Прочитано: 12707
Рейтинг:
Оценить: 1 2 3 4 5

Комментарии: (0)

Добавить комментарий
Ваше имя*:
Ваш email:
URL Вашего сайта:
Ваш комментарий*:
Код безопастности*:

Рассылка новостей
Выгодные условия на полное бухгалтерское сопровождение бизнеса в компании Buhnalog.
Рейтинги
© 2007, Программирование Исходники.Ру