R0 CREW

Реверсинг Android приложений

Оригинал: resources.infosecinstitute.com

Intro

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

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

За кулисами

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

Android приложения в действительности являются приложениями Java, базирующимися вокруг “R” класса Google, который расширяет java.lang.Object. Все приложения используют Android API, разработанный Google. Из других компонентов, используемых приложениями, следует выделить конфигурационные XML файлы (AndriodManifest.xml, strings.xml, main.xml и некоторые другие), которые определяют: права доступа, требуемые приложениям; графические ресурсы; расположение элементов на экране и т.д.

В конечном счете, после компиляции в байт-код, приложения представляют собой файлы .dex (Dalvik Executable). Эти .dex файлы интерпретируются виртуальной машиной Dalvik и выполняются в виде приложений. Мы поговорим больше о формате этих файлов, когда рассмотрим инструменты, с помощью которых можно реверсить Android приложения.

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

Краткая схема разработки приложений под Android

При взламывании .apk архивов, очень полезно иметь общее представление о процессе разработки под Android. Ниже дана обобщенная, высокоуровневая версия этого процесса, которая даст вам общее представление о том, как все это работает:

  • Установка среды разработки для Android. Google подробно описал этот процесс в документе, названном, «Installing the SDK», который расположен тут.
  • Разработка кода на Java. Позже мы рассмотрим простое приложение.
  • Создание пакетов. Это может быть сделано с помощью Eclipse IDE или с помощью инструментов командной строки.
  • Тестирование приложения в VM или на реальном устройстве.
  • Размещение в Маркете.

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

Теперь, когда у нас есть представление о том, как все работает, давайте заглянем внутрь .apk файла.

Внутренности пакетов

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

Вот краткий список важных пунктов, которые включены во все исходные проекты Android приложений:

  • AndroidManifest.xml – Это важный конфигурационный XML-файл, который определяет такие свойства как: имя пакета; минимально необходимую версию Android OS, на которой будет запущено приложение; иконку и т.д. Одним из наиболее известных свойств Android приложений определенных в этом конфигурационном файле является определение «прав доступа приложения».
  • /src – Место расположения ваших (.java) файлов.
  • /res – Папка ресурсов, которая содержит файлы, зависящие от пользовательского интерфейса. Графика и XML-документы обычно расположены здесь.
  • /res/layout/main.xml – Этот конфигурационный файл содержит определения, которые управляют дизайном основного приложения.
  • /res/values/strings.xml – Как можно догадаться, файл содержит строки. Это статические определения строк, на которые ссылается ваше приложение. Одним важным определением является «app_name», которое содержит имя вашего приложения. Имя файла ‘strings.xml’ является значением по умолчанию.

При реверсинге .apk файлов, вы, вероятно, встретитесь с этими файлами:

  • AndroidManifest.xml – Это тот же самый конфигурационный файл, что находится в вашем исходном проекте, только «этот» преобразован в двоичный формат.
  • /META-INF – Эта папка содержит следующие файлы: CERT.RSA, CERT.SF, и MANIFEST.MF. Эти файлы содержат цифровой сертификат приложения, а так же относительный путь и SHA1-хэш для каждого файла в .apk.
  • classes.dex – Архив .dex содержит все файлы Java классов (.class).

Безопасность

Ранее, мы упоминали, что конфигурационный файл AndroidManifest.xml содержит определения прав доступа приложения (application permission). В следующей строке дан пример директивы для добавления прав доступа в приложение:

<uses-permission android:name="android.permission.INTERNET" />

Значение «android.permission.INTERNET» указывает на то, какое разрешение требуется. Конкретно это значение позволяет приложению создавать сетевые сокеты, фактически давая ему доступ в Интернет. В таблице ниже дан список других общих значений. Для получения исчерпывающего списка, смотрите страницу android.Manifest.permission.

Некоторые общие значения из android.Manifest.permission:

  • ACCESS_COARSE_LOCATION - Allows coarse location access (Cell / WiFi)
  • ACCESS_FINE_LOCATION - Allows fine location access (GPS)
  • ACCESS_WIFI_STATE - Разрешает доступ к получению информации о состоянии WiFi сети
  • GET_ACCOUNTS - Разрешает доступ к списку аккаунтов устройства
  • INTERNET - Разрешает сетевое взаимодействие
  • READ_CONTACTS - Разрешает доступ к данным контактов
  • VIBRATE - Разрешает доступ к управлению вибрацией
  • WRITE_EXTERNAL_STORAGE - Разрешает запись на внешнее устройство

Присутствие этих записей в AndroidManifest.xml является причиной появления следующего диалогового окна от Android Market:

Reversing

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

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

apktool – инструмент, используемый для работы с .apk файлами
Download: http://code.google.com/p/android-apktool/

jad – декомпилятор Java (только для Windows)
Download: http://www.varaneckas.com/jad

JD-Core + JD-GUI – еще один декомпилятор, поддерживающий более новые версии и функции Java
Download: http://java.decompiler.free.fr

dex2jar – инструмент для преобразования .dex файлов в файлы .class
Download: http://code.google.com/p/dex2jar/downloads/list (dex2jar)

Процесс декомпиляции / реверсинга Android приложений – следующий:

  • Скачайте приложение, которое вы хотите проанализировать, из Маркета на ваше Android устройство.
  • Скопируйте .apk файл из вашего устройства на компьютер. Для этого действия требуется полный доступ к файловой системе устройства. Я использовал порутанный Motorola Droid для этих целей. По умолчанию путь к файлам .apk следующий /data/app.

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

java –jar apktool.jar d file.apk destination_directory

Это позволит распаковать .apk файл, воссоздав структуру каталогов проекта. Также это преобразует двоичный XML файл в текстовый XML. Это быстрый и простой способ исследовать AndroidManifest.xml для того, чтобы увидеть какие именно права доступа требуются приложению. Помимо всего прочего, во время распаковки, .dex код будет преобразован в формат .smali. Формат .smali, по сути, представляет дизассемблированную версию байт-кода .dex. Это примерно то же самое, что использовать программу, генерирующую ассемблерный код для бинарных программ, которые написаны на языке C. Пока вы не получите оригинальный исходный код от этого процесса, у вас будет очень точное представление оригинального исходного кода, которое может быть преобразовано обратно в байт-код.

Если цель заключается в том, чтобы исследовать исходный код .java, то необходим ручной подход. Этот процесс подробно описан ниже.

  • Распакуйте .apk файл.
  • Преобразуйте clasees.dex в .jar файл
dex2jar classes.dex
  • Распакуйте .jar файл.
  • Декомпилируйте байт-код с помощью jad (или аналогичной утилиты)
jad –s .java *.class

На данный момент, у вас есть исходный код Java, который, по сути, эквивалентен оригинальному коду приложения. Если скомбинировать два эти метода, то можно получить хорошее понимание того, как работает исследуемое приложение. Тут вы можете спросить себя, что нам делать дальше? Давайте посмотрим на более практические вещи, которые мы можем сделать помимо простого анализа исходных файлов.

Переходим на следующий уровень

Одной из вещей, которую можно рассмотреть, является то, как можно изменить приложение и пересобрать его для последующей установки на ваше устройство. С точки зрения безопасности, самыми легкими целя при реверсинге Android приложений, используя описанные выше методы, являются конфигурационные XML-файлы. Изменения этих файлов не требуют изменения исходного кода Java. Так же это позволяет изменить права доступа предоставляемые всему приложению. Еще это может быть полезным, если вы хотите препятствовать возможности приложения получать доступ к определенным ресурсам или просто, чтобы добавить дополнительные разрешения. Хорошим примером этого является удаление android.permission.INTERNET из AndroidManifest.xml. Это бы эффективно препятствовало созданию сетевых соединений приложением, возможно, с целью отключения встроенной рекламы. Однако, воздействия такого изменения намного меньше, чем те из изменений, которые основаны на непосредственно изменении исходного кода Java.

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

Есть несколько проблем связанных с изменением исходного кода и переупаковкой существующего Android приложения. Во-первых, пакет должен быть подписан с помощью ключа. Существует отладочный ключ, который используется для тестирования приложений на виртуальных машинах и устройствах. Однако, подпись, сделанная с помощью этого ключа, имеет несколько побочных эффектов. Вы не сможете устанавливать программы из Маркета + Android устройство должно разрешать установку программ из неизвестных источников. Другой проблемой состоит в том, что инструмент zipalign не будет использован для пакета. Согласно документации Android, это заставит приложение использовать больше памяти. This could make rolling your own applications undesirable without a developer key.

Стоит заметить, что имеется приложение, которое делает тоже, что было описано в предыдущих двух параграфах. То есть, распаковывает .apk файлы, проверяет и удаляет нежелательные права доступа из AndroidManifest.xml, затем пересобирает и переустанавливает пакеты, подписав их валидным ключом. Называется оно Privacy Blocker и доступно в Android Market. Вы можете почитать о нем больше тут.

Демонстрационный пример

Для того, чтобы проиллюстрировать некоторые из пунктов, которые мы рассмотрели в этой статье, я создал очень простое приложение. Эта программа просто получает иконку Google из заранее предопределенного URL и отображает ее в контейнере Webview. Этому приложению требуется android.permission.INTERNET.

На следущем скриншоте показано приложение с соответствующими правами доступа (слева) и приложение с удаленными правами (справа).

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

Вы можете загрузить исходный код тут, а приложение тут.

В заключение

Мы рассмотрели, какие компоненты содержит Android приложение, как распаковать .apk, чтобы исследовать его содержание, а так же какие инструменты можно использовать для дальнейшего анализа компонентов программы. Мы также рассмотрели основные права доступа в AndroidManifest.xml, как они позволяют получать доступ к ресурсам устройства, а также где и как изменить эти средства управления.

© Translated by Prosper-H from r0 Crew