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

Платформа .NET

Фреймворк .NET это программная платформа, выпущенная компанией Microsoft в далеком 2002 году. Основой платформы является общеязыковая среда исполнения Common Language Runtime, которая подходит для различных языков программирования. Функциональные возможности CLR доступны в любых языках программирования, использующих эту среду. В настоящее время .NET Framework развивается в виде .NET.

Приложение для .NET Framework, написанное на любом поддерживаемом данной технологией языке программирования, сначала переводится компилятором в единый для .NET промежуточный байт-код языка Common Intermediate Language (CIL). В рамках данной статьи мы не будем подробно рассматривать CIL. На Хабре можно найти интересные статьи, посвященные этому языку.

Далее, данный байт-код, представляющий собой сборку в терминах .NET, может быть выполнен специальной виртуальной машиной Common Language Runtime (CLR). Также этот байт код транслируется утилитой ngen.exe в исполняемый код для конкретного целевого процессора. В случае использования виртуальной машины CLR встроенный в неё JIT компилятор на лету (just in time) преобразует промежуточный байт код в машинные коды нужного процессора.

Метаданные в .NET представляют собой определённые структуры данных, добавляемые в код CIL для описания высокоуровневой структуры кода. Метаданные описывают все классы и члены классов, определённые в данной сборке и в других сборках, вызываемых данной. При этом, метаданные для метода содержат полное описание этого метода, включая его класс а также сборку, содержащую этот класс), его возвращаемый тип и все параметры этого метода.

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

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

Необходимые инструменты

Для того, чтобы получить код .NET приложения нам не нужен дизассемблер или отладчик. Для работы с приложениями данного типа есть свои инструменты. Наиболее распространенным является .NET Reflector. Данная утилита может использоваться для навигации, поиска и анализа содержимого .NET-компонентов, а также сборок и перевода двоичных данных в форму, пригодную для чтения человеком.

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

Еще одним полезным средством анализа .NET приложений является утилита Detect It Easy, которая позволяет проанализировать чем был обфусцирован тот или иной файл.

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

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

Однако, в качестве дополнительного средства анализа их вполне можно использовать.

Разбираем пример

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

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

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

Зато мы видим упоминание некоего Safeguard. Использование для анализа DetectItEasy не дало особых результатов, так как этот анализатор нашем множество других упаковщиков, но не один из них не содержит в себе упоминание Safeguard. Гуглинг по фразе Safeguard unpack выдает большое количество видео с распаковкой мыла одноименной марки, но в глубине поискового результата удается найти ссылку на следующий сайт: https://github.com/NotPrab/.NET-Deobfuscator.

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

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

В результате получаем файл *-cleaned, который затем можно попробовать заново открыть в .NET Reflector. Но на этот раз мы воспользуемся DnSpy. При открытии нового файла мы по-прежнему видим большую часть кода в зашифрованном виде, но в процессе навигации можно обнаружить класс Module.

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

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

Выгруженный файл мы также прогоняем через наш деобфускатор. Далее, при попытке открыть новый очищенный файл в DnSpy нас ожидает неприятный сюрприз – утилита намертво подвисает при попытке открытия. Поэтому далее мы снова воспользуемся .NET Reflector.

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

И также находим в коде зашифрованные значения Username и Password.

Здесь в качестве алгоритма шифрования используется AES. В результате продолжительного гуглинга удалось найти исходник проекта, который выполняет расшифровку данных, зашифрованных Safeguard в ручном режиме. То есть мы можем скормить этой утилите зашифрованный текст и она с помощью зашитого в нее  ключа расшифрует эти данные.

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

Нам осталось только расшифровать логин и пароль.

После ввода расшифрованных значений получаем сообщение об успешном взломе крякми.

Заключение

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

В завершение статьи хочу пригласить вас на бесплатный вебинар "Анализ стиллера на .NET". На вебинаре проанализируем Стиллер, написанный для работы на С#, изучим методы отладки и попробуем извлечь из него интересные данные. В результате вебинара вы напишете программу для извлечения данных трояна. Зарегистрироваться можно по этой ссылке.

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