Как взломать приложение на C# созданное в Xamarin

Взлом приложения

Существует большое количество приложений на С# созданы с помощью платформы Xamarin. В этой статье рассмотрим способы анализа и взлома подобных приложений.

Еще по теме: Взлом протектора .NET Reactor

Как взломать приложение на C# созданное в Xamarin

Недавно в мои руки попало интересное мобильное приложение на C# созданное в Xamarin, которое к моему сожалению работало не так, как хотелось бы мне. Хороший повод распотрошить приложение, подумал я.

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

Для этого дела отлично подойдет последняя версия GDA.

Итак, открываем APK-файл приложения и видим, что выг­лядит он как‑то очень странно. Все классы activity имеют при­мер­но оди­нако­вый шаб­лонный код:

Это наводит на мыс­ли, что нам попал­ся какой-то некошерный APK. Воз­можно —  это фрей­мворк… Попробуем поменять рас­ширение .apk на .zip и тут же в гла­за бро­сает­ся загадочная пап­ка assemblies, которая содержит множество DLL-биб­лиотек. Загадочность заключается в том, что в обыч­ных мобиль­ных при­ложе­ниях такой папки нет.

Пос­коль­ку мно­гие биб­лиоте­ки в наз­вании имеют сло­во Xamarin, все ста­новит­ся ясным — основной код приложения написан на С# и находится в биб­лиоте­ке DLL, а шаблонные части кода написаны на Java, которые пред­назна­чен­ны для свя­зи меж­ду сре­дой выпол­нения Mono и вир­туаль­ной машиной сре­ды выпол­нения Android (ART).

Выбор инструмента

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

dotPeek от разработчика JetBrains. Утилита может деком­пилиро­вать и анализировать файлы .exe и .dll. Утилита имеет самую удобную навигацию по деком­пилиро­ван­ному коду, так что, если говорить толь­ко об анализе алго­рит­ма, данная тулза самая удоб­ная.

Глав­ное окно dotPeek
Глав­ное окно dotPeek

dnSpy — может деком­пилиро­вать, редак­тировать, ком­пилиро­вать и отла­живать сбор­ки .Net. Стоит отме­тить, что весь фун­кционал, кро­ме деком­пиляции, работа­ет далеко не всег­да, все зависит от кон­крет­ной ситу­ации. Лично в моем слу­чае ком­пиляция не хотела работать: dnSpy не смог­ свя­зать прос­транс­тва имен Mono и Android.

Взломать приложение на C#. Глав­ное окно dnSpy
Глав­ное окно dnSpy

Simple-assembly-explorer — это довольно древний но от это­го не утра­тив­ший свою акту­аль­нос­ти инструмент. Утилита умеет деком­пилиро­вать .exe и .dll в код на С# или CIL. Самая важная функция —  инс­тру­мент может ком­пилиро­вать код на CIL, что дает возможность без тру­да вно­сить изме­нения в анализируемые фай­лы.

Взлом приложение на C#. Глав­ное окно Simple assembly explorer
Глав­ное окно Simple assembly explorer

Для рас­паков­ки и сборки файла APK я буду использовать архиватор 7z вмес­то используемого для подобных случаев apktool. Далее я объ­ясню почему.

Распакова APK

В начале я попробовал исполь­зовать для рас­паков­ки APK популярную софтину apktool, но при сборке появилась загвоздка из‑за того, что apktool «не зна­ет»  что такое .dll и не счи­тает его стан­дар­тным для файла APK. Стан­дар­тны­ми счи­тают­ся исключительно фай­лы с име­нами из сле­дующе­го мас­сива:

При сбор­ке файла APK все неиз­вес­тные фай­лы сжи­мают­ся (тип сжа­тия DEFLATED), а фреймворк Xamarin желает уви­деть свои DLL нес­жатыми (STORED) и соответственно не может их прочитать.

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

Итак, начинаем рас­паковку:

Пос­ле рас­паков­ки, кроме при­выч­ных для APK фай­лов, видим папку assemblies с файлами dll. Из всех этих файлов нас инте­ресу­ет только одна биб­лиоте­ка, название которой сов­пада­ет с названием нашего при­ложе­ния. Ее‑то мы и будем вскрывать и исследовать.

Патчинг .Net

Ана­лиз DLL и поиск мес­та для вне­сения пра­вок выходит за рам­ки сегод­няшней статьи, так как мыс­лям на эту тему будет тес­но даже в кни­ге. Оста­нов­люсь лишь на тех­ничес­ких момен­тах. Как я писал выше, dnSpy отка­зал­ся ком­пилиро­вать исправ­ленную биб­лиоте­ку, поэто­му приш­лось при­бег­нуть к помощи Simple-assembly-explorer (SAE).

До­пус­тим, нам нужно, что­бы дан­ная фун­кция всег­да воз­вра­щала true:

Пос­коль­ку прав­ки мож­но вно­сить толь­ко в IL-код, в окне SAE перек­люча­емся на вклад­ку Details, где видим следующую кар­тину:

Тут есть два пути.

  1. По­дой­ти к делу осно­ватель­но, фун­дамен­таль­но, изу­чить язык CIL и написать необ­ходимый код самос­тоятель­но.
  2. На­писать нуж­ную фун­кцию на C# и ском­пилиро­вать в CIL, получив тем самым нуж­ный код авто­мати­чес­ки.

Я выб­рал вто­рой вари­ант — это намного быс­трее. Более того, нем­ножко погуг­лив, мож­но обна­ружить очень полез­ный сайт sharplab.io, на котором весь­ма удоб­но кон­верти­ровать код из C# в CIL.

Итак, вво­дим в левой вклад­ке сле­дующее:

и спра­ва сре­ди кучи лиш­него получа­ем:

Встав­ляем получен­ный код в биб­лиоте­ку с помощью Simple assembly explorer, не забывая при этом сох­ранить изме­нен­ную DLL. Если мы ничего не напута­ли и ниг­де не ошиб­лись, то пора собирать новый APK.

Сборка APK обратно

Для сбор­ки, как я уже писал выше, будем исполь­зовать 7z в режиме без сжа­тия. Получен­ный таким обра­зом APK будет боль­шего раз­мера, чем исходный, ну да раз­мер не глав­ное:

Не­боль­шое пояс­нение:

  • -tzip — фор­мат архи­ва,
  • -mx0 — отсутс­твие сжа­тия,
  • -r0 — рекур­сивный обход всех под­катало­гов

Да, перед сбор­кой луч­ше уда­лить каталог META-INF, содер­жащий ста­рую под­пись. Он не нужен, ведь нам при­дет­ся под­писывать APK самос­тоятель­но. Затем нуж­но соз­дать сер­тификат для под­писи и помес­тить его в хра­нили­ще.

Если у вас уже есть сер­тификат, то этот шаг мож­но про­пус­тить. Соз­даем сер­тификат с помощью ути­литы keytool из сос­тава JDK:

Она задаст стан­дар­тные воп­росы:

Ну и пос­ле это­го мож­но перехо­дить к под­писыва­нию:

В резуль­тате будет соз­дан поч­ти готовый к уста­нов­ке файл

«Поч­ти» — потому что перед исполь­зовани­ем его сле­дует выров­нять прог­раммой zipalign из сос­тава build-tools SDK Android. Дан­ная про­цеду­ра гаран­тиру­ет, что все нес­жатые фай­лы в архи­ве выров­нены отно­ситель­но начала фай­ла.

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

Итак, ров­няем:

Пос­ле это­го мож­но сме­ло уста­нав­ливать прог­рамму на телефон или эму­лятор и прис­тупать к ее тес­тирова­нию.

Заключение

Как видите, приложениея C# в сборке Xamarin ничуть не слож­нее для ана­лиза, чем род­ные при­ложе­ния ОС Android, надо лишь учесть некото­рые тон­кости при сбор­ке APK.

Полезные ссылки:

Дима (Kozhuh)

Эксперт в кибербезопасности. Работал в ведущих компаниях занимающихся аналитикой компьютерных угроз. Анонсы новых статей в Телеграме.

Добавить комментарий