- Реверс-инжиниринг
- Apktool
- dex2jar
- JD-GUI
- Burp Suite
- Разбор вредоносной программы
- Activation
- SmsReciever
- MainService
- ServerSession
- Android App Reverse Engineering 101
- Table of Contents
- 2. Android Application Fundamentals
- Build an App
- Fundamentals Review
- Dalvik & Smali
- Application Entry Points
- Launcher Activity
- Services
- Broadcast Receivers
- Exported Components (Services & Activities)
- Application Subclass
Реверс-инжиниринг
Вы потеряли исходник своей программы и вам нужно восстановить код. Вы скачали программу с вирусом и хотите узнать, что он делает.
Программы под Android распространяются в архивах. Эти архивы имеют расширение «.apk». Такие файлы не шифруются и являются по сути файлами «zip». Можете переименовать apk-файл в zip, чтобы убедиться в этом.
Вам необходимо поковыряться в APK-файле и получить какие-то данные. Можно потренироваться на кошках. Возьмём свою программу «Hello Kitty», найдём его apk-файл в папке проекта app\build\outputs\apk и переместим в отдельную папку для опытов.
Распаковав архив, вы можете увидеть структуру приложения и встретить знакомые файлы. И даже извлечь некоторые файлы для просмотра. К примеру, в папке res/drawable-hdpi-v4 я нашёл свою картинку pinkhellokitty.png. Казалось бы, вот оно — счастье. Но погодите радоваться. Если с изображениями проблем нет, то с чтением XML-файл вас ждёт облом. Какие-то строки вам видны, но в целом текст совершенно нечитаем. Поэтому сначала пойдём другим путём.
Так как пользовательские приложения для Android выполняются в java-машине, то APK-файлы наследуют все характерные черты JAR-файлов.
Содержимое архива обычно выглядит примерно так:
Каталог META-INF содержит:
CERT.RSA — сертификат приложения
CERT.SF — контрольные суммы файлов ресурсов (картинок, звуков и т.д.)
MANIFEST.MF — служебная информация, описывающая сам apk-файл
Каталог res содержит ресурсы — значки в нескольких разрешениях, описание размещения элементов на форме в xml-файле.
AndroidManifest.xml — служебная информация о приложении. В этом файле содержатся и так называемые «permission» — разрешения, которые требуются для работы приложения (например, доступ к сети или доступ к телефонной книге).
classes.dex — исполняемый код приложения. Именно этот файл интересует нас в первую очередь.
resources.arsc — таблица ресурсов. В этом файле собраны xml-описания всех ресурсов.
Вот и вся краткая информация, которую нужно знать, приступая к разбору вредоносных программ под Android.
Теперь рассмотрим популярные утилиты, используемые для изучения программ.
Apktool
Для начала скачиваем утилиту Apktool, который представляет собой jar-файл с номером версии. Для удобства переименовываем его в короткий вид apktool.jar, так как будем работать в командной строке. Подопытный файл разместите в той же папке с утилитой.
Запускаем в окне командной строки утилиту с флагом d:
Появится отдельная папка, имя которой будет совпадать с именем вашего файла. Зайдите в неё и исследуйте файлы. Вы заметите, что XML-файлы теперь доступны для чтения в нормальном виде. Таким образом, мы можем открыть файл activity_main.xml и узнать разметку своей активности.
В папке вы также найдёте множество системных файлов, которые проект тянет с собой при создании приложения. На них не обращаем внимания. Вам нужно искать только те файлы, которые создавали программисты, хакеры, вы.
При изучении своей или чужой программы вам надо посмотреть на файл манифеста, чтобы узнать используемые разрешения, список активностей, сервисов и т.д. А в папке res изучить все ресурсы, относящиеся к программе.
Моя тестовая программа была слишком проста. В других примерах могут быть дополнительные папки, например, assets, которая может содержать файлы, картинки и т.д. Там могут находиться html-файлы с сценариями на Javascript, которые ведут на вредные страницы.
В папке smali находятся уже файлы классов с тем же расширением smali. Код выглядит как в ассемблере и при желании можно понять листинг, но очень неудобно. Оставив файлы пока в покое.
Первую часть задачи мы выполнили.
dex2jar
Вторая утилита dex2jar, позволяет преобразовать файлы dex в jar. Скачиваем последнюю версию и распаковываем архив утилиты. Утилита содержит множество файлов для различных ситуаций. Можете поизучать их на досуге.
Запускаем команду d2j-dex2jar.bat app-debug.apk и получаем на выходе файл app-debug-dex2jar.jar. Это стандартный тип файлов для Java, но для нас пока не слишком полезный. Тем не менее мы выполнили второй шаг и получили промежуточный файл.
JD-GUI
Утилита, которая поможет нам прочитать jar-файл, называется JD-GUI. На странице разработчика можно найти ссылки на плагины к средам разработки и даже онлайн-версию.
Скачиваем последнюю версию и распаковываем архив. Там всего два файла — исполняемый exe-файл и readme.txt
Запускаем программу и перетаскиваем на него jar-файл. И весь код на ладони.
Обратите внимание, что код немного будет отличаться. Например, код в студии:
Сравните с кодом в утилите.
Иными словами, вместо констант из класса R подставляются их реальные значения. Вам придётся попотеть, чтобы сопоставить данные. Но вы справитесь, я в вас верю.
Burp Suite
Burp Suite позволит вам просматривать HTTP-траффик на эмуляторе. Скачайте последнюю версию.
Далее следует настроить прокси и другие параметры.
Разбор вредоносной программы
В качестве примера возьмем программу suspicious.apk, который детектируется разными антивирусами как вредоносная программа.
Чтобы лучше понять, что именно искать, нужно проанализировать файл «AndroidManifest.xml» — посмотреть, какие именно разрешения требуются анализируемому приложению. Данный файл бинарный, а не обычный текстовый xml. Для того, чтобы его прочитать нужно воспользоваться консольной утилитой «aapt» из комплекта Android SDK. Она находится в каталоге «platform-tools». Так как графического интерфейса нет, то команду нужно вводить в консоли. Например, для Windows:
Разумеется, вы должны подставить свои пути. В Linux команда будет такой же с очевидными отличиями (не будет букв дисков и расширения «exe» у утилиты). Для большего удобства вывод можно перенаправить в файл:
В файле нужно найти секцию «Android manifest» и искать перечисление разрешений. В анализируемом файле это выглядит так:
Из этой информации становится понятно, что программа может получать состояние телефона (сюда включаются, например «телефон в режиме вызова», «телефон в режиме принятия данных»). Это разрешение нужно и для получения номера телефона, на котором запущена программа, работать с сетью и мониторить приход СМС. На этих аспектах и нужно сосредоточить внимание при дальнейшем анализе.
Для того, чтобы получить доступ к коду нужно выполнить два шага — преобразовать apk-файл в jar-файл и декомпилировать полученный байткод в более понятный для человека вид.
Воспользуемся конвертером «dex2jar»:
Сконвертированный файл будет находится в том же каталоге, что и оригинальный файл. К его имени будет добавлено «.dex2jar.jar», то есть в данном примере это будет «suspicious.apk.dex2jar.jar».
Этот файл можно открыть декомпилятором. Иерархия пакета в окне декомпилятора выглядит так:
На этом подготовительные шаги заканчиваются — дальнейший успех зависит только от вашего знания Java и умения пользоваться поисковиком.
К счастью, экземпляр выбранный для примера имеет довольно скромные размеры — финальный jar всего 7,01 KB.
В программе всего шесть классов. Исключим те, которые не представляют интереса. Это класс R, в котором только перечислены идентификаторы всех ресурсов. Так же из рассмотрения можно исключить класс Config, в котором содержится конфигурация сборки.
Рассмотрим подробнее оставшиеся три класса.
Activation
Этот класс срабатывает по событию onCreate(), то есть сразу после старта приложения.
TelephonyManager localTelephonyManager = (TelephonyManager)getSystemService(«phone»); — создает localTelephonyManager, в которую помещает данные об устройстве.
str1 = localTelephonyManager.getDeviceId(); — выбирает из полученных данных идентификационный номер устройства и помещает его в строку str1
Дальше идет цикл, который делит DeviceId на кусочки по четыре цифры, вставляя между ними дефис «-«, то есть из XXXXXXXXXXXXXXXX получается XXXX-XXXX-XXXX-XXXX. Полученную строку цифр и дефисов передают в TextView с идентификатором 2131034112.
SmsReciever
Этот класс срабатывает при приходе СМС-сообщения, событие onReceive().
В задачу этого класса входит отслеживать входящие смс и в случае обнаружения запускать класс MainService, передавая ему указатель на новое пришедшее сообщение.
MainService
Этот класс довольно велик, поэтому не стану приводить его целиком. Сразу после вызова запускает субкласс «SmsBlockerThread», который блокирует уведомление о поступившем СМС, чтобы пользователь не был оповещен о новом входящем СМС.
Затем входящее СМС обрабатывается таким образом:
String str1 = localSmsMessage.getOriginatingAddress(); — номер телефона-получателя (то есть номер телефона, на котором установлен троянец) помещается в переменную str1.
String str2 = localSmsMessage.getMessageBody(); — тело сообщения помещается в переменную str2
Затем создаются связанные пары localBasicNameValuePair1 и localBasicNameValuePair2 в которые помещаются значения
Эти пары сохраняют в массив localArrayList, в который позже добавляют пару localBasicNameValuePair3, представляющую собой устройства>
При этом, как видите, DeviceId получается заново, а не используется то, что было получено в классе Activation. Заканчивается тем, что вызывается метод postRequest() из последнего класса ServerSession:
В качестве параметра передается тот самый массив пар, в котором номер телефона, содержимое СМС и идентификатор устройства.
ServerSession
Этот класс имеет два метода: initUrl(), который возвращает часть ссылки «(http://softthrifty.com/security.jsp)»:
и большой метод postRequest(), который вызывался из класса MainService. Несмотря на размер, задача postRequest() проста — отправить на сервер по ссылке, возвращаемой методом initUrl(), данные, добавив пары из массива, собранного в MainService. То есть всего лишь обратиться по ссылке:
Итак, данный троянец перехватывает СМС и отправляет на сервер запрос, в котором передает номер зараженного телефона, содержимое СМС и идентификатор зараженного телефона. Такое поведение может быть признаком банковского троянца, атакующего двухфакторную авторизацию. Для успешной атаки требуется выполнение таких условий:
1) злоумышленник должен заразить компьютер жертвы, чтобы перехватить данные для он-лайн банкинга;
2) злоумышленник должен заразить телефон жертвы для перехвата СМС с кодом подтверждения от банка;
3) злоумышленник должен каким-то образом связать пользователя зараженного компьютера и зараженного телефона, чтобы знать, от каких учетных данных он-лайн банкинга данный код подтверждения;
В силу своих размеров и очевидности производимой деятельности такой образец хорошо подходит для демонстрации базовых приемов разбора вредоносных программ под Андроид.
Источник
Android App Reverse Engineering 101
Learn to reverse engineer Android applications!
Table of Contents
2. Android Application Fundamentals
Build an App
One of my biggest suggestions for folks looking to reverse engineer things, whatever they may be, is to try and build what you want to reverse. In the case of Android, you’re lucky because there are so many free resources available to build your first application. If you’ve never built an Android application before, I suggest you start there. Pick any of the available tutorials and videos that spark your interest and get to building. When you understand how a developer builds something, it makes it much easier to understand how to reverse engineer it.
Fundamentals Review
Great! You’ve built an app or learned basic Android app development principles. Here is a review of some of the important points. This “Application Fundamentals” page in the Android developers’ docs is a great review.
- Android applications are in the APK file format. APK is basically a ZIP file. (You can rename the file extension to .zip and use unzip to open and see its contents.)
- APK Contents (Not exhaustive)
- AndroidManifest.xml
- META-INF/
- Certificate lives here!
- classes.dex
- Dalvik bytecode for application in the DEX file format. This is the Java (or Kotlin) code that the application will run by default.
- lib/
- Native libraries for the application, by default, live here! Under the lib/ directory, there are the cpu-specific directories. Ex: armeabi, mips,
- assets/
- Any other files that may be needed by the app.
- Additional native libraries or DEX files may be included here. This can happen especially when malware authors want to try and “hide” additional code, native or Dalvik, by not including it in the default locations.
Dalvik & Smali
Most Android applications are written in Java. Kotlin is also supported and interoperable with Java. For ease, for the rest of this workshop, when I refer to “Java”, you can assume that I mean “Java or Kotlin”. Instead of the Java code being run in Java Virtual Machine (JVM) like desktop applications, in Android, the Java is compiled to the Dalvik Executable (DEX) bytecode format. For earlier versions of Android, the bytecode was translated by the Dalvik virtual machine. For more recent versions of Android, the Android Runtime (ART) is used.
If developers, write in Java and the code is compiled to DEX bytecode, to reverse engineer, we work the opposite direction.
Smali is the human readable version of Dalvik bytecode. Technically, Smali and baksmali are the name of the tools (assembler and disassembler, respectively), but in Android, we often use the term “Smali” to refer to instructions. If you’ve done reverse engineering or computer architecture on compiled C/C++ code. SMALI is like the assembly language: between the higher level source code and the bytecode.
For the following Hello World Java code:
The Smali code would be:
The Smali instruction set is available here.
Most often when reverse engineering Android applications, you will not need to work in Smali. Most applications can be lifted to an even higher level, decompiled Java. Like all tools, Java decompilers may have bugs. My suggestion to you is that whenever the decompiled Java output looks questionable, look at the Smali output. Work line by line with the instruction reference to figure out what the code is doing.
To get the Smali from DEX, you can use the baksmali tool (disassembler) available at https://github.com/JesusFreke/smali/wiki. The smali tool will allow you to assemble smali back to DEX.
Application Entry Points
One of the most important points of reverse engineering is knowing where to begin your analysis and entry points for code execution is an important part of that.
Launcher Activity
The launcher activity is what most people think of as the entry point to an Android application. The launcher activity is the activity that is started when a user clicks on the icon for an application. You can determine the launcher activity by looking at the application’s manifest. The launcher activity will have the following MAIN and LAUNCHER intents listed.
Keep in mind that not every application will have a launcher activity, especially apps without a UI. Examples of applications without a UI (and thus a launcher activity) are pre-installed applications that perform services in the background, such as voicemail.
Services
Services run in the background without a UI. There are a myriad of ways that they can be started and thus are an entry point for applications. The default way that a service can be started as an entry point to an application is through Intents.
When the startService API is called to start a Service, the onStart method in the Service is executed.
Broadcast Receivers
Broadcasts can be thought of a messaging system and broadcast receivers are the listeners. If an application has registered a receiver for a specific broadcast, the code in that receiver is executed when the system sends the broadcast. There are 2 ways that an app can register a receiver: in the app’s Manifest or dynamically registered in the app’s code using the registerReceiver() API call.
In both cases, to register the receiver, the intent filters for the receiver are set. These intent filters are the broadcasts that should trigger the receiver.
When the specific broadcasts are sent that the receiver is registered for are sent, onReceive in the BroadcastReceiver class is executed.
Exported Components (Services & Activities)
Services and Activities can also be “exported”, which allows other processes on the device to start the service or launch the activity. The components are exported by setting an element in the manifest like below. By default, android:exported=»false» unless this element is set to true in the manifest or intent-filters are defined for the Activity or Service.
Application Subclass
Android applications can define a subclass of Application. Applications can, but do not have to define a custom subclass of Application. If an Android app defines a Application subclass, this class is instantiated prior to any other class in the application.
If the attachBaseContext method is defined in the Application subclass, it is called first, before the onCreate method.
This project is maintained by maddiestone
Hosted on GitHub Pages — Theme by orderedlist
Источник