[Программирование, Разработка под Android] Подменяем Runtime permissions в Android
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Здравствуйте, меня зовут Виталий.
Немного о себе. Мне 25 лет, закончил магистратуру СПБГЭТУ «ЛЭТИ» в своем родном городе. Уже 10 лет занимаюсь программированием, из которых 4 пишу под Android. Автор многих Homebrew программ, известный под ником VITTACH, для *Sony PlayStation Portable (PSP)*.
Сегодня я бы хотел обсудить с вами проблему безопасности мобильных приложений. Разработчики из Google постоянно улучшают Android, находя и исправляя уязвимости не без помощи обширного сообщества, собранного благодаря программе *Android Security Rewards*, о которой мы поговорим позже. Тем не менее, проблемы все еще остаются, и наша общая задача как коммьюнити сообщать о них, чтобы их своевременно исправляли.
Уязвимость о которой я буду говорить, относится к классу с Priority: **P2** и Severity: **S2**, что согласно [таблице](https://developers.google.com/issue-tracker/concepts/issues) в широком смысле означает:
* Проблему, которую необходимо решить в разумные сроки;
* Проблему, которая важна для большого процента пользователей и связана с основными функциями.
## Runtime permission
Речь в статье пойдет о такой известной всем разработчикам вещи как Runtime permission, а именно – о возможности введения в заблуждение конечного пользователя путем демонстрации диалогового окна выдачи разрешения со своим текстом и иконкой поверх системного. Нетрудно догадаться, что подобный подход позволил бы разработчикам запрашивать у пользователя разрешение, скажем, к файловой системе, а по факту – к выдаче доступа к геопозиционированию, камере или чему-то еще.
## Это невозможно
Не один раз задавался подобный вопрос на специализированных форумах, в частности на [StackOverflow](https://stackoverflow.com/questions/33266328/how-can-i-customize-permission-dialog-in-android). Единственным правильным ответом было то, что это невозможно. И это действительно так: невозможно подменить текст в самом системном диалоге, но возможно его перекрыть своим.
## Что под капотом
_Runtime Permission_ впервые появились в `Android 6.0` в ответ на потребность повышенного внимания в области выдачи dangerous-разрешений. Фактически основная идея состоит в том, чтобы взаимодействовать с пользователем при запросе разрешений через всплывающее окно. Поэтому теперь разрешения из списка [dangerous](https://developer.android.com/guide/topics/permissions/overview#dangerous-permission-prompt) необходимо запрашивать у пользователя как только они понадобятся приложению.
<details><summary>Dangerous permissions</summary>
- *android.permission_group.CALENDAR*
- android.permission.READ_CALENDAR
- android.permission.WRITE_CALENDAR
- *android.permission_group.CAMERA*
- android.permission.CAMERA
- *android.permission_group.CONTACTS*
- android.permission.READ_CONTACTS
- android.permission.WRITE_CONTACTS
- android.permission.GET_ACCOUNTS
- *android.permission_group.LOCATION*
- android.permission.ACCESS_FINE_LOCATION
- android.permission.ACCESS_COARSE_LOCATION
- *android.permission_group.MICROPHONE*
- android.permission.RECORD_AUDIO
- *android.permission_group.PHONE*
- android.permission.READ_PHONE_STATE
- android.permission.CALL_PHONE
- android.permission.READ_CALL_LOG
- android.permission.WRITE_CALL_LOG
- android.permission.ADD_VOICEMAIL
- android.permission.USE_SIP
- android.permission.PROCESS_OUTGOING_CALLS
- *android.permission_group.SENSORS*
- android.permission.BODY_SENSORS
- *android.permission_group.SMS*
- android.permission.SEND_SMS
- android.permission.RECEIVE_SMS
- android.permission.READ_SMS
- android.permission.RECEIVE_WAP_PUSH
- android.permission.RECEIVE_MMS
- android.permission.READ_CELL_BROADCASTS
- *android.permission_group.STORAGE*
- android.permission.READ_EXTERNAL_STORAGE
- android.permission.WRITE_EXTERNAL_STORAGE
</details>
Для отображения системного диалога в Android есть [GrantPermissionsActivity](https://android.googlesource.com/platform/packages/apps/PackageInstaller/+/b11175d/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java), который запускается после запроса на выдачу разрешений и отображает нам диалог со знакомым интерфейсом.
![](https://developer.android.com/images/permissions/runtime_permission_request_2x.png)ActivityCompat.requestPermissions(
MainActivity.this,
arrayOf(Manifest.permission.READ_CONTACTS),
PERMISSION_REQUEST_CODE
)
А раз это _Activity_, которая перекрывает UI нашего приложения, значит можно попробовать пойти тем же путем и создать свою _Activity_, которая уже будет перекрывать системную.
Теперь давайте посмотрим на пример:
Пусть есть _Activity_ с флагом `android:windowIsTranslucent=true` (чтобы сделать _Activity_ с прозрачным фоном, позволяющим видеть, что за ним стоит) и оно запускается другим _Activity_ , который я назову фоновым. Визуально вы все еще можете видеть некоторую часть фонового _Activity_ через прозрачные пиксели в _Activity_ переднего плана.
![](https://c.radikal.ru/c02/2009/0f/f9b598497bef.png)
Синий – это активное Activity с полупрозрачным окном, а фиолетовый – Activity прямо под ним.
Что произойдет с _Activity,_ если вы поместите приложение в фоновый режим?
![](https://c.radikal.ru/c04/2009/69/300b1457d180.png)
Фоновая _активность_, несомненно, будет убита, а передний план _деятельности_ может выжить, пока вы не переключитесь на другое приложение.
И вот что произойдет, когда вы вернете свое приложение на передний план:
![](https://c.radikal.ru/c28/2009/93/b14fcb9569d7.png)
Фоновая _Activity_ создается, а затем `onResume` и `onPause` вызываются по порядку. Затем оживает передний план _Activity_.
Идея заключается в том, чтобы перекрыть эту _Activity_ в стеке своей собственной с кастомным диалогом, но так чтобы оставить возможность взаимодействовать с кнопками системного диалога. И вот это уже – возможно!
## Попробуй сам
Для демонстрации использован язык программирования Kotlin
- Создать стиль
К сожалению, невозможно настроить эти параметры иначе как из стилей
```
<style name="Theme.Transparent" parent="AppTheme">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
</style>
```
- Прописать в манифесте _Activity_ со стилем
```
...
<activity
android:name=".PermissionActivity"
android:theme="@style/Theme.Transparent" />
</application>
```
- Создать PermissionActivity со своим _layout_
В методе onCreate написать код:
```
window.addFlags(FLAG_NOT_FOCUSABLE or FLAG_NOT_TOUCH_MODAL or FLAG_NOT_TOUCHABLE)
```
Здесь мы использую трюк с использованием следующих флагов:
- `FLAG_NOT_FOCUSABLE`: window, в которой установлен параметр `FLAG_NOT_FOCUSABLE`, не может взаимодействовать с методом ввода;
- `FLAG_NOT_TOUCH_MODAL`: разрешит отправку любых событий за пределы окна в окна позади него, в противном случае он сам будет использовать все события указателя, независимо от того, находятся ли они внутри окна;
- `FLAG_NOT_TOUCHABLE`: это окно никогда не может получать события касания.
- В MainActivity вызвать запрос
```
ActivityCompat.requestPermissions(
MainActivity.this,
arrayOf(Manifest.permission.READ_CONTACTS),
REQUEST_CODE
)
```
И сразу после этого из MainActivity запустить другую активити: PermissionActivity.
```
startActivity(Intent(this, PermissionActivity::class.java))
```
PermissionActivity с прозрачным фоном и отсутствием фокуса и прокидыванием событий на _Activity_ позади себя запустится и позволит добиться перекрытия системного диалога с сохранение полного взаимодействия с ним. Результат достигнут!
## Android >=7.1.1
Хотя _Runtime Permission_ появились в версии `Android 6.0`, но до версии `7.1.1` эту уязвимость использовать не получится, т.к. ранние версии Android ругаются на обнаружение перекрытия при попытке нажатия на кнопку `Разрешить`.
Если вы попробуете запустить мой код на версии `Android 6.0`, то получите это предупреждение. По неизвестной мне причине, Google отказался от этих ограничений в новых версиях.
![](https://c.radikal.ru/c13/2009/54/b7415d78a08f.png)
## Android Rewards Programm
Я подал заявку и приложил все объяснительные и демонстрационные документы по данной уязвимости. В данный момент заявка находится в стадии рассмотрения, поэтому я не могу разглашать подробности, потому что подписал соответствующее соглашение.
## А как проще?
Для удобства эксплуатации уязвимости мною была написана [библиотека](https://github.com/VITTACH/FakePermission)
![](https://raw.githubusercontent.com/VITTACH/FakePermission/master/Samples.gif)
===========
Источник:
habr.com
===========
Похожие новости:
- [Информационная безопасность, Системное администрирование, Сетевые технологии, Облачные сервисы] Обзор Check Point Secure 2020
- [Управление проектами, Развитие стартапа, Управление продуктом] Что делать, если у стартапа денег на счету меньше, чем на 1 год (перевод)
- [Программирование, Go, Микросервисы] Создаем высокопроизводительные микросервисы с помощью gRPC, Ballerina и Go (перевод)
- [Информационная безопасность, Сетевые технологии] MaxPatrol 8 — с чего начать?
- [Информационная безопасность, Криптография, Законодательство в IT] Власти Казахстана снова принуждают пользователей устанавливать сертификат, чтобы читать зашифрованную переписку
- [] Крошка Енот: как операторы JS-сниффера FakeSecurity распространяли стилер Raccoon
- [Open source, Программирование, C++] Не хочется ждать в очереди? Напишем свой диспетчер для SObjectizer с приоритетной доставкой
- [Разработка под Android, Гаджеты] Samsung начала выпускать Android 11 для своих устройств через три месяца после выхода ОС
- [Информационная безопасность, Open source, Софт] Освобождаем свои данные из корпоративного рабства. Концепция личного хранилища
- [Информационная безопасность] История развития компьютерных вирусов для Unix-подобных систем
Теги для поиска: #_programmirovanie (Программирование), #_razrabotka_pod_android (Разработка под Android), #_permissions, #_android, #_runtime_permissions, #_bezopasnost (безопасность), #_ujazvimost (уязвимость), #_google, #_library, #_programmirovanie (
Программирование
), #_razrabotka_pod_android (
Разработка под Android
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 10:57
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Здравствуйте, меня зовут Виталий.
Немного о себе. Мне 25 лет, закончил магистратуру СПБГЭТУ «ЛЭТИ» в своем родном городе. Уже 10 лет занимаюсь программированием, из которых 4 пишу под Android. Автор многих Homebrew программ, известный под ником VITTACH, для *Sony PlayStation Portable (PSP)*. Сегодня я бы хотел обсудить с вами проблему безопасности мобильных приложений. Разработчики из Google постоянно улучшают Android, находя и исправляя уязвимости не без помощи обширного сообщества, собранного благодаря программе *Android Security Rewards*, о которой мы поговорим позже. Тем не менее, проблемы все еще остаются, и наша общая задача как коммьюнити сообщать о них, чтобы их своевременно исправляли. Уязвимость о которой я буду говорить, относится к классу с Priority: **P2** и Severity: **S2**, что согласно [таблице](https://developers.google.com/issue-tracker/concepts/issues) в широком смысле означает: * Проблему, которую необходимо решить в разумные сроки; * Проблему, которая важна для большого процента пользователей и связана с основными функциями. ## Runtime permission Речь в статье пойдет о такой известной всем разработчикам вещи как Runtime permission, а именно – о возможности введения в заблуждение конечного пользователя путем демонстрации диалогового окна выдачи разрешения со своим текстом и иконкой поверх системного. Нетрудно догадаться, что подобный подход позволил бы разработчикам запрашивать у пользователя разрешение, скажем, к файловой системе, а по факту – к выдаче доступа к геопозиционированию, камере или чему-то еще. ## Это невозможно Не один раз задавался подобный вопрос на специализированных форумах, в частности на [StackOverflow](https://stackoverflow.com/questions/33266328/how-can-i-customize-permission-dialog-in-android). Единственным правильным ответом было то, что это невозможно. И это действительно так: невозможно подменить текст в самом системном диалоге, но возможно его перекрыть своим. ## Что под капотом _Runtime Permission_ впервые появились в `Android 6.0` в ответ на потребность повышенного внимания в области выдачи dangerous-разрешений. Фактически основная идея состоит в том, чтобы взаимодействовать с пользователем при запросе разрешений через всплывающее окно. Поэтому теперь разрешения из списка [dangerous](https://developer.android.com/guide/topics/permissions/overview#dangerous-permission-prompt) необходимо запрашивать у пользователя как только они понадобятся приложению. <details><summary>Dangerous permissions</summary> - *android.permission_group.CALENDAR* - android.permission.READ_CALENDAR - android.permission.WRITE_CALENDAR - *android.permission_group.CAMERA* - android.permission.CAMERA - *android.permission_group.CONTACTS* - android.permission.READ_CONTACTS - android.permission.WRITE_CONTACTS - android.permission.GET_ACCOUNTS - *android.permission_group.LOCATION* - android.permission.ACCESS_FINE_LOCATION - android.permission.ACCESS_COARSE_LOCATION - *android.permission_group.MICROPHONE* - android.permission.RECORD_AUDIO - *android.permission_group.PHONE* - android.permission.READ_PHONE_STATE - android.permission.CALL_PHONE - android.permission.READ_CALL_LOG - android.permission.WRITE_CALL_LOG - android.permission.ADD_VOICEMAIL - android.permission.USE_SIP - android.permission.PROCESS_OUTGOING_CALLS - *android.permission_group.SENSORS* - android.permission.BODY_SENSORS - *android.permission_group.SMS* - android.permission.SEND_SMS - android.permission.RECEIVE_SMS - android.permission.READ_SMS - android.permission.RECEIVE_WAP_PUSH - android.permission.RECEIVE_MMS - android.permission.READ_CELL_BROADCASTS - *android.permission_group.STORAGE* - android.permission.READ_EXTERNAL_STORAGE - android.permission.WRITE_EXTERNAL_STORAGE </details> Для отображения системного диалога в Android есть [GrantPermissionsActivity](https://android.googlesource.com/platform/packages/apps/PackageInstaller/+/b11175d/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java), который запускается после запроса на выдачу разрешений и отображает нам диалог со знакомым интерфейсом. ![](https://developer.android.com/images/permissions/runtime_permission_request_2x.png)ActivityCompat.requestPermissions( MainActivity.this, arrayOf(Manifest.permission.READ_CONTACTS), PERMISSION_REQUEST_CODE ) А раз это _Activity_, которая перекрывает UI нашего приложения, значит можно попробовать пойти тем же путем и создать свою _Activity_, которая уже будет перекрывать системную. Теперь давайте посмотрим на пример: Пусть есть _Activity_ с флагом `android:windowIsTranslucent=true` (чтобы сделать _Activity_ с прозрачным фоном, позволяющим видеть, что за ним стоит) и оно запускается другим _Activity_ , который я назову фоновым. Визуально вы все еще можете видеть некоторую часть фонового _Activity_ через прозрачные пиксели в _Activity_ переднего плана. ![](https://c.radikal.ru/c02/2009/0f/f9b598497bef.png) Синий – это активное Activity с полупрозрачным окном, а фиолетовый – Activity прямо под ним. Что произойдет с _Activity,_ если вы поместите приложение в фоновый режим? ![](https://c.radikal.ru/c04/2009/69/300b1457d180.png) Фоновая _активность_, несомненно, будет убита, а передний план _деятельности_ может выжить, пока вы не переключитесь на другое приложение. И вот что произойдет, когда вы вернете свое приложение на передний план: ![](https://c.radikal.ru/c28/2009/93/b14fcb9569d7.png) Фоновая _Activity_ создается, а затем `onResume` и `onPause` вызываются по порядку. Затем оживает передний план _Activity_. Идея заключается в том, чтобы перекрыть эту _Activity_ в стеке своей собственной с кастомным диалогом, но так чтобы оставить возможность взаимодействовать с кнопками системного диалога. И вот это уже – возможно! ## Попробуй сам Для демонстрации использован язык программирования Kotlin - Создать стиль К сожалению, невозможно настроить эти параметры иначе как из стилей ``` <style name="Theme.Transparent" parent="AppTheme"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowIsTranslucent">true</item> </style> ``` - Прописать в манифесте _Activity_ со стилем ``` ... <activity android:name=".PermissionActivity" android:theme="@style/Theme.Transparent" /> </application> ``` - Создать PermissionActivity со своим _layout_ В методе onCreate написать код: ``` window.addFlags(FLAG_NOT_FOCUSABLE or FLAG_NOT_TOUCH_MODAL or FLAG_NOT_TOUCHABLE) ``` Здесь мы использую трюк с использованием следующих флагов: - `FLAG_NOT_FOCUSABLE`: window, в которой установлен параметр `FLAG_NOT_FOCUSABLE`, не может взаимодействовать с методом ввода; - `FLAG_NOT_TOUCH_MODAL`: разрешит отправку любых событий за пределы окна в окна позади него, в противном случае он сам будет использовать все события указателя, независимо от того, находятся ли они внутри окна; - `FLAG_NOT_TOUCHABLE`: это окно никогда не может получать события касания. - В MainActivity вызвать запрос ``` ActivityCompat.requestPermissions( MainActivity.this, arrayOf(Manifest.permission.READ_CONTACTS), REQUEST_CODE ) ``` И сразу после этого из MainActivity запустить другую активити: PermissionActivity. ``` startActivity(Intent(this, PermissionActivity::class.java)) ``` PermissionActivity с прозрачным фоном и отсутствием фокуса и прокидыванием событий на _Activity_ позади себя запустится и позволит добиться перекрытия системного диалога с сохранение полного взаимодействия с ним. Результат достигнут! ## Android >=7.1.1 Хотя _Runtime Permission_ появились в версии `Android 6.0`, но до версии `7.1.1` эту уязвимость использовать не получится, т.к. ранние версии Android ругаются на обнаружение перекрытия при попытке нажатия на кнопку `Разрешить`. Если вы попробуете запустить мой код на версии `Android 6.0`, то получите это предупреждение. По неизвестной мне причине, Google отказался от этих ограничений в новых версиях. ![](https://c.radikal.ru/c13/2009/54/b7415d78a08f.png) ## Android Rewards Programm Я подал заявку и приложил все объяснительные и демонстрационные документы по данной уязвимости. В данный момент заявка находится в стадии рассмотрения, поэтому я не могу разглашать подробности, потому что подписал соответствующее соглашение. ## А как проще? Для удобства эксплуатации уязвимости мною была написана [библиотека](https://github.com/VITTACH/FakePermission) ![](https://raw.githubusercontent.com/VITTACH/FakePermission/master/Samples.gif) =========== Источник: habr.com =========== Похожие новости:
Программирование ), #_razrabotka_pod_android ( Разработка под Android ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 10:57
Часовой пояс: UTC + 5