Site icon AppTractor

Как я взломал приложение для Android, чтобы получить премиум-функцию

Эта статья предназначена только для ОБРАЗОВАТЕЛЬНЫХ ЦЕЛЕЙ и раскрывает известные уязвимости в Android-приложениях. НЕ пытайтесь использовать это в реальных приложениях.

TL; DR Я переписал байт-код, чтобы разблокировать премиум-функции приложения на моем устройстве, и теперь я покажу вам, как предотвратить это в вашем приложении.

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

Платные функции с биллингом

Многие приложения предлагают пользователям совершать покупки внутри приложений — премиум-функции, какие-то виртуальные монеты для игр и т.д. После оплаты с помощью учетной записи Google покупки навсегда сохраняются на сервере Google с уникальным идентификатором. Это позволяет использовать купленные предметы на всех устройствах.

Но как, например, насчет Huawei, где сервисы Google Play не работают/недоступны? Huawei предоставляет почти идентичный API покупок в приложениях, хотя пользователь не может переносить свои покупки и подписки между платформами.

Подробнее о реализации можно прочитать здесь: https://developer.android.com/google/play/billing/integrate.

Проблема

Иногда приложения пытаются использовать более простые пути и не следуют инструкциям и рекомендациям Google. Это означает, что иногда они отказываются от проверки ранее приобретенных элементов при запуске приложения, тем самым оставляя для любого злоумышленника дверь открытой. Делать что-то на устройстве — всегда плохая идея.

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

Давайте поговорим о моем варианте: я купил премиум-функцию в Google Play, но само приложение не было доступно в магазине Huawei. Поэтому я скачал APK и установил его вручную, но премиум-функции были недоступны.

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

Самый первый шаг — декомпилировать APK в код Smali. В ходе анализа я обнаружил, что это приложение X сохраняет логический флаг в Android SharedPreferences после успешной транзакции. Выполнение таких операций на устройствах — недопустимо.

Премиум-функция как флаг в SharedPreferences

Этот логический флаг использовался, чтобы проверить позже в приложении, куплена ли у пользователя расширенная функция.

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

Smali

Я не хочу сразу переходить к результату и подробно объяснять, что происходит. Начну издалека. Когда мы компилируем приложение Java, создается байт-код. На платформе Android у нас раньше была виртуальная машина Dalvik, а теперь — Android Runtime (ART). Вместо байт-кода Java он преобразует исходный код в набор инструкций в формате .dex, который можно преобразовать в читаемый человеком код Smali. Smali очень похож на байт-код Java.

Вот фрагмент начала метода onCreate из MainActivity в Smali:

Его можно перевести в:

где константа flag 128 означает FLAG_KEEP_SCREEN_ON из WindowManager.

Самая первая строка — это сигнатура метода, но что это за .locals, p0, p1, v0?

Например, onCreate имеет 2 параметра p0 и p1, которые переводятся как «this» и Bundle соответственно -> super.onCreate(Bundle)

Практическое правило: повторно используйте существующие переменные «v», когда это возможно.

Коды операций Dalvik вы можете найти тут.

Внедрение кода

После всех вышеперечисленных шагов мы знаем, что для обхода проверки наличия премиум-функции нам просто нужно ввести код, который устанавливает логическое значение до того, как что-либо загрузится. Наиболее предпочтительное место находится в классе Application или в основной Activity (зависит от приложения). Допустим, мы собираемся внедрить его в MainActivity#onCreate.

Этот фрагмент кода такой же, как

SharedPreferences.Editor editor = sharedPref.edit();
edit.putBoolean("preferencePremium", true);
edit.apply();

Самый простой способ добиться этого — написать реальный код Kotlin/Java, скомпилировать и затем декомпилировать его, чтобы извлечь из него Smali, или напрямую написать байт-код Smali, который я предпочитаю для таких простых задач.

После этого приложение всегда будет запускаться с логическим флагом true.

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

Как предотвратить?

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

Прочтите еще рекомендации от Google: https://developer.android.com/google/play/billing/security

На этом пока все.

Спасибо!

Источник

Exit mobile version