Многие люди хранят в телефоне пикантные фото, но по каким причинам – тема другой статьи. И здесь остро встает вопрос о том, как защитить фотографии, хранящиеся на мобильном устройстве.
Автор: Michael Allen @_Dark_Knight_
Мы слишком часто слышим печальные истории людей, потерявших мобильные телефоны с конфиденциальными фотографиями. Другой случай: кто-то одалживает телефон своим друзьям, а те начинают копаться внутри и просматривать фотоальбомы. Как бы то ни было, многие люди хранят в телефоне пикантные фото, но по каким причинам – тема другой статьи. И здесь остро встает вопрос о том, как защитить фотографии, хранящиеся на мобильном устройстве.
Один из вариантов решения этой проблемы – использовать специальное приложение, предназначенное для защиты фотографий, видео и другого контента. Подобные программы создают альбомы внутри контейнеров, доступ к которым осуществляется при помощи пароля, отпечатка пальца или TouchID. Последняя технология используется в случае, если устройство является одной из последних моделей.
Я решил присмотреться к некоторым из этих приложений под операционную систему iOS. Быстро вбив запрос «best photo vaults iOS» в гугле, я получил следующие варианты:
Рисунок 1: Перечень популярных iOS-приложений, предназначенных для защиты фотографий
В этой статье я буду исследовать несколько наиболее популярных бесплатных приложений, которые мне удалось найти.
Ингредиенты, необходимые для работы:
Джейлбрейковый iPhone 4S (7.1.2)
BurpSuite Pro
Шестнадцатеричный редактор (на ваш выбор)
Cycript
Исследуемые приложения:
Private Photo Vault
Photo+Video Vault Keep Safe (My Media)
KeepSafe
Я буду рассказывать о наиболее распространенных техниках, используемых мной во время экспертизы iOS-приложений. Кроме того, на примере приложения Private Photo Vault мы немного углубимся в область реверс-инжиниринга. Техники, изложенные ниже, можно применять и при исследовании других приложений (останется читателю в качестве домашнего задания).
Примечание: если не сказано иного, все команды выполняются в Mac OS после подключения к джейлбрейковому устройству через ssh.
Анализ приложения Private Photo Vault
Первым подопытным приложением будет Private Photo Vault. Выяснилось, что уже написано несколько статей о проблемах, связанных с безопасностью этого приложения (см. раздел Ссылки). Поскольку уже прошло какое-то время с момента написания тех статей, я решил проверить, устранили ли разработчики приложения найденные проблемы. Оказалось, что (на момент написания данной заметки) некоторые уязвимости до сих пор не исправлены.
Обход экрана блокировки
При запуске приложения появляется экран с предложением о вводе пароля:
Рисунок 2: Экран блокировки
Обходи экрана блокировки не представляет особых сложностей. Вначале нужно найти процесс приложения, а затем подцепить cycript. Для тех, кто не знаком с cycript, привожу выдержку с сайта cycript.org:
«Cycript позволяет разработчикам исследовать и модифицировать приложения как в iOS, так и в Mac OS X. Синтаксис команд унаследован от Objective-C++ и JavaScript. Работа ведется через интерактивную консоль, в которой предусмотрена подсветка синтаксиса и автодополнение».
Чтобы найти нужный процесс используем следующую команду:
ps –e | grep “Photo”
Затем подцепляем cycript:
cycript –p PhotoVault
Рисунок 3: Подцепляем cycript к процессу приложения Photo Vault
Далее выводим иерархию представлений при помощи следующей команды:
[[UIApp keyWindow] recursiveDescription]
Рисунок 4: Иерархия представлений
По иерархии представлений находим несколько упоминаний PasswordBox. Попробуем поиграться с видимость этого элемента при помощи следующей команды:
[#viewAddress setHidden:YES].
В качестве адреса используем 0x15f687f0.
Рисунок 5: Сокрытие первого поля ввода пароля
После выполнения команды видим, что первый PasswordBox исчез:
Рисунок 6: Экран блокировки с исчезнувшим элементом PasswordBox
Далее мы будем использовать команду nextResponder для того, чтобы найти контроллер текущего представления. Ссылки на подробную документацию об этой команде и о MVC-модели указаны в разделе Ссылки.
Суть идеи заключается в том, что мы вызываем команду nextResponder до тех пор, пока не доберемся до контроллера. Начинаем с команды [#0x15f687f0 nextResponder], которая возвращает <UIView: 0x15f68790>. Далее вызываем команду [#0x15f68790 nextResponder] и добираемся до контроллера, как показано на рисунке ниже:
Рисунок 7: Поиск контроллера текущего представления
В итоге мы нашли контроллер WhiteLockScreenViewController, соответствующий представлению экрана блокировки. Ранее я выгрузил информацию о классах при помощи утилиты class-dump-z и нашел интересный метод dismissLockScreen.
Неужели все настолько просто? Оказалось, что да. Мы можем просто вызвать этот метод и обойти экран блокировки:
Рисунок 8: Обход экрана блокировки при помощи метода dismissLockScreen
Незащищенное хранилище
Далее я решил проверить, где находится пароль от хранилища. Свои фотографии я «защитил» при помощи пароля 1337. Оказалось, что пароль хранится в открытом виде в файле com.enchantedcloud.photovault.plist, который находится в директории /var/mobile/Applications/A025EF5F-ED84-4D82-A23D-BBCFE183F539/Library/Preferences.
Попутно мне стало интересно, на что повлияет изменение параметра Request Pin (см. ниже).
Рисунок 9: Пароль хранится в открытом виде
Не только PIN хранится в открытом виде. У пользователя есть возможность установить пароль на отдельные альбомы. И снова пароль хранится как обычный текст в файле Albums.plist:
Рисунок 10: Содержимое файла Albums.plist
Отсутствие шифрования
Пароли в открытом виде, это еще полбеды. Оказалось, что и сами картинки хранятся в незашифрованном виде в директории /0:
Рисунок 11: Директория, где хранятся незашифрованные фотографии
Рисунок 12: Содержимое незашифрованной фотографии
Реверс-инжиниринг приложения Private Photo Vault
На данный момент мы научились обходить экран блокировки при помощи cycript. Давайте попробуем сделать то же самое при помощи других методов.
Нам понадобится:
IDA Pro/Hopper
LLDB
Usbmuxd
Debugserver
Настройка рабочей среды
Подключите мобильное устройство к вашей системе и запустите скрипт tcprelay (из директории usbmuxd) при помощи следующей команды:
tcprelay.py -t <remote-port-to-forward><local-port-to-listen>
Рисунок 13: Запуск скрипта tcprelay
Tcprelay позволяет нам отлаживать приложение через USB. Можно было бы то же самое делать через Wi-Fi, но этот протокол часто замедляет весь процесс.
Подключаемся к устройству через SSH, запускаем debugserver и цепляемся к процессу при помощи следующей команды:
debugserver *:8080 –a “PhotoVault”
Рисунок 14: Запуск debugserver на мобильном устройстве
Далее в нашей системе запускаем lldb и подключаемся к серверу отладки на мобильном устройстве. Запускаем следующую команду из lldb:
process connect connect://localhost:8080
Рисунок 15: Подключаемся к debugserver через lldb
Дешифровка бинарного файла
После всех настроек можно приступать к отладке. Но вначале расшифруем бинарный файл при помощи следующей команды:
DYLD_INSERT_LIBRARIES=dumpdecrypted_armv7.dylib /var/mobile/Applications/A025EF5F-ED84-4D82-A23D-BBCFE183F539/PhotoVault.app/PhotoVault mach -o decryption dumper
Рисунок 16: Дешифровка бинарного файла приложения PhotoVault
Обычно я проверяю, какие еще архитектуры поддерживает бинарный файл, при помощи следующей команды:
otool –hV PhotoVault.decrypted
Рисунок 17: Проверка на то, является ли бинарный файл мультиархитектурным
Если файл поддерживает несколько архитектур, я оставляю только ту, с которой я работаю в данный момент. Допустим, файл запускается на устройстве iPhone 4S. Тогда используем следующую команду:
lipo -thin armv7 -output PhotoVault-v7 PhotoVault.decrypted
В итоге получаем файл PhotoVault-v7, который далее будем анализировать в IDA или Hopper (инструкции по настройке lldb и debugserver находятся в разделе Ссылки).
Ранее мы выяснили, что контроллер WhiteLockScreenViewController управляет экраном блокировки. Если мы введем некорректный пароль, появится сообщение «Wrong Passcode – Try Again» Наша первая задача – выяснить при помощи IDA, какие задействуются участки кода, когда мы вводим неправильный пароль.
Рисунок 18: Поиск участков кода, связанных с неверным вводом пароля
Мы нашли несколько соответствий, но особый интерес для нас представляет контроллер WhiteLockScreenViewController. После небольших исследований, выясняется следующее:
Рисунок 19: Содержимое функции customKeyboardButtonPressed, принадлежащей контроллеру WhiteLockScreenViewController
По адресу 0013A102 вызывается метод lockScreen:isPasswordCorrect. По адресу 0013A114 происходит проверка возвращаемого значения. По адресу 0013A118 принимается решение, куда двигаться дальше. Если мы ввели некорректный пароль, приложение переходит к ветке loc_13A146 и выводит сообщение «Wrong Passcode», как показано на рисунке ниже.
Рисунок 20: Ветка, связанная с выводом сообщения о неверном пароле
Наша задача – сделать так, чтобы в приложении выполнялась ветка 0013A11A, и вызвался метод selRef_lockScreen_didEnterCorrectPassword_ .
Рисунок 21: Интересующая нас ветка
Устанавливаем точку останова по адресу 0013A110 перед тем, как происходит проверка возвращаемого значения. Но вначале нужно учесть, что приложение защищено ASLR, и нам нужно найти смещение для нашего устройства.
Рисунок 22: Точка останова будет установлена по адресу 0013A110
Чтобы решить эту проблему, используем следующую команду (внутри сессии lldb):
image list –o -f
Рисунок 23: Поиск смещения
Приложение загружено по адресу 0xef000, и точка останова будет установлена по адресу 0x229110 (0x000ef000 + 0013A110) при помощи следующей команды:
br s -a 0x229110
Все последующие точки останова также будут вычисляться как сумма двух смещений (ASLR и IDA).
Рисунок 24: Установка точки останова
Далее вводим произвольный пароль, и срабатывает точка останова. Смотрим содержимое регистра r8:
Рисунок 25: Содержимое регистра r8
Поскольку в регистре значение 0, далее инструкция TST.W R8, #0xFF переведет нас в ветку, где выводится сообщение «Wrong Passcode». Нам нужно изменить это значение, чтобы перейти в другую ветку. Используем следующую команду:
register write r8 1
Рисунок 26: В регистр r8 устанавливаем значение 1
Перед тем как продолжить, повнимательнее посмотрим на ту ветку, в которую мы хотим попасть. Там есть вызов функции lockScreen_didEnterCorrectPassword. Через поиск в IDA выясняем, что функция принадлежит классу PasswordManager.
Рисунок 27: Поиск ссылок на функцию lockScreen_didEnterCorrectPassword
Внутри функции lockScreen_didEnterCorrectPassword находим кое-что интересное:
Рисунок 28: Содержимое функции lockScreen_didEnterCorrectPassword
В коде на рисунке выше считывается PIN-код, хранящийся на устройстве, и полученное значение сравнивается с тем, что вводим мы (по адресу 0012D498). Естественно, проверка закончится неудачно, поскольку мы ввели неправильный PIN-код. Далее вызывается уже знакомая нам функция dismissLockScreen. Если не забыли, мы вызывали эту функцию ранее при помощи cycript.
Рисунок 29: Ветка, где вызывается функция dismissLockScreen
Чтобы оказаться в этой ветке нам нужно изменить значение в регистре r0 так, чтобы инструкция TST возвратила нужный результат, и система думала, что мы ввели корректный PIN-код. Устанавливаем точку останова по адресу 0012D49C, где сравнивается введенное значение. Напоминаю, что мы находимся внутри метода lockScreen_didEnterCorrectPassword, принадлежащего классу PasswordManager.
Рисунок 30: Место, где происходит сравнение введенного PIN-кода
Чтобы проверка PIN-кода оказалась удачной, нужно установить в регистр r0 значение 1.
Рисунок 31: Обновляем регистр r0, чтобы вызвать функцию dismissLockScreen
После обновления регистра вызывается функция dismissLockScreen, экран блокировки исчезает, и мы получаем доступ к фотографиям.
Подводим итоги. Первый трюк позволяет нам вызывать функцию lockScreen_didEnterCorrectPassword, второй - функцию dismissLockScreen. Вызовы этих функций происходят вне зависимости от того, какой PIN-код мы ввели.
Теперь рассмотрим другие приложения.
Анализ приложения My Media
Незащищенный веб-сервер
Приложение My Media довольно популярно, однако содержит те же самые уязвимости, которые описаны выше. Особенность этого приложения заключается в том, что для управления пользовательскими альбомами используется веб-сервер, запущенный на 5555 порту.
Рисунок 32: Веб-сервер запущен на 5555 порту
Перейдя по адресу выше, оказывается в менеджере фотографий:
Рисунок 33: Менеджер фотографий
Первое, что я заметил – отсутствие аутентификации. Все, кто находится в той же подсети, потенциально могут получить доступ к пользовательским альбомам. Более глубокий анализ показал, что имеются уязвимости, наиболее распространенные в веб-приложениях. Например, через имя альбома можно выполнить межсайтовый скриптинг:
Рисунок 34: XSS-уязвимость в имени альбома
Незащищенное хранилище
Как и в предыдущем случае, фотографии не шифруются, что легко проверить в любом шестнадцатеричном редакторе. Фото и видео хранятся в следующей директории:
/var/mobile/Applications/61273D04-3925-41EF-BD63-C2B0BC128F70/Library/XFFile/Decoy/1/Picture/Album1
Рисунок 35: Незащищенное хранилище с фотографиями
На устройстве список альбомов и фотографии выглядят так:
Рисунок 36: Перечень альбомов и фотографий на устройстве
Еще одна из фишек подобных приложений – возможность установить специальный пароль, введя который пользователь попадает в фальшивый альбом. Фотографии, хранимые в фальшивом альбоме, также не зашифрованы. «Левые» фотографии хранятся в следующей директории:
/var/mobile/Applications/B73BB177-CEB7-4576-BDFC-2408A0369D42/Library/XFFile/Decoy/2/Picture/Decoy Album
Пользовательские данные хранятся в незашифрованном виде в базе sqlite. Мне без труда удалось получить перечень всех паролей, в том числе административных.
Рисунок 37: Содержимое таблицы с паролями
Анализ приложения KeepSafe
Обход экрана блокировки
Обход экрана блокировки в приложении KeepSafe также не представляет особых сложностей.
Рисунок 38: Экран блокировки
Экран блокировки можно обойти, если вызвать метод showMainStoryboard, принадлежащий классу KeepSafe.AppDelegate. Подключаемся к процессу приложения, но в этот раз смотрим список экземпляров методов.
Рисунок 39: Перечень экземпляров методов
Для обхода экрана блокировки достаточно вызвать либо метод showAccountStoryboard, либо метод showMainStoryboard, как показано на рисунке ниже:
Рисунок 40: Обход экрана блокировки
В приложении KeepSafe можно защитить паролем каждый альбом. Каждый альбом синхронизируется с облаком.
Рисунок 41: Облако в KeepSafe
Выяснилось, что пароль возвращается сервером в открытом виде, как показано на рисунке ниже:
Рисунок 42: Пароль от альбомов возвращается сервером в открытом виде
Помимо обхода экрана блокировки злоумышленник может получить пароль к каждому альбому.
Заключение
Подведем краткие итоги того, чего нам удалось добиться. Мы использовали:
Cycript для обхода экранов блокировки.
Sqlite для извлечения конфиденциальной информации из баз данных.
Plutil для чтения конфиденциальной информации из plist-файлов.
BurpSuite Pro для перехвата трафика.
IDA Pro для анализа бинарных файлов и решения задач, схожих с теми, что мы решали при помощи cycript.
В среднем, чтобы получить доступ к фотографиям и пользовательским учетных данным, нам требовалось не более 30 минут. Единственное исключение – анализ бинарных файлов в IDA, но мы проводили этот анализ лишь с целью показать вам альтернативные методы работы. Злоумышленник может получить доступ к конфиденциальным фотографиям в течение нескольких минут.
Во всех случаях обход экрана блокировки не представлял особых сложностей. Основные проблемы в системе безопасности приложений:
Отсутствует детектирование джейлбрейкового устройства.
Хранилище с учетными данными не защищено.
Отсутствует шифрование фотографий.
Обход экрана блокировки не представляет никаких сложностей.
Присутствуют распространенные уязвимости в веб-приложениях.
Однако следует отметить, что не все приложения, предназначенные для защиты фотографий, настолько уязвимы. Я лишь взял наиболее популярные программы и провел быстрый анализ. С другой стороны, я бы не удивился, если в других приложения оказались бы те же самые проблемы, поскольку разработчики часто делают неверные предположения и думают, что у пользователей нет доступа к файловой системе.
Так в чем заключаются основные риски? Во-первых, если вы запускаете эти приложения на джейлбрейковом устройстве, то легко получите доступ к конфиденциальной информации. В случае с My Media даже если у вас нет джейлбрейкового устройства, но вы подключены к веб-серверу, то легко сможете получить доступ к фотографиям.
Еще более важным является то, что ваши данные не зашифрованы, и любое вредоносное приложение может получить доступ как к фотографиям, так и к учетным записям.
В следующий раз, когда вы захотите воспользоваться одним из приложений, описанных в этой заметке, имейте в виду, что функционал данных приложений может быть не тот, каким кажется на первый взгляд. Еще лучше, если вы не будете хранить конфиденциальные фото на мобильных устройствах.
Ссылки