Remote wipe на Android и Exchange ActiveSync

в 18:17, , рубрики: android, Microsoft Exchange, Песочница, метки: ,

Однажды наш администратор Microsoft Exchange упомянул о функциональности полной очистки любого устройства по своему усмотрению (будь то iPhone, или девайс на основе BlackBerry или Android), получающих почту по протоколу Exchange ActiveSync. Девайс рапортует серверу, доступен ли ему функционал wipe, а администратор может запретить передачу почты на устройства, не поддерживающие wipe.

Сначала я не поверил: как так, безобидная настройка почтового аккаунта даёт администратору почты столько полномочий на моём личном устройстве. Сделав полный бэкап SD-карточки и всей внутренней памяти, предложил эксперимент. И чудо — пришло push-уведомление, телефон подзавис, через некоторое время перезагрузился и я остался с заводскими настройками. А SD-карта вообще не подавала признаков жизни.

Remote wipe на Android и Exchange ActiveSync

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

Первым делом надо было посмотреть, что случилось с SD-картой. Телефон считал, что она отсутствует и я вставил её в кард-ридер. Просмотр в HEX-редакторе показал, что таблица разделов (MBR) затёрта, но сами разделы (FAT32 и Linux swap) вполне нормальны. Замечательной утилитой TestDisk я моментально восстановил содержимое карточки к состоянию до очистки (вот вам и Full Wipe)

Затем просмотрел исходники Android, поискав по ключевым словам wipe, clear, factory settings. Код самоуничтожения располагается в модуле /system/framework/services.jar и представляет собой некий BroadcastReceiver, ожидающий запроса на уничтожение данных (исходник этого класса)

Приложение Settings.apk, входящее в состав open-source пакета Android, вызывает его следующим способом:

sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR"));

От несанкционированного вызова он якобы защищён

It can only be granted to apps signed with the platform key, or installed on the system partition.

Но, как мы увидим ниже, обычное приложение может обойти эту защиту.

Поискав, другие способы запуска очистки, на Stackoverflow я нашёл рецепт, как обычное приложение (без специальных permissions) может попросить Settings.apk показать страницу управления очисткой, где пользователь сам нажмёт «Очистить» на странице доверенного приложения.

Context ctx = createPackageContext("com.android.settings", Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);
Class<?> mc = ctx.getClassLoader().loadClass("com.android.settings.MasterClear");
startActivity(new Intent(ctx, mc));

Пока всё под контролем пользователя…

Далее я декомпилировал все приложения из стандартной прошивки Gingerbread 2.42 (HTC Sense) для Desire Z, и поискал в исходниках обращения к android.intent.action.MASTER_CLEAR, либо к com.android.settings.MasterClear.

Всего таких приложения нашлось четыре:

CheckinProvider.apk
MyHTC.apk
Settings.apk
Mail.apk

Первые два — функционал блокировки потерянного устройства от онлайн-сервисов Google и HTC, далее — очистка девайса по запросу пользователя из страницы настроек и виновник расследования, почтовый клиент.

Почтовик вызывает очистку таким кодом:

    Intent i = new Intent("android.intent.action.MAIN");
    i.setClassName("com.android.settings", "com.android.settings.MasterClear");
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    i.putExtra("EASRemoteWipe", true);
    this.mContext.startActivity(i);

то есть, от предыдущего примера он пошёл немного дальше и вызывает не activity с кнопкой, которую может нажать юзер, а activity, которая запускается после нажатия кнопки.

У меня есть подозрение, что для выполнения этого кода не нужны особые разрешения (не могу проверить, т.к. не установлены ни java-IDE, ни Android SDK).

На этом моё любопытство было удовлетворено. Исправив в дизасм-листинге название MasterClear на MasterXlear, я пересобрал Mail.apk, залил его на устройство и проверил, что команда wipe от exchange больше не имеет власти над телефоном (при попытке синхронизировать почту, появляется ошибка синхронизации, пока «потерянный» телефон не будет отвязан от учётной записи exchange, после чего на следующей синхронизации вся почта заливается заново, как на новый девайс, и продолжает нормально работать)

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

1. Подпись пересобранного приложения.

Любое Android-приложение должно быть подписано личным сертификатом разработчика, иначе оно не запустится. Бесплатный сертификат можно получить из программы openssl, если попросить её об этом так:

openssl genrsa -out key.pem 1024
openssl req -new -key key.pem -out request.pem
openssl x509 -req -days 9999 -in request.pem -signkey key.pem -out certificate.pem
openssl pkcs8 -topk8 -outform DER -in key.pem -inform PEM -out key.pk8 -nocrypt

В результате мы получим вожделенные certificate.pem, key.pem и key.pk8, которыми подпишем пересобранный Mail.apk с помощью утилиты signapk.jar:

java -jar signapk.jar certificate.pem key.pk8 Mail-unsigned.apk Mail-signed.apk

2. Dalvik cache

У каждого приложения есть кеш JIT-компиляции, чтобы не проводить компиляцию каждый запуск. При установке apk обычным способом кеш очищается, но при копировании приложения (в системный раздел /system/app) его нужно очистить самостоятельно:

rm /data/dalvik-cache/*@Mail.apk@*

3. Глюки apktool

Утилита apktool, которой я проводил дизассемблирование и пересборку приложения, упорно создавала неработоспособный файл. Внутри apk находятся ресурсы, собранные в бинарный файл resources.arsc (например, xml-ресурсы в этом файле переведены в бинарный вид, скорее всего для удобной навигации по xml-дереву) и код, собранный в classes.dex. Поскольку править мне надо только код, при декомпиляции я задал опцию -r (Do not decode resources) и после компиляции исправленной требухи обратно в apk-файл он наконец-то запустился.

Автор: qw1

* - обязательные к заполнению поля