В этой главе мы рассмотрим Android-приложение или файл .apk, а также его различные компоненты. Мы будем использовать инструменты (такие как Apktool, dex2jar и jd-gui) для обратного проектирования приложения. Мы также изучим, как искать уязвимости в Android-приложениях с помощью обратного проектирования и анализа исходного кода. Кроме того, мы применим некоторые статические инструменты и скрипты для поиска уязвимостей и их использования.
Android-приложение — это архив данных и ресурсов, созданный во время разработки приложения. Расширение файла Android-приложения — .apk, что означает «пакет приложений». В большинстве случаев он включает следующие файлы и папки:
Чтобы убедиться в этом, можно использовать любой архиватор (например, 7zip, WinRAR или любой другой предпочтительный инструмент), чтобы просто разархивировать приложение. В Linux или Mac мы можем просто использовать команду unzip для отображения содержимого сжатого пакета, как показано на скриншоте ниже:
Здесь мы используем флаг -l (list), чтобы просто отобразить содержимое сжатого пакета вместо его распаковки. Мы также можем использовать команду file, чтобы проверить, является ли это действительным сжатым пакетом.
Android-приложения состоят из различных компонентов, которые вместе создают работающее приложение. Этими компонентами являются действия, службы, приёмники широковещательных сообщений, поставщики контента и общие настройки. Прежде чем продолжить, давайте кратко рассмотрим эти различные компоненты:
Как обсуждалось ранее, Android-приложения представляют собой архивы данных и ресурсов. Даже в этом случае мы не можем просто распаковать архив (файл .apk), чтобы получить читаемый исходный код. Для этих случаев нам необходимо полагаться на инструменты, преобразующие байт-код (такой как тот, что находится в файле classes.dex) в читаемый исходный код.
Одним из способов преобразования байт-кода в читаемые файлы является использование инструмента под названием dex2jar. Файл .dex представляет собой байт-код Java, преобразованный в байт-код Dalvik, оптимизированный и эффективный для мобильных платформ. Этот бесплатный инструмент просто преобразует файл .dex, присутствующий в Android-приложении, в соответствующий файл .jar. Следуйте этим шагам:
Загрузите инструмент dex2jar с сайта https://code.google.com/p/dex2jar/.
Теперь мы можем использовать его для запуска файла .dex нашего приложения и преобразования его в формат .jar.
Теперь нам нужно сделать следующее: перейти в командную строку и перейти в папку, где находится dex2jar. Затем мы должны запустить файл d2j-dex2jar.bat (в Windows) или файл d2j-dex2jar.sh (в Linux / Mac), предоставив имя приложения и путь в качестве аргументов. Здесь аргументом может быть просто файл .apk или мы даже можем разархивировать файл .apk и передать файл classes.dex, как показано на следующем скриншоте:
Как видно на скриншоте выше, dex2jar успешно преобразовал файл .dex приложения в файл helloworld-dex2jar.jar формата .jar. Теперь мы можем открыть этот файл .jar в любом графическом средстве просмотра Java (таком как JD-GUI), которое можно загрузить с официального веб-сайта http://jd.benow.ca/.
После загрузки и установки JD-GUI мы теперь можем продолжить его открытие. Это выглядит так, как показано на следующем снимке экрана:
Здесь мы теперь можем открыть файл .jar, преобразованный на предыдущем шаге, и просмотреть все исходные коды Java в JD-GUI. Чтобы открыть файл .jar, мы можем просто выбрать File | Open.
На правой панели мы видим исходный код Java для приложения и все методы. Обратите внимание, что процесс повторной компиляции предоставит вам приблизительную версию исходного кода Java. В большинстве случаев это не имеет значения; однако в некоторых случаях вы можете увидеть, что преобразованный файл .jar не содержит некоторых кодов. Кроме того, если разработчики приложения использовали какие-либо средства защиты, предотвращающие декомпиляцию, такие как proguard и dex2jar, при использовании dex2jar или Apktool для декомпиляции приложения вы не увидите точный исходный код; вместо этого вы увидите кучу разных исходных файлов, которые не являются точным представлением исходного кода.
Другой способ обратного проектирования Android-приложений — преобразовать файл .dex в файлы smali. Smali — это формат файла, синтаксис которого похож на язык под названием Jasmine. Сейчас мы не будем углубляться в подробности формата файлов smali. Дополнительную информацию можно найти в онлайн-вики по адресу https://code.google.com/p/smali/wiki/, чтобы узнать больше о smali.
После загрузки Apktool и его настройки, следуя инструкциям из предыдущего раздела, мы готовы к дальнейшим действиям. По сравнению с JD-GUI основным преимуществом Apktool является то, что он двунаправленный. Это означает, что если вы декомпилируете приложение и модифицируете его, а затем используете Apktool для его перекомпиляции, оно сможет идеально перекомпилироваться и создать новый файл .apk. Однако dex2jar и JD-GUI не могут делать то же самое, потому что они предоставляют приблизительный код, а не точный код.
Поэтому, чтобы использовать Apktool для декомпиляции приложения, нам нужно передать файл .apk вместе с двоичным файлом Apktool в командную строку. После завершения декомпиляции Apktool создаст новую папку с именем приложения, которая будет содержать все файлы. Чтобы декомпилировать, мы просто вызываем apktool d [имя приложения].apk. Здесь флаг -d обозначает декомпиляцию.
На следующем скриншоте мы видим приложение, декомпилированное с использованием Apktool:
Теперь, если мы перейдём в папку smali, мы увидим множество разных файлов smali, содержащих код классов Java, написанных во время разработки приложения. Здесь мы также можем открыть один файл, изменить некоторые значения и использовать Apktool для сборки его снова. Чтобы собрать изменённое приложение из файлов smali, мы будем использовать флаг b (build) Apktool.
Однако для декомпиляции, модификации и повторной сборки приложения я рекомендую использовать другой инструмент под названием Virtuous Ten Studio (VTS). Этот инструмент предоставляет функции, аналогичные Apktool, единственное отличие состоит в том, что VTS предоставляет красивый графический интерфейс, что делает его относительно простым в использовании. Ограничением этого инструмента является то, что он работает только в среде Windows. Мы можем загрузить VTS с официального сайта для скачивания http://www.virtuous-ten-studio.com/. Следующий скриншот показывает декомпиляцию того же проекта приложения:
Обычно Android-приложения содержат множество уязвимостей безопасности, часто из-за ошибок разработчиков и игнорирования лучших практик безопасного кодирования. В этом разделе мы обсудим уязвимости, основанные на Android-приложениях, и способы их выявления и использования. Дрозер и запуск модуля app.provider.finduri для поиска содержимого поставщика URI.
dz> run app.provider.finduri com.adobe.reader
Scanning com.adobe.reader...
content://com.adobe.reader.fileprovider/
content://com.adobe.reader.fileprov
Как только мы нашли URI, теперь мы можем использовать app.provider.read для поиска и использования локальных файлов, содержащих уязвимости. Здесь я пытаюсь прочитать некоторые файлы из системы, такие как /etc/hosts и /proc/cpuinfo, которые по умолчанию присутствуют во всех экземплярах Android, поскольку это файловая система на основе Linux.
dz> run app.provider.read content://com.adobe.reader.fileprovider/../../../../etc/hosts
127.0.0.1 localhost
Мы успешно использовали уязвимость в поставщике контента Adobe Reader для чтения файлов в файловой системе Android, как видно на скриншоте ниже.
Клиентские инъекционные атаки
Клиентские атаки обычно происходят, когда приложение не проверяет пользовательский ввод. Например, при запросе к базе данных SQLite приложение анализирует пользовательский ввод, так как он находится в операторе запроса.
Рассмотрим пример приложения, которое проверяет локальную базу данных SQLite, чтобы аутентифицировать пользователя на основе учётных данных. Таким образом, когда пользователь предоставляет имя пользователя и пароль, выполняемый запрос будет выглядеть следующим образом:
SELECT * FROM 'users' where username='user-input-username' and password='user-input-password'
В нормальных условиях это будет работать нормально, пользователь вводит свои настоящие учётные данные, и запрос вернёт true или false в зависимости от условия.
SELECT * FROM 'users' where username='aditya' and password='mysecretpass
Но что, если злоумышленник введёт SQL-запрос вместо обычного имени пользователя? Рассмотрим следующий код:
SELECT * FROM 'users' where username='1' or '1' = '1' - - and password='mysecretpassword
Таким образом, в этом случае, даже если пользователь не знает имени пользователя и пароля, они могут легко обойти его, используя 1'or'1'='1, который всегда возвращает true. Поэтому разработчики приложений должны проверять пользовательский ввод в приложении.
Мы также можем использовать Drozer app.provider.query для использования уязвимостей SQL-инъекций. Его синтаксис выглядит следующим образом:
run app.provider.query [Content Provider URI] --projection "* FROM SQLITE_MASTER WHERE type='table';- -"
Теперь это вернёт список всех таблиц в базе данных SQLite, информация о которых хранится в SQLITE_MASTER. Вы также можете продолжить и выполнить больше SQL-запросов, чтобы извлечь больше информации из приложения. Чтобы использовать Drozer для практического использования уязвимости, вы можете загрузить их приложение с уязвимостью с https://www.mwrinfosecurity.com/products/drozer/community-edition/.
OWASP Mobile Top10
Проект Open Web Application Security Project (OWASP) является одним из стандартов, связанных с безопасностью и поиском уязвимостей. Он также публикует список из 10 наиболее распространённых и важных уязвимостей на различных платформах.
Вы можете найти руководство OWASP по мобильной безопасности на https://www.owasp.org/index.php/Projects/OWASP_Mobile_Security_Project_-_Top_Ten_Mobile_Risks. Если мы посмотрим на OWASP Mobile Project, то вот 10 мобильных проблем безопасности:
Давайте рассмотрим их по очереди и быстро поймём их связь в мобильных приложениях и как их обнаружить:
Слабый контроль сервера
Первая уязвимость OWASP — слабый контроль сервера, что означает, что сервер не отправляет данные из мобильного приложения безопасным способом или раскрывает некоторые чувствительные API при отправке данных. Например, рассмотрим мобильное приложение, отправляющее учётные данные для входа на сервер для аутентификации без проверки ввода. Злоумышленник может изменить учётные данные таким образом, чтобы получить доступ к конфиденциальной или несанкционированной области сервера. Эта уязвимость может рассматриваться как уязвимость как в мобильных, так и в веб-приложениях.
Небезопасное хранение данных
Это просто означает, что приложение хранит информацию, связанную с пользователем, на устройстве в доступной форме. Многие мобильные приложения хранят информацию, связанную с пользователями, или информацию о приложениях в совместно используемых настройках, SQLite (в чистом текстовом формате) или внешнем хранилище. Разработчики должны помнить, что даже если приложение хранит конфиденциальную информацию в папке данных (/data/data/package-name), любое вредоносное приложение/злоумышленник может получить к ней доступ, если телефон рутирован.
Недостаточная защита транспортного уровня
Многие разработчики Android полагаются на передачу данных через небезопасные режимы сети, такие как HTTP или SSL, реализованный неправильно. Это делает приложения уязвимыми для всех видов атак, происходящих в сети, таких как перехват трафика, манипулирование параметрами при отправке данных от приложения на сервер и изменение ответа для доступа к заблокированным областям приложения.
Случайная утечка данных
Эта уязвимость возникает, когда приложение сохраняет данные в месте, которое легко атаковать. К ним относятся буфер обмена, кэш URL, файлы cookie браузера, HTML5 DataStorage, статистика и т. д. Пример — пользователь входит в свой банковский счёт, а его пароль копируется в буфер обмена. Теперь даже вредоносное приложение может получить доступ к данным буфера обмена пользователя.
Отсутствие авторизации и аутентификации
Если мобильное приложение или общее мобильное приложение пытается аутентифицировать или авторизовать пользователей на основе клиентской проверки без надлежащих мер безопасности, эти приложения наиболее подвержены атакам. Следует отметить, что после того, как телефон рутирован, большинство клиентских защит можно обойти злоумышленником. Поэтому рекомендуется разработчикам мобильных приложений использовать проверку подлинности и авторизацию на стороне сервера и выполнять надлежащую проверку, а затем использовать случайно сгенерированный токен для аутентификации пользователя на мобильном устройстве.
Неэффективное шифрование
Это означает использование небезопасной функции хеширования для частичного шифрования данных. Это может включать в себя некоторые алгоритмы, известные наличием уязвимостей, такие как MD5, SHA1, RC2, или даже пользовательские алгоритмы без надлежащей защиты.
Инъекция клиента
Это возможно в приложениях Android и происходит главным образом из-за использования SQLite для хранения данных. Мы будем выполнять инъекции в различных главах этой книги.
Принятие небезопасных решений на основе ввода
Разработчики мобильных приложений всегда должны фильтровать и проверять вводимые пользователем данные или другие соответствующие входные данные и не должны использовать их так, как это делается в приложении. Ненадёжные входные данные часто приводят к другим рискам безопасности в приложении, таким как инъекция клиента.
Неправильная обработка сеанса
При обработке сеансов для мобильных приложений разработчики должны учитывать множество факторов, таких как нормальный срок действия аутентификационных файлов cookie, создание безопасных токенов, генерация и ротация файлов cookie и невозможность сделать сеанс на сервере недействительным. Необходимо поддерживать правильную синхронизацию безопасности между веб-приложением и приложением Android.
Отсутствие двоичной защиты
Это означает, что невозможно правильно предотвратить взлом приложения путём обратного проектирования или декомпиляции. Такие инструменты, как Apktool и dex2jar, можно использовать для обратного проектирования приложений Android, и если они не следуют правильным методам разработки, они раскрывают различные риски безопасности приложения. Разработчики могут использовать ProGuard и DashO для предотвращения анализа приложения с помощью обратного проектирования.
Заключение
В этой главе мы изучили использование различных методов для обратного проектирования мобильных приложений Android и анализа исходного кода. Мы также узнали, как модифицировать исходный код, а затем перекомпилировать приложение, чтобы обойти некоторые меры защиты. Кроме того, мы увидели, как использовать инструменты, такие как Drozer, для поиска уязвимостей в мобильных приложениях Android. Вы также можете попробовать различные уязвимости в лаборатории Exploit-Me на http://labs.securitycompass.com/exploit-me/, разработанной Security Compass.
В следующей главе мы продолжим попытки перехвата трафика мобильных приложений Android и будем использовать его в наших тестах на проникновение.
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.