Реверсинг приложений под Android. Ищем уязвимости
В этой мы продолжим изучать тему реверсинга приложений для Android. В предыдущих статьях мы рассмотрели основные инструменты, которые нам понадобятся и поговорили о том, как можно анализировать APK файлы на подозрительную активность. Сегодня мы посмотрим, как можно найти уязвимости в приложении для Android.
Как известно, существует несколько способов поиска уязвимостей. Есть методы, основанные на анализе исходного кода приложения и используемых в нем зависимостей. Также есть сканеры уязвимостей, также различными способами пытающиеся выявить уязвимости в уже откомпилированном файле — артефакте. Еще есть фаззинг — методика основанная на скармливании приложению некорректно построенных данных и данных большого объема. Здесь выявление потенциальных уязвимостей построено на анализе приложения на подаваемый набор данных.
И еще один метод поиска уязвимостей это реверсинг. То есть анализ уже готового APK файла. Именно этот метод мы и будем использовать для поиска уязвимостей.
Нашей целью будет эффективное применение наши навыки реверс-инжиниринга в инструменте DEX для поиска уязвимости в приложении для Android. Этот пример немного сложнее предыдущих и познакомит нас с реверсингом в различных компонентах приложения.
На практике поиск уязвимостей в APK может потребоваться, например при анализе банковских приложений. Вас беспокоит, что в этом приложении может быть уязвимость, позволяющая выполнять произвольные команды. Соответственно, нас будут интересовать фрагменты программы, потенциально позволяющие выполнить произвольный код.
Начинаем исследовать
Для реверсинга нам, как и в предыдущих статьях потребуется виртуальная машина Android App, в которой необходимо будет запустить jadx, и открыть файл FotaProvider.apk.
Прежде всего необходимо задастся вопросом: как в Android-приложении можно выполнять произвольные команды. Кроме того, немаловажно и то, как приложение могло бы получать удаленные команды, ведь нам надо как-то эксплуатировать найденную уязвимость.
Для начала откроем файл jadx и посмотрим содержимое манифеста.
Итак, у нас есть два вопроса: каким образом можно выполнить произвольные команды и каким способом можно передать приложению команды. Начнем с первого вопроса. Если посмотреть в документации по разработке андроид приложений, то существует три API вызова, позволяющего выполнять команды: Runtime.exec (), Processbuilder () и использование в коде system ().
Поищем вызовы этих API в коде нашего приложения. Для этого выполним Text search. По слову Runtime у нас нашлось четыре вхождения.
Для нас некоторый интерес представляет третий вариант. Как видно там фигурирует функция exec, которая выполняет значение некоторой переменной str. Если рассмотреть этот фрагмент кода подробнее, то мы увидим следующее:
Как видно Process exec вполне может выполнять произвольный код, который ему передадут в качестве параметра str. Но нам необходимо разобраться с этим параметром, то есть необходимо понять, какие значения могут в нем передаваться.
Для этого поищем обращения к ArrayList с помощью Usage search:
Первое вхождение для нас будет наиболее интересно. Здесь вызывается командная оболочка. Вроде бы это то что надо, перейдем к фрагменту кода, вызывающему ArrayList:
И тут мы видим, что найденный нами запуск командной оболочки по своей сути не является уязвимостью и не позволяет выполнить произвольный код.
В программе явным образом зафиксировано, что вызываться будет »/system/bin/sh». Это значение жестко задано в коде и изменить его никак нельзя. Поэтому нам придется продолжить наши поиски и поискать другие вызовы API функций.
Ищем ProcessBuilder
Следующей по списку у нас будет вызов API ProcessBuilder.
Получили несколько строк. Здесь для нас наибольший интерес представляет первая строка. Выполним по этой строке запрос, который поищет фрагменты кода, связанные с данным вызовом, с помощью Usage search:
Первая строка, содержащая return может быть для интересна. Посмотрим подробнее тот фрагмент кода, в котором она используется.
Здесь мы передаем cmd некоторое строковое значение, которое затем функция SysService вернет после вызова. Соответственно для выполнения произвольного кода нам необходимо передать SysService в переменной cmd нужные нам команды для их последующего выполнения.
Таким образом мы, возможно, нашли ответ на первый вопрос — каким образом произвольный код может быть выполнен. Теперь давайте попробуем найти ответ на второй вопрос, как нашему приложению можно передать соответствующую команду.
Широковещательные сообщения
Иногда, нашим приложениям требуется получать от операционной системы и других приложений различные уведомления, например, об уровне заряда батареи. Для этой цели используются широковещательные сообщения. Передавая события, использующие сообщения, вы открываете компоненты своего приложения для сторонних приложений, и сторонние разработчики реагируют на события без необходимости изменять ваше оригинальное приложение. В своём приложении вы можете прослушивать широковещательные сообщения других приложений, заменить или улучшить функциональность собственного (или стороннего) приложения или реагировать на системные изменения и события приложений.
Но в нашем случае широковещательные сообщения могут использоваться как раз для передачи произвольных команд уязвимому приложению.
Поищем в коде процедуру onReceive. Именно она получает сообщения от других приложений. И здесь мы видим уже знакомую нам строку cmd.
Таким образом, любое приложение или компонент на устройстве может получить произвольную команду, выполненную от имени привилегированного системного пользователя через это приложение. Например, приложение Data Provider.apk экспортирует широковещательный приемник команды записи через action нашего приложения android.intent.action.AdupsFota.operReceiver.
Любой компонент устройства может отправить запрос с этим действием и дополнительной строкой «cmd», и это «cmd» будет выполнено, так как у нашего приложения есть соответствующий action.
Заключение
В этом несложном примере мы рассмотрели по шагам то, как можно исследовать приложение на наличие потенциальных уязвимостей и ошибок, допущенных разработчиками.
Все актуальные методы и инструменты разработки приложений, в том числе мобильных, можно освоить на онлайн-курсах OTUS: в каталоге можно посмотреть список всех программ, а в календаре — записаться на открытые уроки.