Продолжаем тему безопасности мобильного банкинга, которую мы начали в первой части. Наверное, многие уже догадались, речь в данной статье пойдет об атаке «человек посередине», MitM. Данная атака была выбрана не случайно. В случае, если канал передачи данных между приложением мобильного банкинга и сервером контролируется злоумышленником, последний может украсть деньги со счета клиента, то есть нанести прямой финансовый ущерб. Но обо всем по порядку.
Вообще, провести данное исследование нас подвигли две причины. Во-первых, из проекта в проект мы видим повторяющуюся печальную картину уязвимостей. По итогам аудита, получается очередная короткометражка с видео-взломом МБ для заказчика. Во-вторых, вышли две очень интересные публикации: «The Most Dangerous Code in the World: Validating SSL Certificates in Non-Browser Software» и «Rethinking SSL Development in an Appified World» — советуем с ними ознакомиться. Но обо всем по порядку.
Man-in-The-Middle
Основные сценарии реализации атаки “MitM”:
— Подключение пользователя к поддельной Wi-Fi-точке доступа. Это самый распространенный и реальный сценарий MitM-атаки. Может быть легко воспроизведен в кафе, торговом или бизнес-центре. Программное обеспечения для проведения данной атаки несложно найти в открытом доступе.
— Подключение к поддельной базовой станции оператора. Эта схема становится все более доступной для широких масс благодаря богатому выбору аппаратного и программного обеспечения и его низкой стоимости. Ситуацию необходимо взять под контроль как можно оперативнее.
— Использование зараженного сетевого оборудования. Под заражением сетевого оборудования понимается не только исполнение на нем вредоносного кода, но и его целенаправленное злонамеренное переконфигурирование, например, через уязвимость. Уже известно немало примеров реализации подобных атак.
Стоит сказать, что это лишь несколько сценариев из множества возможных. Главное, что необходимо злоумышленнику, – добиться того, чтобы сетевой трафик от жертвы на сервер шел через подконтрольный ему хост.
Вредоносные SOHO роутеры
Классная находка и исследование от парней из Team Cymru — они нашли вредоносно ПО, которое, попадая во внутреннюю сеть, меняло настройки DNS на свои. Что это значит? Что теперь на подконтрольные злоумышленнику сайты перенаправлялись не только внутренние машины, но и все мобильные устройства, которые цеплялись к этим роутерам по WiFi! И вот перед нами такой замысловатый MiTM.
Специфика работы мобильных устройств с Wi-Fi-сетями:
— Автоматическое подсоединение к известным Wi-Fi-сетям (на основе PNL, Preferred Network List)
o Не везде можно отключить или сконфигурировать каким-либо простым способом
— Идентификация сети происходит на основании SSID (имени сети) и настроек безопасности
— Если известных сетей несколько, то выбор подключения у каждой ОС свой
Атакующий может развернуть собственную Wi-Fi-сеть, полностью идентичную известной сети для мобильного устройства. В результате, устройство автоматически подсоединится к такой точке доступа и будет работать через нее. Например, с помощью программы KARMA. Такая схема и отсутствие простого управления доверенными сетями упрощает реализацию “MitM” для злоумышленника.
Защита канала
Перед тем, как ломать, давайте изучим то, что нам может помешать это сделать.
Под защищенным каналом будем понимать канал, в котором для обеспечения передачи данных используется шифрование и контроль целостности. Но не стоит забывать, что не все криптографические алгоритмы остаются стойкими и не всегда применение криптографии происходит корректно.
Каналы можно разделить на 3 основные группы:
— Открытые
Находясь в одной сети с жертвой, злоумышленник видит все клиент-серверное взаимодействие в открытом виде.
— Защищенные нестандартными методами
Как показывает наша практика, это не лучшее решение: оно приводит к ряду ошибок, которые ведут к компрометации передаваемых данных.
— Защищенные стандартными методами
Самый распространенный вариант – SSL/TLS
Процесс проверки сертификата
Для обеспечения работоспособности данной схемы на устройстве находится много корневых сертификатов (CA), которые хранятся в специальном хранилище доверенных корневых сертификатов, и все, что ими подписано, является доверенным для устройства.
Сертификаты разделяются на:
• системные — предустановлены в систему
• пользовательские — установлены пользователем
Проверка сертификатов идет по цепочке: от присланного на устройство до корневого (CA), которому доверяет устройство. Далее идут проверки имени хоста, отозванности и т.д. Дальнейшие проверки могут различаться (на этом, кстати, тоже можно играть при атаке на то или иное приложение) в зависимости от реализации библиотеки, ОС и т. д.
SSL и Android
В ОС Android до версии 4.0 все сертификаты хранились в едином файле – Bouncy Castle Keystore File.
Файл: /system/etc/security/cacerts.bks
Изменить его без root-привилегий было невозможно, и ОС не предоставляла никаких способов его модификации. Любое изменение сертификата (добавление, отзыв) требовало обновления ОС.
Начиная с версии Android 4.0, подход к работе с сертификатами изменился. Теперь все сертификаты хранятся отдельными файлами, и при необходимости можно удалять их из доверенных.
Системные хранятся в: /system/etc/security/cacerts
Пользовательские хранятся в: /data/misc/keychain/cacerts-added
Для просмотра сертификатов в ОС Android необходимо зайти в меню Настройки -> Безопасность -> Надежные сертификаты (Settings -> Security -> Trusted credentials).
Количество системных сертификатов в различных версиях Android:
— Android 4.0.3: 134
— Android 4.2.2: 140
— Android 4.4.2: 150
Количество сертификатов также может меняться от производителя к производителю и для каждой модели устройства.
Для установки пользовательского сертификата в ОС Android, необходимо загрузить корневой сертификат на SD-карту и зайти в меню Настройки -> Безопасность -> Установить с карты памяти или через MDM (DevicePolicyManager) в Android, начиная с версии 4.4. Заставить пользователя установить сертификат с помощью социальной инженерии можно, но не очень просто.
SSL и iOS
В ОС iOS посмотреть встроенные сертификаты нельзя, и получить информацию о них можно только с сайта компании Apple. Для просмотра пользовательских сертификатов необходимо зайти в меню Настройки -> Основные -> Профиль(и).
Системные хранятся в: /System/Library/Frameworks/Security.framework/certsTable.data
Пользовательские хранятся в: /private/var/Keychains/TrustStore.sqlite3
Количество системных сертификатов в различных версиях iOS (Количество сертификатов может обновляться):
— iOS 5: 183
— iOS 6: 183
— iOS 7: 211
В ОС iOS существует несколько путей установки пользовательских сертификатов:
— Через браузер Safari – необходимо зайти по ссылке, на которой лежит сертификат с расширением .pem или профиль конфигурации с расширением .profile
— Через присоединение сертификата к E-mail
— Через MDM API
Видно, что провести установку пользовательского сертификата через социальную инженерию на iOS намного проще, чем на Android.
Возможные векторы установки сертификатов через социальную инженерию:
1) Пользователь делает все сам из-за неосведомленности. Например, обещается бесплатный доступ в интернет на определенной точке доступа после установки определенного сертификата ;)
2) Приобретается подержанный телефон со встроенным вредоносным сертификатом
3) Сертификат устанавливается на телефон с iOS за несколько секунд, если оказывается случайно в руках злоумышленника (например, он попросил позвонить)
4) Сетевое оборудование с «хорошим» сертификатом — тут NSA и все дела. В процессе просмотра системных сертификатов были замечены сертификаты от Японии и Америки. То есть, они могут проводить MiTM, переподписывая сертификат собственным, и устройство даже не «пикнет» об атаке (и backdoor в крипте не нужен). Наших там нет =(
Vulns, bugs, errors, ...
В данном разделе мы рассмотрим, какие проблемы существуют при взаимодействии между клиентским приложением (в нашем случае, приложением для мобильного банкинга) и сервером.
Все примеры, приведенные здесь, — реальные, данную информацию мы получили в процессе аудитов защищенности приложений для мобильного банкинга.
— Отсутствие HTTPS (SSL)
Как бы удивительно это ни звучало, еще год назад мы встречали приложения для мобильного банкинга, в которых все общение, включая финансовые операции, происходило по HTTP-протоколу: аутентификация, данные о переводах, – все было в открытом виде. Это значит, что злоумышленнику для получения финансовой выгоды необходимо было просто находиться с жертвой в одной сети и обладать минимальной квалификацией. Тогда для успешной атаки было достаточно исправлять номера счетов назначения и, при желании, суммы.
Что касается взаимодействия приложения со сторонними сервисами, по сравнению с прошлым годом ситуация стала немного лучше, но по-прежнему большинство из них ходит за дополнительной информацией для своего функционирования по открытому каналу, на который легко может влиять злоумышленник. Как правило, это информация связана с:
• новостями банка
• расположением банкоматов
• курсом валют
• социальными сетями;
• статистикой программы для разработчиков;
• рекламой
В лучшем случае, злоумышленник может просто дезинформировать жертву, а в худшем – внедрить собственный код, который выполнится на устройстве жертвы, что в дальнейшем поможет похитить аутентификационные данные или деньги. Причина в том, что ОС Android позволяет подгружать код из Интернета, а затем выполнять его. Такой код злоумышленник может, при определенных обстоятельствах, внедрить в открытый канал. Или еще ситуация, когда разработчик передает по открытому каналу crash dump программы, а там можно найти логин и пароль от МБ и другую интересную информацию.
— Собственное шифрование
Данный вариант нам также встречался как на практике, так и в процессе исследования. Использование его нам непонятно, но, по нашим предположениям, оно может быть связано с устоявшимися внутренними процессами банка. При этом, трафик в SSL дополнительно разработчиком не заворачивается.
Как показывает наша практика, использование собственного шифрования до добра не доводит. Порой это даже не шифрование, а просто свой бинарный протокол, который, на первый взгляд, кажется непонятным, зашифрованным. Так что после небольшого ручного анализа MiTM также возможен.
— Некорректное использование SSL
Самый распространенный класс ошибок – это некорректное использование SSL. Чаще всего оно связано со следующими причинами:
• Отсутствие тестовой инфраструктуры у заказчика
Иногда заказчик не может по тем или иным причинам предоставить хорошую тестовую инфраструктуру. И это приводит к тому, что разработчикам приходится идти на ряд ухищрений для проверки корректности работы приложения.
• Невнимательность разработчика
Данный пункт частично связан с предыдущим, и приводит к тому, что в процессе разработки используется различный отладочный код для ускорения процесса тестирования. И перед выпуском программы про этот код забывают.
• Использование уязвимых фреймворков
Часто для упрощения разработчики применяют различные фреймворки. Другими словами, используют чужой код, низкоуровневая часть которого часто скрыта и недоступна. Этот код также содержит уязвимости, о чем разработчики часто даже не догадываются. Особенно это актуально в свете активной кроссплатформенной разработки для мобильных устройств. Пример, уязвимость в Appcelerator Titanium или Heartbleed (CVE-2014-0160) в OpenSSL (атаковать клиента тоже можно — exploit).
• Ошибки разработчика
Разработчик может использовать различные библиотеки для работы с SSL, каждая имеет свою специфику, и ее нужно учитывать. Так, с переходом с библиотеки на библиотеку разработчик может неправильно использовать константу при инициализации или переопределить функцию на свою.
Основные ошибки при работе с SSL:
— Отключение проверок (отладочное API)
— Некорректное переопределение стандартных обработчиков на собственные
— Неправильная конфигурация API-вызовов
— Слабые параметры шифрования
— Использование уязвимой версии библиотеки
— Неправильная обработка результатов вызовов
— Отсутствие проверки на имя хоста или использование неправильных регулярных выражений для проверки
Безоговорочная классика — отключение проверки действительности сертификата!
Безоговорочная классика — отключение проверки имени хоста в сертификате!
Компрометация корневого сертификата
При использовании SSL существует зависимость от корневых сертификатов. Нельзя исключать возможность их компрометации – вспомним, к примеру, последние инциденты с Bit9, DigiNator и Comodo. Не стоит забывать и о сертификатах других стран, компаний, для которых трафик, можно сказать, является открытым.
Как уже было показано, на устройствах находится большое количество сертификатов CA, и при компрометации любого из них компрометируется почти весь SSL-трафик для устройства.
Если CA-сертификат скомпрометирован:
1) Пользователь может удалить сертификат из доверенных
a. В ОС Android пользователь может это сделать как со встроенными сертификатами, так и с пользовательскими
b. В iOS пользователь может удалить только пользовательские сертификаты
2) Разработчик ОС может выпустить обновление
3) Издатель сертификата может отозвать свой сертификат. Механизм проверки сертификата может динамически проверить это
a. Android не поддерживает ни CRL, ни OCSP
b. iOS использует OCSP
Надеяться на то, что пользователь сам будет управлять корневыми сертификатами, сложно. Так что единственный путь – это ждать обновления ОС. OCSP реализован не везде. Пользователь в промежуток времени между компрометацией и обновлением системы уязвим.
CA-сертификаты бывают разных типов – точнее, могут служить для разных целей (шифрования почты, подписи кода и т. д.), но они, как правило, хранятся в одном безопасном хранилище и могут использоваться для проверки доверия к HTTPS-соединению. К сожалению, корректная проверка назначения сертификата не везде реализована. Таким образом, злоумышленник может получить легитимный сертификат от выпускающего центра для одних целей, а использовать для установки HTTPS-соединения в процессе MitM-атаки.
Кроме того, когда пользователь работает в браузере, он может заметить действия с подозрительным сертификатом по красному значку замочка в строке адреса. В такой же ситуации при работе через приложение пользователь никак не будет информирован, если разработчик этого не предусмотрел заранее, что делает атаку скрытой.
SSL Pinning
В качестве защиты от компрометации корневых системных сертификатов и специально встроенных пользовательских можно использовать подход SSL Pinning.
Pinning – это процесс ассоциации хоста с его ожидаемым X509-сертификатом или публичным ключом. Подход заключается во встраивании сертификата или публичного ключа, которому мы доверяем при взаимодействии с сервером, прямо в приложение и отказе от использования встроенного хранилища сертификатов. В итоге, при работе с нашим сервером приложение будет проверять действительность сертификата только на основании криптографического примитива, прошитого в нем.
Приложения для МБ отлично подходят для использования SSL Pinning, так как разработчики точно знают, к каким серверам будет подключаться приложение, и список таких серверов мал.
SSL Pinning бывает двух основных типов:
— Certificate Pinning:
o Простота реализации
o Низкая гибкость подхода
— Public Key Pinning:
o Проблемы с реализацией на некоторых платформах
o Хорошая гибкость подхода
У каждого подхода есть свои плюсы и минусы.
Преимуществом также является возможность использовать:
1) Self-Signed сертификаты
2) Private CA-Issued сертификаты
Для реализации SSL Pinning необходимо переопределить некоторые стандартные функции и написать собственные обработчики. Стоит отметить, что SSL Pinning не получится реализовать в случае использования WebView в Android и UIWebView в iOS в связи с их спецификой.
Механизм работы SSL Pinning
App1 для проверки действительности сертификата будет использовать только вшитый сертификат или публичный ключ.
App2 для проверки действительности сертификата пойдет в системное хранилище сертификатов, где последовательно пройдет по всем сертификатам.
Применение SSL Pinning в наши дни
Впервые технология широко распространилась в Chrome 13 для сервисов Google. Далее были Twitter, Cards.io и т. д.
Сейчас уже все магазины мобильных приложений (Google Play, App Store, WindowsPhone Market) используют данный подход для работы со своими устройствами.
Код для реализации SSL Pinning уже сейчас можно найти на сайте OWASP для Android, iOS и .NET. Начиная с Android 4.2, SSL Pinning поддерживается на системном уровне.
Обход SSL Pinning
SSL Pinning можно обойти/отключить, если на мобильном устройстве присутствует jailbreak или root-доступ. Как правило, это нужно только исследователям для анализа сетевого трафика. Для отключения на Android есть программа Android SSL Bypass, для iOS – программы iOS SSL Kill Switch и TrustMe.
По идее, эти же подходы могут использовать и вредоносные программы.
Как и любой код, проверки при SSL Pinning могут быть реализованы некорректно, и на это стоит обращать внимание.
Анализ
Хватит теории, перейдем к практике и результатам!
Для проведения этого исследования мы использовали 2 устройства: iPhone с iOS 7 и Android с 4.0.3
Из инструментов применялись: Burp, sslsplit, iptables и openssl. Вот такой нехитрый набор. Как можно догадаться, использовался динамический анализ — просто шла попытка аутентифицироваться в банке через приложение. Забавно, что все приложения доступны бесплатно в магазинах (Google Play и App Store), и зарегистрированных аккаунтов во всех (есть несколько исключений) банках нам не надо! Так что данный эксперимент может провести любой желающий с определенным уровнем знаний и «прямыми» руками.
Мы проверяли два аспекта:
1) Насколько корректна валидация SSL-сертификата на стороне клиента:
— Использовали самоподписанный сертификат
— Использовали сертификат, выданный доверенным CA на другое имя хоста
2) Задействуется ли SSL Pinning:
— Использовали CA-сертификат для данного хоста;
Мы проводили активную атаку “MitM”. Для этого мы заставляли жертву выходить в сеть Интернет через наш контролируемый шлюз, на котором производили манипуляции с сертификатами.
Для проверки работы с самоподписанными сертификатами мы сгенерировали собственный.
Для проверки наличия SSL Pinning и правильности проверки имени хоста мы генерировали собственный корневой сертификат, устанавливали его на мобильное устройство.
Итак, результаты:
У iOS 6 % приложений, а у Android 11 % приложений имели свой собственный протокол, и безопасность такого взаимодействия требует глубокого ручного анализа. Из зрительного анализа трафика можно сказать, что он содержит как понятные, читаемые данные, так и сжатые/зашифрованные. Наша практика и мировой опыт позволяют сказать, что, вероятнее всего, эти приложения уязвимы к атаке “MitM”.
14 % iOS-приложений и 15 % Android-приложений уязвимы к самоподписанным сертификатам. Кража средств для этих приложений — лишь вопрос времени.
14% iOS приложений и 23% Android приложений уязвимо к CA-signed cert hostname. Также можно отметить, что при проверки имен хостов может существовать множество ошибок проверок. В связи с тем, что данная проверка производилась только с одним именем, можно считать данные результаты лишь нижней границей количество уязвимых приложений.
При этом стоит сказать, что только один банк имеет одновременно уязвимое приложение для iOS и Android.
SSL pinning встречается очень редко: в 1% приложений для iOS и в 8% приложений для Android. При этом стоит отметить, что, возможно, эта проверка не прошла по каким-либо иным причинам, не связанным с SSL pinning, и процент приложений, использующих данный механизм, еще меньше. Также мы не пытались обойти данный защитный механизм, не анализировали корректность его реализации.
Как показывает наш опыт в анализе безопасности мобильных приложений, почти всегда присутствует код, отвечающий за отключение проверки действительности сертификата. Функции обычно называются в духе Fake*, NonValidating*, TrustAll* и т.д. Данный код используется разработчиками для тестовых целей. В связи с этим, из-за невнимательности разработчика код может попасть в итоговый релиз программы. Таким образом, уязвимость проверки действительности сертификата может появляться в одной версии и исчезать в другой, что делает данную уязвимость “плавающей” от версии к версии. В итоге, безопасность данного кода зависит от правильности процессов, организованных у разработчика.
ЗАКЛЮЧЕНИЕ
Неправильная работа с SSL — это всего лишь одна из уязвимостей, которая приводит к краже денег со счетов клиентов банков. Использование других уязвимостей (порой менее критичных) и их цепочек, также может привести к финансовым потерям. При этом, на серверной стороне тоже порой не все хорошо (АБС порой так и манит к себе), но это уже совсем другая история.
P.S. Стоит отметить, что аналогичные уязвимости были найдены автором и в процессе участия в различных BugBounty программах ;)
P.S.S. Спасибо Егору Карбутову, Ивану Чалыкину, Никите Келесису за помощь при анализе такого огромного количества программ!
Автор: d1g1