Security in android application

Содержание
  1. How to Secure an Android App
  2. Introduction
  3. 1. Use Internal Storage for Sensitive Data
  4. 2. Encrypt Data on External Storage
  5. 3. Use Intents for IPC
  6. 4. Use HTTPS
  7. 5. Use GCM Instead of SMS
  8. 6. Avoid Asking for Personal Data
  9. 7. Validate User Input
  10. 8. Use ProGuard Before Publishing
  11. Conclusion
  12. Android Security: Guide to Android OS
  13. Introduction to the Android Operating System and Android Security Features (including Android Application Security)
  14. Secure Coding Handbook
  15. Android’s Five Key Security Features:
  16. Android Security: System-Level Security Features
  17. Android Application Security Features
  18. Android Application Security Scans
  19. Android Security: Geared Towards User-Friendly Security
  20. Проблемы безопасности Android-приложений: классификация и анализ
  21. 1. Устройство ОС Android
  22. 2. Проблемы безопасности
  23. 2.1. Уязвимости ядра Linux и его модулей
  24. 2.2. Уязвимости модификаций и компонентов производителей устройств
  25. 2.3. Уязвимости модулей в машинных кодах
  26. 2.4. Уязвимости механизмов межкомпонентного взаимодействия
  27. 2.5. Уязвимости в самих приложениях
  28. 2.6. Уязвимости во встроенных сервисах и библиотеках
  29. 2.7. Интернет-источники
  30. 2.8. Уязвимости аппаратуры и связанных с ней модулей и протоколов
  31. 3. Инструменты для анализа Android-приложений
  32. Статический анализ
  33. Динамические и смешанные инструменты анализа
  34. 4. Идеальная система полносистемного анализа платформы Android
  35. 1. Поддержка загрузки прошивок от производителей различных устройств
  36. 2. Возможность исполнения отдельных кусков машинного кода на реальном устройстве
  37. 3. Проброс данных от датчиков оборудования реальных устройств в эмулятор
  38. 4. Совместный анализ на уровне Java-кода и машинного кода
  39. 5. Поддержка анализа межкомпонентного взаимодействия
  40. 6. Защита от статических эвристик обнаружения
  41. 7. Минимальные изменения прошивок Android
  42. 8. Поддержка полносистемного анализа помеченных данных с отслеживанием потоков управления
  43. 9. Поддержка символьного исполнения и частичного исполнения с конкретными значениями с использованием данных, полученных из статического анализа кода (concolic execution — смешанное исполнение)
  44. Заключение

How to Secure an Android App

Introduction

The Android operating system has lots of built-in security features, such as application sandboxing, protection against buffer and integer overflow attacks, and segregated memory areas for program instructions and data. As a result, simple Android apps that don’t perform any file system or networking operations can often be considered secure by default.

If you are developing a more complex app, however, it is your responsibility to make it secure and protect the privacy of your users. In this article, I’m going to list some of the best practices you can follow to build a secure Android app that doesn’t leak data or permissions, and is, in general, less vulnerable to malicious apps that might be installed on the user’s device.

1. Use Internal Storage for Sensitive Data

Every Android app has an internal storage directory associated with it whose path is based on the package name of the app. Files inside this directory are very secure because they use the MODE_PRIVATE file creation mode by default. This means the files cannot be accessed by any other app on the device. Therefore, it is a best place to store all the sensitive data of your app in the internal storage directory.

To determine the absolute path of your app’s internal storage directory, it is recommended that you use the getFilesDir() method. Once you know its path, referencing files inside it is as simple as referencing files inside any other directory. For example, here’s how you could reference a file called myfile.dat in the internal storage directory of your app:

2. Encrypt Data on External Storage

The internal storage capacity of an Android device is often limited. Therefore, at times, you might have no choice but to store sensitive data on external storage media, such as a removable SD card.

Because data on external storage media can be directly accessed by both users and other apps on the device, it is important that you store it in an encrypted format. One of the most popular encryption algorithms used by developers today is AES, short for Advanced Encryption Standard, with a key size of 256 bits.

Writing code to encrypt and decrypt your app’s data using the javax.crypto package, which is included in the Android SDK, can be confusing. Therefore, most developers prefer using third party libraries, such as Facebook’s Conceal library, which are usually much easier to work with.

3. Use Intents for IPC

Experienced programmers who are new to Android application development often try to use sockets, named pipes, or shared files to asynchronously communicate with other apps installed on an Android device. These approaches are not only hard and inelegant, but also prone to threats. An easier and more secure approach to interprocess communication on the Android operating system is to use intents.

To send data to a specific component of an app, you must create a new instance of the Intent class and use its setComponent() method to specify both the package name of the app and the name of the component. You can then add data to it using the putExtra() method.

For example, here’s how you could send the string Hello World to an Activity called MyActivity, which belongs to an app whose package name is my.other.app:

To send data to multiple apps at once, you can send the intent as a broadcast using the sendBroadcast() method. However, by default, a broadcast can be read by any app that has an appropriately configured BroadcastReceiver .

Therefore, if you want to send sensitive information as a broadcast, you must use a custom permission whose protectionLevel is set to signature . By doing so, the Android operating system makes sure that only apps that were signed using your signing key can receive the broadcast.

Here’s a code snippet that shows you how to send the string Hello World as a secure broadcast:

Note that the above code works as expected only if the custom permission is declared and used in the manifest files of both the sender and receiver apps.

4. Use HTTPS

All communications between your app and your servers must be over an HTTPS connection, preferably using the HttpsURLConnection class. If you think using HTTP for data that is not confidential is fine, think again.

Many Android users connect to several open Wi-Fi hotspots in public areas every day. Some of those hotspots could be malicious. A malicious hotspot can easily alter the contents of HTTP traffic to make your app behave in an unexpected manner, or worse still, inject ads or exploits into it.

By using HTTPS, as long as the server is configured with a certificate issued by a trusted certificate authority, such as DigiCert or GlobalSign, you can be sure that your network traffic is secure against both eavesdropping and man-in-the-middle attacks.

If your app has a lot of networking code and you are afraid that you might unwittingly be sending some data as cleartext, you should consider using nogotofail, an open source tool built by Google to find such mistakes.

5. Use GCM Instead of SMS

Back when GCM, short for Google Cloud Messaging, didn’t exist, many developers were using SMS to push data from their servers to their apps. Today, this practice is largely gone.

If you are one of those developers who still hasn’t made the switch from SMS to GCM, you must know that the SMS protocol is neither encrypted nor safe against spoofing attacks. What’s more, an SMS can be read by any app on the user’s device that has the READ_SMS permission.

GCM is a lot more secure and is the preferred way to push messages to an app because all GCM communications are encrypted. They are authenticated using regularly refreshed registration tokens on the client side and a unique API key on the server side. To learn more about GCM, you can refer to this tutorial about push notifications .

6. Avoid Asking for Personal Data

User privacy is given a lot of importance these days. In fact, there are laws, such as the European Union’s Data Protection Directive and Canada’s Personal Information Protection and Electronic Documents Act, which mandate the protection of the privacy of a user. Therefore, unless you have a good reason and a very secure infrastructure to collect, store, and transmit personal user information, you must avoid directly asking for it in your apps.

A better approach to user authentication and user profile information look up on Android is through the Google Identity Platform . Google Identity Platform allows users to quickly sign in to your app using their Google account. After a successful sign in through the platform, whenever necessary, your app can easily look up various details about the user, such as the user’s name, email address, profile photo, contacts, and more. Alternatively, you could use free services like Firebase that can manage user authentication for you.

If you must handle user credentials yourself, it is recommended that you store and transmit them in the form of secure hashes. The most straightforward way to generate different types of hashes using the Android SDK is by using the MessageDigest class.

Here’s a little code snippet that shows you how to create a hash of the string Hello World using the SHA-256 hashing function:

7. Validate User Input

On Android, invalid user input doesn’t usually lead to security issues like buffer overruns. However, if you allow users to interact with a SQLite database or a content provider that internally uses a SQLite database, you must either rigorously sanitize user input or make use of parameterized queries. Failing to do so makes your data vulnerable to SQL injection attacks.

On a similar note, user input validation and sanitization is also very important if you are using user input to dynamically generate code to run on an embedded scripting engine, such as Mozilla Rhino .

8. Use ProGuard Before Publishing

Security measures built into an Android app can be severely compromised if attackers are able to get their hands on the source code. Before you publish your app, it is recommended to make use of a tool called ProGuard, which is included in the Android SDK, to obfuscate and minify source code.

Читайте также:  Как проверить скорость памяти андроид

Android Studio automatically includes ProGuard in the build process if the buildType is set to release . The default ProGuard configuration available in the Android SDK’s proguard-android.txt file is sufficient for most apps. If you want to add custom rules to the configuration, you can do so inside a file named proguard-rules.pro, which is a part of every Android Studio project.

Conclusion

I hope you now have a better understanding of how to make your Android apps secure. Most of the best practices I mentioned in this article are applicable only if you are using the Android SDK to develop your apps. If you are using the Android NDK instead, you have to be a lot more careful because, while programming in the C language, you are expected to manage low-level details, such as pointers and memory allocation yourself.

To learn more about security on Android, you can refer to the AOSP security documents.

Источник

Android Security: Guide to Android OS

Introduction to the Android Operating System and Android Security Features (including Android Application Security)

Android is a Linux kernel mobile platform. Android runs on a wide range of devices, from mobile smartphones and tablets, to set-top boxes. The Android mobile operating system is dependent upon the mobile device’s processer capabilities for its performance.

Security is a major part of any Android device. Android was created with openness in mind, and is conducive to the use of third-party applications and cloud-based services. Android seeks to be a secure and usable operating system for mobile platforms.

Secure Coding Handbook

Android’s Five Key Security Features:

1. Security at the operating system level through the Linux kernel

2. Mandatory application sandbox

3. Secure interprocess communication

4. Application signing

5. Application-defined and user-granted permissions

Android Security: System-Level Security Features

The Linux kernel provides Android with a set of security measures. It grants the operating system a user-based permissions model, process isolation, a secure mechanism for IPC, and the ability to remove any unnecessary or potentially insecure parts of the kernel. It further works to prevent multiple system users from accessing each other’s resources and exhausting them.

Android Application Security Features

This user-based protection allows Android to create an “Application Sandbox.” Each Android app is assigned a unique user ID, and each runs as a separate process. Therefore, each application is enforced at the process level through the Linux kernel, which does not allow applications to interact with one another, and gives them only limited access to the Android operating system. This gives the user permission-based access control, and he/she is presented with a list of the activities the Android application will perform and what it will require to do them, before the app is even downloaded. The same goes for filesystem permissions – each application (or user) has its own files, and unless a developer explicitly exposes files to another Android application, files created by one application cannot be read or altered by another.

Android Application Security Scans

When building and testing the security of Android apps, developers should follow Android security best practices and keep the following in mind when performing security tests:

  • Inbound SMS listeners (command and control)
  • Unsafe file creation
  • Improper database storage
  • Unsafe use of shared preferences
  • Storage of sensitive data on mass storage device
  • Content provider SQL injection
  • APN or proxy modification

Android Security: Geared Towards User-Friendly Security

All of Android’s more technical security features are designed to be simply presented to the user, meaning that they can be easily controlled through the interface. Straightforward methods of improving your Android device’s security can include: using a password or pin, setting your phone to lock after a period of inactivity, only enabling wireless connections that you use, and only installing Android apps you trust and have personally vetted.

Google also only allows tested and proven secure Android applications into its marketplace, meaning that the user has less of a chance of installing a malicious app. Furthermore, the Android security system prompts the user to allow the installation of an application, meaning that it is impossible to remotely install and run an application. Users can further ensure that their Android device is secure by regularly installing system updates.

Источник

Проблемы безопасности Android-приложений: классификация и анализ

Использование смартфонов в повседневной жизни не ограничивается голосовыми звонками и СМС. Возможность загружать и выполнять программы, а также мобильный доступ в Интернет привели к появлению громадного числа мобильных приложений. Функциональность современного смартфона составляют браузеры, клиентские программы социальных сетей, офисные приложения и всевозможные сервисы, работающие в Сети. Android-устройства заняли бóльшую часть рынка смартфонов за счет открытой архитектуры платформы Android и удобного API разработчика. На данный момент Android является наиболее популярной мобильной ОС с долей рынка более 75%. Количество приложений, загруженных из магазина Google Play, в 2016 году составило 65 миллиардов [1].

Параллельно наблюдается и бурный рост числа вредоносных приложений: в 2015 году их было обнаружено 2,3 миллиона [3]. Кроме того, около 60% Android-устройств работают на версиях ОС с известными уязвимостями, и они потенциально могут быть атакованы злоумышленниками [6]. Эти угрозы, в свою очередь, привели к развитию средств защиты. Официальный магазин Google Play ввел фильтрацию приложений с помощью песочницы Google Bouncer. Антивирусные компании стали выпускать свои продукты под Android (хотя, как показано в [8], многие из них сами по себе содержат опасные уязвимости). Число научных публикаций по данной теме также возросло: одна из обзорных работ 2015 года о решениях безопасности для Android [2] насчитывает более 40 проектов и упоминает далеко не все известные на данный момент исследования. В связи с тем, что мобильные устройства являются источником и хранилищем большого количества конфиденциальных данных, проблема безопасности ОС Android и ее приложений стоит особо остро.

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

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

1. Устройство ОС Android

В основе ОС Android лежит ядро Linux с некоторыми архитектурными изменениями, которые были сделаны инженерами Google. Приложения для операционной системы Android разрабатываются на языке Java. Начиная с версии Android 1.5 был представлен набор инструментов Android NDK, который позволяет разрабатывать модули приложений на языках С и С++ и компилировать их в машинный код [4]. Приложения поставляются в виде файлов специального формата APK, который является ZIP-архивом с определенной структурой каталогов и файлов. APK-файл приложения содержит:

  • манифест;
  • модули, скомпилированные в машинный код (разделяемые библиотеки .so);
  • различные ресурсы приложения;
  • DEX-файл;
  • прочие необходимые файлы.

Начиная с версии Android 4.4 поддерживаются две среды выполнения приложений: Dalvik VM и ART. Следует отметить, что процесс подготовки APK-файла не изменился, изменился только процесс установки приложений в новой среде выполнения ART. Начиная с версии 5.0 среда выполнения ART стала использоваться по умолчанию вместо Dalvik VM.

Среда выполнения Java-программ Dalvik VM на Android сильно отличается от «обычной» Java VM. Во-первых, при компиляции Java-программы она компилируется в байт-код виртуальной машины Dalvik, который сильно отличается от байт-кода виртуальной машины HotSpot. Виртуальная машина Dalvik является регистровой, что делает ее выполнение на RISC-архитектурах, часто используемых в мобильных устройствах, более эффективным. Также при разработке Dalvik учитывались ограничения памяти в мобильных устройствах. Начиная с версии Android 2.2 среда выполнения Dalvik содержит JIT-компилятор, который компилирует «горячие» куски кода Java-программ в машинный код [5].

Стандартные библиотеки Java были либо заменены на доработанные библиотеки из пакета Apache Harmony либо написаны заново. При компиляции Java-программы получается файл формата DEX (Dalvik Executable), который содержит байт-код для виртуальной машины Dalvik. Формат файла был разработан с целью сокращения объема занимаемой памяти и существенно отличается от стандартного формата JAR. Для вызова модулей, реализованных в машинном коде, из Java-программ используется интерфейс JNI. Стоит отметить, что имеется возможность подгружать машинные модули динамически по сети с помощью компонента DexClassLoader.

2. Проблемы безопасности

Родительским процессом для всех приложений в ОС Android является процесс Zygote. Данный процесс представляет собой каркас Android-приложения, в котором уже загружены все необходимые библиотеки окружения Android, но отсутствует код самого приложения. Запуск приложения Android с точки зрения операционной системы происходит следующим образом:

  1. Вначале происходит системный вызов fork для создания потомка от процесса Zygote (см. рис. 1).
  2. В этом новом процессе открывается файл запускаемого приложения (системный вызов open).
  3. Происходит чтение информации о файлах классов (classes.dex) и ресурсов из файла приложения. Происходит открытие сокетов для IPC.
  4. Выполняется системный вызов mmap для отображения файлов приложения в память.
  5. Среда выполнения производит настройку необходимого окружения и выполняет приложение (интерпретирует байт-код Dalvik или передает управление функциям в исполняемом коде в случае ART [7]).

На уровне ядра ОС Android каждое приложение является отдельным процессом с уникальными значениями user/group ID, которые даются ему при установке. Таким образом, каждая программа работает в своей песочнице. Начиная с версии 4.3 в дополнение к этой политике безопасности добавилось использование компонента мандатного контроля доступа SELinux [10].

Рис. 1. Запуск нового приложения в ОС Android

По умолчанию приложение ограничено в своих возможностях и не может сделать ничего, чтобы негативно повлиять на другое приложение или пользователя: ни прочитать пользовательские данные, ни модифицировать системные приложения; отсутствует доступ к сети. Для получения доступа к различным ресурсам приложение обращается к сервисам ОС Android. Разрешения на доступ задаются статически в файле манифеста приложения и выдаются приложению во время его работы по мере необходимости. Система запрашивает у пользователя согласие на выдачу этих разрешений во время установки или во время обновления приложения. Ответственность за выдачу доступа приложению лежит на пользователе, он самостоятельно решает, какому приложению давать разрешения на определенные действия, а какому не давать, — во время его установки. Использование такого подхода, при котором все разрешения выдаются разом при установке приложения, привело к тому, что пользователи стали раздавать полномочия приложениям, не задумываясь о последствиях. В свою очередь, приложения стали запрашивать все больше разрешений по мере расширения их функциональности. В Android 6 Marshmallow данная система заменена на другую: приложение запрашивает доступ к ресурсам у пользователя во время его работы, а пользователь может либо разрешить доступ, либо запретить его [11].

Читайте также:  Snapdragon 625 android 10

Android-приложение состоит из четырех видов компонентов и не содержит функции main() или какой-то другой единой точки входа. Компоненты приложений взаимодействуют друг с другом с помощью специальных сообщений, называемых Intent.

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

Компоненты под названием Service [9] производят фоновую обработку. Когда Activity нужно выполнить какую-то операцию, например загрузку файла или проигрывание музыки, и продолжить работу, когда пользователь перешел в другое приложение или свернул текущее, приложение запускает сервис, цель которого — выполнение этой операции. Разработчики могут использовать Service в качестве приложения-демона, стартующего во время загрузки системы. Компонент Service, как правило, поддерживает RPC (Remote Procedure Call), поэтому другие компоненты системы могут обращаться к нему.

Компонент Content provider сохраняет и обменивается данными, используя интерфейс реляционных баз данных. Каждый Content provider содержит уникальный URI для данных и обрабатывает запросы к нему в виде очередей SQL (Select, Insert, Delete).

Компоненты Broadcast receiver выступают в роли ящиков для сообщений от других приложений.

Проблемы безопасности, возникающие в ОС Android, рассматривались в работах [2, 12, 13], но классификация проблем по категориям дана только в статье [2]. Эта классификация достаточно подробная и охватывает многие проблемы безопасности, но у нее есть ряд существенных недостатков: некоторые категории охватывают широкую область уязвимостей, в то время как другие достаточно специализированы; приведенные категории уязвимостей никак не соотносятся с программными уровнями архитектуры ОС Android; не охвачены уязвимости из интернет-источников, а также слабо охвачены уязвимости в протоколах и аппаратуре (п. 2.7 и 2.8 в нашей классификации). Предлагаемая ниже классификация уязвимостей устраняет эти недочеты.

2.1. Уязвимости ядра Linux и его модулей

К данной категории проблем относятся уязвимости, которые присущи всем ОС, основанным на той же версии ядра Linux, что и ОС Android. Эксплойты, использующие уязвимости в ядре, могут получить данные пользователя или права администратора системы. Повысив привилегии процесса до прав администратора системы, вредоносная программа может отключить систему безопасности Android, вставить в существующие программы вредоносный код и установить руткит. К тому же производители различных устройств добавляют в ядро модули для своих устройств; в этих модулях также могут быть уязвимости. Примеры уязвимостей повышения привилегий описаны в [14, 15, 16, 64]. Также стоит отметить, что совсем недавно была обнаружена уязвимость в компоненте ashmem для межпроцессного взаимодействия в Android [62].

2.2. Уязвимости модификаций и компонентов производителей устройств

В последнее время производители различных мобильных устройств стали выпускать свои модифицированные прошивки Android. Эти прошивки могут содержать различные приложения и сервисы, разработанные производителем устройства, которые чаще всего нельзя удалить. Например, в октябре 2016 года был обнаружен скрытый бэкдор в прошивках Foxconn [63]. Анализ этих сервисов, приведенный в статьях [17], показывает, что в них содержится от 65 до 85% уязвимостей, обнаруженных во всей системе. К тому же стоит отметить, что уязвимости, которые были обнаружены и исправлены в основной ветке Android, могут долгое время оставаться в ветках производителей устройств [18, 19].

2.3. Уязвимости модулей в машинных кодах

Android-приложения поддерживают запуск машинного кода через интерфейс JNI. Это порождает еще одну категорию уязвимостей, связанную с широко известными уязвимостями утечек памяти в низкоуровневых языках (например, в С и С++ ) [20]. Поскольку на уровне процессов ОС Android нет никаких ограничений, кроме накладываемых ядром Linux, сторонние библиотеки в машинных кодах могут использовать разрешения, выданные всему приложению, для совершения вредоносной активности (см. также следующую категорию уязвимостей, п. 2.4). Также модули приложения в машинных кодах используются авторами вредоносных приложений, чтобы обойти инструменты анализа и мониторинга уровня Android. Эти модули также могут использовать техники противодействия анализу, используемые в обычных программах.

2.4. Уязвимости механизмов межкомпонентного взаимодействия

К данной категории относятся уязвимости, связанные с взаимодействием между различными компонентами приложений. Так как на уровне операционной системы приложение ограничено песочницей процесса, ему необходим механизм доступа к компонентам ОС Android для взаимодействия с ними. Это происходит через устройство /dev/Binder и различные другие сервисы ОС Android. Как уже говорилось выше, параметры этого доступа задаются в файле манифеста, в виде XML-файла с разрешениями. Анализ, приведенный в статьях [12, 21, 22, 23, 24, 25], указывает на недочеты этой системы ограничений и показывает пути их обхода. Так, например, приложение может воспользоваться правами доступа другого приложения и получить с помощью него данные через ICC. Также могут быть уязвимости, связанные со сторонними библиотеками. Сторонние библиотеки, используемые в приложении, получают тот же набор ограничений, что и само приложение. Поэтому сторонние библиотеки могут использовать разрешения, выданные всему приложению, для совершения вредоносной активности. Приложения к тому же могут перехватывать системные события, пересылаемые через широковещательный запрос, и сохранять информацию о входящих звонках и СМС.

2.5. Уязвимости в самих приложениях

Каждое приложение сохраняет какие-то данные о пользователе. Эти данные должны быть защищены должным образом, чтобы к ним не могли получить доступ другие приложения, — но такая защита предусмотрена не всегда. Например, Skype в одной из версий приложения сохранял базу данных контактов в открытом виде на диске. Таким образом, контакты можно было прочитать любым другим приложением, у которого есть доступ к диску [26]. Также приложения могут использовать криптографические библиотеки с ошибками [27] или же какие-то собственные реализации. К тому же не все приложения производят хорошую аутентификацию и авторизацию пользователя. Кроме этого, приложения могут позволять SQL-инъекции и подвержены атакам XSS. Также стоит отметить, что большинство разрабатываемых приложений написаны на Java без использования какой-либо защиты для бинарного кода, а байт-код Java, как известно, легко поддается дизассемблированию и анализу. Стоит отметить, что к этой категории уязвимостей относится также известный список Mobile OWASP-10. Многие подобные уязвимости описаны в [28, 29].

2.6. Уязвимости во встроенных сервисах и библиотеках

Стандартный набор библиотек и сервисов, работающих в Android, также содержит уязвимости. Например, недавно была обнаружена уязвимость Stagefright в библиотеке для отображения видео в MMS-сообщениях, которой были подвержены все версии Android, начиная с 2.2 [30]. Позже была обнаружена уязвимость в компоненте MediaServer, которой подвержены все версии Android c 2.3 до 5.1 [31]. В статье [13] показаны уязвимости рантайма Dalvik: запустив большое количество процессов в системе, можно добиться, что последующий процесс запустится с правами администратора.

2.7. Интернет-источники

Android-приложения распространяются через широкое количество источников помимо официального магазина приложений. Поскольку Android-приложения написаны в основном на Java, то они легко поддаются обратной разработке и переупаковке с использованием вредоносного кода [32, 33]. Кроме того, как было показано в статье [34], песочницу анализа приложений Bouncer, используемую в официальном каталоге, легко обойти. Поэтому и в самом официальном магазине содержится большое количество вредоносных программ. Кроме этого, Android поддерживает удаленную установку приложений через Google Play на устройства, связанные с Google-аккаунтом. Таким образом, если взломать учетную запись Google для устройства, можно установить из Google Play вредоносное приложение, которое туда предварительно загрузил злоумышленник. При этом на экране мобильного телефона не требуется каких-либо подтверждений этих действий, поскольку они запрашиваются в окне браузера и приложение устанавливается на телефон в фоновом режиме при получении доступа к Интернету. Также к этой категории уязвимостей относится использование социальной инженерии, когда для продолжения работы предлагают установить приложение из неавторизованного источника [35].

2.8. Уязвимости аппаратуры и связанных с ней модулей и протоколов

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

Примерами таких атак служат атака типа «отказ в обслуживании» на технологию Wi-Fi Direct [36], кража данных кредитных карт с помощью NFC [37], исполнение удаленного кода через Bluetooth [38], установка вредоносного приложения без ведома пользователя через adb с помощью механизма бэкапов [39]. В работе [13] показаны уязвимости, с помощью которых можно повысить привилегии приложения, используя ошибки в реализации протокола adb.

3. Инструменты для анализа Android-приложений

С того момента, как были выпущены первые Android-телефоны, было написано большое количество инструментов для анализа Android-приложений. Наиболее полный обзор этих инструментов содержится в статьях [40, 41, 42, 2]. В первых трех источниках инструменты классифицированы по видам анализа: статический, динамический и их объединение (смешанный). В статье [2] используется классификация инструментов по стадиям развертывания приложения на Android-устройстве. В нашей работе используется классификация по видам анализа.

Статический анализ

Инструменты статического анализа можно разделить на следующие категории:

  • Инструменты, извлекающие метаинформацию из манифеста приложения и предоставляющие информацию о запрашиваемых разрешениях, компонентах Activity, сервисах и зарегистрированных Broadcast receivers. Метаинформация часто используется позже в динамическом анализе для запуска функций приложения.
  • Инструменты для модификации существующего байт-кода приложения с использованием техники инструментирования. Это позволяет, например, добавлять трассирование функциональности в существующие приложения.
  • Инструменты, которые реализуют декомпилятор или дизассемблер байт-кода Dalvik.

Одним из наиболее популярных инструментов обратной разработки является Apktool [43]. Он имеет возможности декодирования ресурсов приложения приблизительно в оригинальную форму, переупаковки приложений обратно в APK/JAR-файлы, отладку байт-кода smali. Для декомпилирования и компилирования в apktool байт-кода Dalvik используется другой широко известный проект smali/backsmali [44]. Также для дизассемблирования байт-кода Dalvik часто применяется инструмент Dedexer [45].

Читайте также:  Hot downloads android что это

Radare2 [46] — инструмент с открытым исходным кодом для дизассемблирования, анализа, отладки и изменения бинарных файлов Android-приложения.

Один из самых разносторонних инструментов для статического анализа — Androguard [47]. Он может дизассемблировать и декомпилировать приложение обратно в исходный код Java. Получив два APK-файла, он может посчитать коэффициент их похожести для детектирования переупакованных приложений или известных вредоносных приложений. Благодаря своей гибкости он используется в некоторых инструментах смешанного анализа.

Более полный список инструментов статического анализа можно найти в статьях, указанных выше. Следует отметить, что статический анализ имеет ряд существенных ограничений, связанных с тем, что имеется лишь абстрактное представление о программе. Например, статический анализ становится намного сложнее, если к программе применены обфусцирующие преобразования. В зависимости от сложности обфускации некоторые (а может, и все) статические подходы могут стать абсолютно бесполезными. Если вызов каждого метода делается только косвенно, вряд ли удастся построить граф вызовов программы. В Android такое преобразование можно сделать, используя Java Reflection API для вызова методов и создания объектов вместо использования обычных вызовов и инструкций создания нового объекта. На рынке решений по защите исходного кода уже представлено несколько продуктов для обфускации файлов Android-приложений, которые могут свести на нет все преимущества статического анализа [48, 49]. Более подробно о техниках противодействия статическому анализу можно почитать в 50.

Динамические и смешанные инструменты анализа

Инструменты динамического анализа отслеживают поведение неизвестного приложения во время выполнения при запуске его в контролируемой песочнице для получения поведенческого следа. Для этого производится инструментирование песочницы на различных уровнях архитектуры участками кода, которые отслеживают поведение приложения и ОС Android.

Рис. 2. Уровни архитектуры песочницы Android

Архитектура песочницы Android представляет из себя эмулятор Android (чаще всего QEMU), внутри которого работает ОС Android. Инструментирование производится либо на уровне эмулятора, либо на уровне ОС Android, либо и там и там. Уровень ОС Android также делится на четыре подуровня:

  • приложения,
  • среда разработки приложения,
  • рабочее окружение приложения и библиотеки,
  • ядро и его модули.

Техники, используемые в динамическом анализе приложения:

  • Отслеживание помеченных данных. Такие инструменты используются, чтобы отслеживать потенциальные утечки конфиденциальной информации.
  • Мониторинг системных вызовов. Инструменты могут записывать системные вызовы с помощью инструментирования виртуальных машин, strace или модуля ядра. Это позволяет производить трассировку машинного кода.
  • Трассировка методов (функций). Инструменты могут отслеживать вызовы Java-методов приложения в виртуальной машине Dalvik, вызовы функций в машинных кодах через JNI, системные вызовы и прерывания.

К инструментам смешанного анализа относятся инструменты, которые сочетают в себе техники динамического и статического анализа.

4. Идеальная система полносистемного анализа платформы Android

Статьи [40, 41, 42, 2] насчитывают более 40 различных инструментов как для анализа Android-приложений, так и для анализа ОС Android в целом. Как было замечено в статьях [34, 60, 61], существующие инструменты динамического анализа обладают рядом серьезных недостатков. Данные недостатки присущи и стандартному инструменту анализа приложений в магазине Google Play — Google Bouncer, вследствие чего вредоносные приложения могут распространяться через официальный магазин, не будучи обнаруженными.

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

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

  • поддержку смешанного исполнения,
  • трассировку приложений,
  • анализ помеченных данных,
  • анализ межкомпонентного взаимодействия,
  • склейку машинного и Java-кода приложения,
  • взаимодействие с реальным оборудованием.

Список требований к данной системе:

1. Поддержка загрузки прошивок от производителей различных устройств

Существенным недостатком всех существующих инструментов анализа ОС Android и ее приложений является невозможность запуска прошивок от производителей устройств в доступных эмуляторах. Как было показано в п. 2.2, модифицированные прошивки от производителей устройств содержат от 65 до 85% уязвимостей, обнаруженных во всей системе. На данный момент не существует инструментов для анализа, которые позволяли бы запускать прошивки от производителей. Все существующие решения работают на специальной сборке Android для виртуальной платформы GoldFish.

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

По информации из статей [34, 61], существуют способы выявления работы внутри эмулятора. Как правило, выявляется выполнение в эмуляторе QEMU в режиме бинарной трансляции, поскольку именно на нем основано большинство песочниц. Способы основаны на разном поведении определенных участков машинного кода в эмуляторе и на реальном устройстве. Так как изменение механизма бинарной трансляции представляется сложной задачей, исполнение отдельных кусков машинного кода на реальном устройстве было бы хорошим подходом для противостояния данным способам обнаружения эмулятора.

3. Проброс данных от датчиков оборудования реальных устройств в эмулятор

Как было описано в статьях [34, 61], существуют способы определения эмулятора, основанные на данных, получаемых от датчиков оборудования, таких как акселерометр, гироскоп, GPS, датчик света, силы тяжести. Выходные значения этих датчиков основаны на информации, собранной из окружающей среды, и следовательно, реалистичная их эмуляция является сложной задачей. Присутствие такого рода датчиков — основное различие между смартфонами и настольными компьютерами. Увеличивающееся число датчиков на смартфонах дает новые возможности для идентификации мобильных устройств.

4. Совместный анализ на уровне Java-кода и машинного кода

Затруднением для многих систем анализа Android-приложений является то, что приложения содержат как модули в байт-коде Dalvik, так и модули в машинных кодах. Из существующих решений поддержка анализа всех модулей реализована только в DroidScope [57] и CopperDroid [58, 59]. Идеальная система анализа должна позволять отслеживать потоки данных и управления на уровне пользовательского и системного кода. Для пользовательского кода, когда это возможно, следует поднимать уровень представления до Java-кода, являющегося высокоуровневым языком разработки. Также необходимо обеспечивать «склейку» потоков данных и управления при переходе от машинного кода к Java и наоборот.

5. Поддержка анализа межкомпонентного взаимодействия

В статье о CopperDroid [58] показана реализация поддержки анализа межкомпонентного взаимодействия как внутри Android-приложения, так и между различными приложениями. Это сделано с помощью перехвата данных, проходящих через компонент ядра Binder, так как все взаимодействие проходит через него. Подход, реализованный в CopperDroid, позволяет не производить модификации исходного кода Android, что делает возможность его переноса на новые версии ОС Android и новую среду запуска приложений ART с минимальными изменениями.

6. Защита от статических эвристик обнаружения

Как показано в статьях [[57], 61], большинство песочниц для анализа можно обнаружить, просто проверив значения IMEI, IMSI или номера сборки прошивки у устройства. Также эмулятор может быть обнаружен, если проверить на стандартные значения таблицу маршрутизации. Из существующих решений защита от обнаружения по статическим эвристикам реализована только в проекте ApkAnalyzer [65].

7. Минимальные изменения прошивок Android

Также стоит отметить, что многие решения динамического анализа основаны на инструментировании кода различных компонентов ОС Android, в частности виртуальной машины Dalvik. Это осложняет их дальнейшую поддержку, а также миграцию в новую среду запуска приложений ART. Многие песочницы ограничиваются только анализом кода компонентов Java, тогда как все больше и больше приложений используют компоненты в машинных кодах.

8. Поддержка полносистемного анализа помеченных данных с отслеживанием потоков управления

Стоит отметить, что многие из инструментов динамического анализа используют анализ помеченных данных, используя для этого инструмент TaintDroid [56]. В статье [60] были показаны успешные способы обхода анализа данного инструмента. Причиной успешности данных атак являются следующие факты: 1) TaintDroid отслеживает только потоки данных и не отслеживает потоки управления, 2) TaintDroid отслеживает потоки данных только на уровне виртуальной машины Dalvik и проходящих через интерфейс JNI. Возможные пути разрешения данных недостатков описаны в [60] и дают направление для дальнейших исследований.

9. Поддержка символьного исполнения и частичного исполнения с конкретными значениями с использованием данных, полученных из статического анализа кода (concolic execution — смешанное исполнение)

В статье [51] описана среда анализа, реализующая данный подход. Эта среда сочетает в себе техники статического анализа графа потока управления программы, символьного исполнения программы и исполнения программы с конкретными значениями. Подходы, сочетающие техники символьного исполнения и исполнения программы с конкретными значениями, описаны в статьях [52, 53, 54, 55]. Целью данного метода является наблюдение путей исполнения, которые приводят к секциям программы, содержащим «интересный» код. Под «интересным» кодом понимают такой код, выполнение которого зависит от каких-либо произошедших внешних событий или настроек окружения системы. Например, код классов в Android, динамически подгружаемый с помощью компонента DexClassLoader или вызов «машинных» методов через интерфейс JNI.

Заключение

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

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

Несмотря на такую пессимистичную картину, в последнее время наблюдается ряд позитивных движений в сторону улучшения безопасности Android. В частности, компания Google запустила программу выпуска обновлений безопасности: они выходят каждый месяц и некоторые вендоры все же добавляют их в свои версии прошивки (устройства, поддерживаемые Google, получают эти обновления первыми). Кроме того, пользователи могут самостоятельно установить на свои устройства версию ОС Android CyanogenMod (ныне LineageOS), которая поддерживает эти обновления безопасности. Также пользователь может снизить риски, если ограничится набором популярных приложений только из официального магазина Google Play. Уязвимости типа RCE (удаленное выполнение кода) встречаются все реже, поэтому доставка вредоносных приложений на телефоны чаще происходит через фишинговые сайты, неофициальные магазины приложений или с помощью социальной инженерии. Среднестатистический пользователь ОС Android, соблюдая определенную технику безопасности, может быть спокоен за свой смартфон.

Источник

Оцените статью