• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

Статья NETрогай! Как защитить программу от лишних глаз.

logotype.png

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

План статьи
Перед каждым началом нужно разобраться с тем, как мы будем защищаться. В этом плане я буду использовать четыре программы:
  1. Spices.Net
  2. Smart Assembly
  3. NET Reactor
Каждый из них мы будем тестировать при помощи Detect It Easy и других утилит для реверса, если это потребуется конечно. Но перед этим нужно что-то создать. В этом деле я покажу самую простую программу на C#. С ней мы и будем работать в дальнейшем.

Программа для тестов
Чтобы что-то защищать нужно что-то создать. Я не стал далеко ходить и написал самую простую утилиту с большой, красной кнопкой. При нажатии на нее операционная система выходит из строя. Поэтому если какой-то любопытный пользователь захочет ее вскрыть мы этого не позволим. Открываем Visual Studio и выбираем проект Windows Forms.

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

C#:
[DllImport("ntdll.dll", SetLastError = true)]
private static extern int NtSetInformationProcess(IntPtr hProcess, int processInformationClass, ref int processInformation, int processInformationLength);
private void Click_Button(object sender, EventArgs e) {
    int isCritical = 1;  // 1
    int BreakOnTermination = 0x1D;  // 2

    Process.EnterDebugMode();  // 3

            // 4
    NtSetInformationProcess(Process.GetCurrentProcess().Handle, BreakOnTermination, ref isCritical, sizeof(int));
}

В первом мы создаем критический процесс и присвоим ее значение 1. Ниже задаем значение для флага BreakOnTermination в шестнадцатиричной системе счисления. После делаем запрос отладочных привилегий в строчке 3 и после присваиваем нашему флагу значение один. Все это дело происходит под четвертым комментарием.

Сохраняем результат и собираем проект. Только не думай нажимать на эту кнопку! Иначе придется перезагружать систему, а это сейчас будет лишним действием. Давай загрузим PE-файл в DiE и убедимся, что все работает корректно.

DiE.jpg


Библиотека никуда не пропала как и линковщик. Все строки хорошо просматриваются, а энтропия остается на статусе в 68%. Значит ничего не зашифровано и мы можем спокойно работать с софтом. Если ты до сих пор не понял, где хранится твой PE-файл из проекта, то загляни в папку bin и там же перейди на Debug. Ну а теперь стоит приступить к защите.

Как работает защита
Для начала предлагаю ознакомиться с теоретической частью нашей статьи. Прежде всего существует два типа защиты NET приложений. Это использование обфускаторов и протекторов. Разберем их плюсы и минусы работы.

Протекторы: предоставляют возможность сделать "недоступным" для других. Часто имеют дополнительные функции и позволяют делать защищенные сборки под себя. К этому типу относится наш любимый NET Reactor.
  • Плюсы: ограничение прав сборки в оперативной памяти с последующим сохранением на диске. Достаточно разнообразный набор функций для защиты.
  • Минусы: конфликты с разрядностью системы. Проще говоря ты не можешь создать 64 битную и 32 битную программу одновременно. Яркая и очень хорошо выраженная реакция антивирусов на протекторы. Из-за нее многие пользователи просто боятся использовать такой продукт. К этому добавляется заявление производителей, которые рекомендуют обфуцировать код перед тем, как покрывать его протектором. То есть они сами признают минус своих детищ.
Обфускаторы: запутывают код на основе определенных алгоритмов делая его не читабельным для человека, но рабочим для компьютера. После них обычно не требуется дополнительная настройка или танцы с бубном, чтобы успешно запустить свой код. Есть два варианта обфускации: Stand-alone (не требует в работе сторонних сервисов) и зависимые от MS сервисов (они в свою очередь никак не могут функционировать без доступа к интернету). Примеры, которые мы будем использовать в работе это Smart Assembly и Spices.Net.
  • Плюсы: независимость от каких-либо программ. Простота и надежность в работе, что дает гарантию запуска кода. Также это считается нестандартным подходом к защите софта.
  • Минусы: здесь есть один жирный минус. Заключается он в том, что на родном языке чтение кода почти невозможно, но дизассемблировать программу и узнать ее алгоритм работы по прежнему остается реальным.
Теперь, после того, как мы разобрались с базовыми понятиями можно приступать к тестированию.

Spices.Net


spices.net.jpg


Spices.Net - инструментальное средство следующего поколения для .Net разработчиков, которое содержит функции защиты .NET кода и множество других возможностей. Программа состоит из ядра системы и 2-х внешних модулей Spices.Obfuscator и Spices.Decompiler. Spices.Decompiler содержит функции декомпилирования для 6 языков IL, C#, C++, VB.Net, J#. В ближайшем будущем в программе появятся новые дополнения, Spices.Investigator (.Net PE metadata browser) и Spices.Informer. Как ты понимаешь по мимо защиты он умеет и декомпилировать некоторые программы. Но наша задача защитить исходный код, чтобы до него не мог добраться пользователь. Поэтому чтобы это сделать открываем нашу программу во вкладке File и далее переходим на Tools, кликаем по кнопке Obfuscate! и ждем результата. В итоге у тебя должен появиться файл и папка Output, где лежит готовая работа.

Теперь давай посмотрим, что у нас получилось. Первым делом заливаем все это в наш любимый DiE.

DiE_OBF1.jpg


Как ты видишь понятие протектора или обфускатора в логах у нас не висит, а это уже хороший плюс в копилку. Глянем вкладку строк и посмотрим, что там изменилось. Изменения появились, хоть и не сильно заметные, но расположение строк явно говорят о наличие какой-то внешней защиты. В энтропии у нас все по стандарту, цифры не поменялись и стабильно держат планку на 63%. Давай копнем чуть глубже и посмотрим результат в dotPeek, он точно должен определить подвох.

А его тут нету. Весь код спокойно читается и никакой обфускации не произошло. В строках DiE мы видели все те же строки, но в другом формате. И выходит, что Spices.Net только на словах защищает код. А вот кстати та самая функция, которая вызывает синий экран смерти путем создания критического процесса. При декомпиляции она выглядит таким образом:

C#:
[DllImport("ntdll.dll", EntryPoint = "NtSetInformationProcess", SetLastError = true)]
private static extern int \u0030(IntPtr _param0, int _param1, ref int _param2, int _param3);

private void \u0030(object _param1, EventArgs _param2) {
    int num1 = 1;
    int num2 = 29;
    Process.EnterDebugMode();
    MainWindow.\u0030(Process.GetCurrentProcess().Handle, num2, ref num1, 4);
}

Поэтому здесь мы разобрались с тем, что не весь софт умеет адекватно выполнять свою работу. Сразу занесем название утилиты в черный список, чтобы в дальнейшем не натыкаться на нее. Это кстати объясняет почему при статическом анализе из скриншота не было видно строчки протектора.

Smart Assembly


smartassembly.jpg


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

Первым делом нас встречает окно с просьбой загрузить исполняемый файл. Берем в руки нашу программу и выгружаем ее в приложение. Далее настраиваем обфускацию из предложенных функций. Нам доступно создание отчетов, создание сложного ключа, автоматическая отправка ошибок, удаление ненужных строк, настройка уровня обфускации и настройка динамического прокси. Ставим все по хардкору и компилируем наш софт, попутно молясь, что все сработает. Ну а если ты хочешь знать, что конкретно я использовал, то выставляй в настройках следующие функции: Obfuscation (3 level), Compression and Encryption, Strings Encoding, MSIL Disassembelr Protection. Ждем несколько минут и радуемся успешной сборке. Переходим в DiE и смотрим изменения.

DiE_OBF2.jpg


Строки зашифрованы, а энтропия подскочила до 77%. Поэтому сказать, что нет изменений очевидно нельзя. Вместо обфускатора у нас в колонке отображается протектор, хотя на самом деле это не так. В скором времени ты поймешь почему. Теперь давай откроем dotPeek и взглянем на то, как выглядит наш код. А он очень сильно изменился.

Переходим в тот же файл MainWindow.cs и смотрим нашу часть кода, которая отвечает за главное действие программы. Теперь все это дело выглядит так:

C#:
[DllImport("ntdll.dll", SetLastError = true)]
private static extern int NtSetInformationProcess(
    IntPtr hProcess,
    int processInformationClass,
    ref int processInformation,
    int processInformationLength);

private void Click_Button(object sender, EventArgs e) {
    int processInformation = 1;
    int processInformationClass = 29;
    Process.EnterDebugMode();
    MainWindow.NtSetInformationProcess(Process.GetCurrentProcess().Handle, processInformationClass, ref processInformation, 4);
}

Теперь как ты понимаешь разобрать название переменных и большую часть кода стало невозможно. К этому добавляется несколько пустых функций в начале нашего файла. Есть также дополнительные модули, которые помогают запутать код и сбить с пути реверсера. Как я говорил ранее, если в dotPeek это прочитать невозможно, то в дизассемблерах все легко читается и понять как работает программа вполне возможно. Возьми тот же x64dbg и попробуй залить бинарник с обфускацией. Разница конечно будет, но не такая яркая как в нашем случаи. Поэтому давай теперь попробуем запутать в принципе все, что только можно и покроем нашу программу протектором.

NET Reactor


netreactor.jpg


NET Reactor - это мощная система защиты и лицензирования NET-кода, которая помогает разработчикам в защите своего NET программного обеспечения простым и безопасным способом. Работать мы будем на крякнутой версии этого протектора. У тебя скорее всего возник вопрос, а почему бы не использовать официальную версию? Здесь все очень просто. В отличие от предыдущих программ, которые яростно требуют чтобы их купили реактор просто при каждой компиляции добавляет диалоговое окно в код с названием протектора. То есть перед запуском самой программы у тебя вылезет маленькое рекламное окошко с названием NET Reactor. Гениальный как по мне ход.

Запускаем наш протектор и выбираем создание нового проекта. Далее заливаем туда файл и выбираем нужные функции, их ты можешь увидеть на скриншоте. Чтобы не устраивать танцы с бубном я отметил тот тип защиты, который применяется наиболее чаще в защите. Так мы создаем гарантию того, что итоговый проект запустится. После всех манипуляций кликаешь на кнопочку Protect и терпеливо ждешь результата. Дождался? Заливаем все это дело в DiE и смотрим, что получилось в итоге.

DiE_OBF3.jpg


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

C++:
[DllImport("ntdll.dll", EntryPoint = "NtSetInformationProcess", SetLastError = true)]
private static extern int v5LKivyS4(IntPtr _param0, int _param1, ref int _param2, int _param3);

private void txK5sHCkH(object _param1, EventArgs _param2) {
    int num1 = 1;
    int num2 = 29;
    Process.EnterDebugMode();
    MainWindow.v5LKivyS4(Process.GetCurrentProcess().Handle, num2, ref num1, 4);
}

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

Подводим итоги
Итак, сегодня я рассказал тебе о трех утилитах, которые помогут тебе скрыть свой код от пользователей. К сожалению одна из них отказалась работать и от обфускации осталось лишь одно слово. Но это только подтверждает факт того, что не любая программа способна защитить софт. Что лучше использовать в работе решать тебе. Лично я отдаю свой голос в пользу NET Reactor, так как в работе это незаменимый софт. Но не стоит забывать про его конкурента Smart Assembly, ведь он тоже имеет место быть. Хоть и есть в нем минус, который выражается в отсутствии адекватной бесплатной версии.
 
Последнее редактирование модератором:
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!