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

vnezakona-featured

Что такое jailbreak?

Итак, jailbreak — это специальная программа для снятия некоторых ограничений безопасности системы посредством эксплойтов. Со временем данное определение четко закрепилось за взломом устройств от компании Apple: iPod, iPad, Apple TV, iPhone. Такое название было дано в связи с основной его целью — взломом песочницы, но песочница эта настолько хорошая, что ее прозвали тюрьмой (jail). Для устройств под управлением ОС Android почти аналогичный процесс называется root’ованием, что связано с конечной целью — работой от пользователя root. Необходимо также не путать эти термины с понятием unlock, под которым подразумевается отвязка оператора сотовой связи, установленного с покупкой телефона. И стоит понимать, что jailbreak зависит от hardware и software: эксплойты, лежащие в его основе, могут использовать особенности как железа, так и программных составляющих. Так что наличие jailbreak под какое-то устройство X с OC Y не означает его работоспособность на устройстве Z с ОС Y или устройстве X с ОС K.

При этом сами jailbreak’и бывают двух типов:

  • tethered (привязанный);
  • untethered (непривязанный).

Привязанный означает, что после перезагрузки такого устройства JB пропадает, а в случае непривязанного останется в силе, что гораздо удобнее.

Why?

Я бы выделил три основные категории людей, кому вообще нужен jailbreak: разработчики, обычные пользователи и исследователи ИБ.
Первым — чтобы узнавать, что крутится под капотом iOS, использовать ее скрытые возможности и как можно лучше оптимизировать свое приложение (порой и задействовать private API). Вторым — для того, чтобы использовать tweak’и (как правило, написанные первыми). Tweak — это небольшая программка, которая вносит какое-либо изменение в работу iOS для улучшения юзабилити. Это может быть новый набор иконок, вставка новых подсказок в SpringBoard или запоминание пароля для App Store — в общем, все, что кажется удобным и полезным со стороны пользователя, но не реализовано Apple. И наконец, исследователи безопасности нуждаются в джейлбрейке для копания в самой ОС и всем, что там крутится. Самый распространенный сценарий — это анализ защищенности мобильного приложения для iOS. Если ты не в курсе, то все iOS-приложения из App Store защищены DRM и получить расшифрованное приложение можно только в runtime. Данная операция пока возможна только на джейлбрейкнутом устройстве. Да, еще можно было бы сюда добавить госслужбы для шпионажа и атаки неугодных стран и ее лидеров. Например, Обаме его служба безопасности уже запретила использовать iPhone. Существует мнение, что в связи с высоким интересом военных к jailbreak может полностью исчезнуть публичный jailbreak: зачем выкладывать что-то бесплатно, когда тебе готовы отсыпать кучи зелени...

Сама Apple, конечно, относится к jailbreak негативно и предупреждает об этом своих пользователей. Это и очевидно, ведь в закрытую ОС сторонние люди вносят изменения и для сохранения этих изменений нарушают работу системы безопасности ОС — патчат и хучат определенные участки кода. Что, естественно, ведет к нарушению стабильности работы OC — это стоит иметь в виду, когда ты делаешь jailbreak.

 

Jailbreak — угроза безопасности

JB отключает большинство механизмов безопасности ОС, в связи с этим появляется угроза заражения устройства вредоносным ПО. Это может быть как случайно скачанное вредоносное ПО из Cydia (его там никто не проверяет), так и целенаправленная атака в духе ZitMo, SpitMo, CitMo. Если ты думаешь, что таких проектов не существует, то ты ошибаешься. Есть проект iPhone-Espionage, который включает в себя такой функционал, как:

  • keylogger;
  • захват снимков экрана;
  • перенаправление SMS;
  • запись микрофона;
  • отправка GPS-координат.

С позиции комьюнити это, наоборот, яркое и широко обсуждаемое событие, которое не обходят стороной даже такие издания, как Forbes. У разработчиков JB даже есть собственная конференция Worldwide jailbreak con, где они делятся информацией друг с другом. А по данным saurik (создателя Cydia — магазина нелегальных приложений для iOS), на 2 марта 2013 года в мире существовало 23 миллиона джейлбрейкнутых устройств.

Как бы то ни было, весь процесс создания jailbreak со стороны напоминает игру в кошки-мышки между Apple и разработчиками. Одни закрывают уязвимости и вносят новые механизмы безопасности в ОС, а другие ждут релизов и тестируют свои детища.

Отношение Apple к jailbreak
Отношение Apple к jailbreak

Security in iOS

Хватит прелюдий, начнем погружение в техническую составляющую jailbreak. Давай немного познакомимся с механизмами безопасности iOS, которые встают на пути JB.

  • Code Signing. Приложения после проверки компанией Apple становятся защищены DRM (используется сертификат X.509v3). Так что на устройстве могут выполняться только подписанные компанией Apple приложения.
  • Sandboxing (Seatbelt). Каждое приложение, которое ставится из App Store, работает в своей песочнице. Оно имеет собственную рабочую директорию/var/mobile/Applications/<app-GUID>, дальше которой ничего не видит. Да и других процессов это тоже касается, так что приложение понятия не имеет, кто еще существует в системе. Из более тонких моментов можно выделить отсутствие прямого доступа к железу устройства и невозможность динамически генерировать код (JIT), исключением является только Safari.
  • Разделение привилегий. Каждое приложение запущено с ограниченными правами под пользователем mobile и имеет ряд entitlements.

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

 

Немного истории и цифр

  • 29 июня 2007 года компания Apple презентовала новый телефон iPhone со своей операционной системой iOS 1.0. Спустя 11 дней ОС была взломана.
  • Jailbreak’и: PwnageTool, redsn0w, purplera1n, Spirit, JailbreakMe, Absinthe, evasi0n.
  • Основные лица: iPhone Dev Team, Chronic Dev Team, George Hotz, comex, pod2g, evad3rs и, конечно, saurik.
  • Привязанный JB делали меньше, чем за неделю, за исключением версии 3.0, где Apple внесла все текущие средства безопасности (чуть меньше 100 дней).
  • Непривязанный выходит гораздо реже, и на его взлом тратится больше времени, причем если сравнивать с привязанным, то время увеличилось в среднем в 7–8 раз.

Жизнь после JB

Приступим к нашей основной теме. Чтобы разобраться, как задетектить, имеет устройство JB или нет, нужно понимать, что JB сделал, изменил, оставил после себя. Итак, ты поставил JB — какие новые грани открылись перед тобой?

  1. Запуск неподписанных приложений. Теперь можно ставить приложения из Cydia и других сторонних репозиториев. Там обычно лежат различные системные приложения, tweak’и, которые не прошли (и никогда не пройдут) проверку Apple — из-за того, что они либо используют private-функции, либо вообще требуют JB для своей полноценной работы. Но поскольку данное ПО никак не проверяется, среди него может быть и вредоносное — об этом не стоит забывать. Особенно вкупе с тем, что JB отключил большинство механизмов защиты. Основной эффект: Cydia и другие неразрешенные Apple приложения.
  2. Возможность доступа к ФС. Появляется доступ для взаимодействия с файловой системой, например по SSH. Становится возможным поход по всем директориям системы, копирование/редактирование/скачивание/загрузка любого файла в системе. Основной эффект: появление новых файлов, изменение стандартных файлов.
  3. Обход ограничений sandbox. Sandbox теперь, по сути, не работает, как и ряд других механизмов безопасности (например, проверка подписи кода), и любое приложение в системе уже может видеть не только свою директорию, но и все файлы в системе. Основной эффект: возможность обращаться к тому, к чему раньше не могли обратиться.

На этих эффектах мы и будем играть — детектить JB!

Общие этапы JB
Общие этапы JB

Последствия JB

Последствие 1: изменения в ФС

До:

/dev/disk0s1 / hfs ro 0 1
/dev/disk0s2 /private/var hfs rw,nosuid,nodev 0 2

После:

/dev/disk0s1 / hfs rw 0 1
/dev/disk0s2 /private/var hfs rw 0 2

После установки JB изменяется /etc/fstab. Директория / становится доступной на запись, а у директории /private/var пропадают биты nosuid, nodev.

Устройство ФС iOS
Устройство ФС iOS

Последствие 2: дополнительные утилиты

По умолчанию на iOS-устройстве отсутствует unix shell. Оно и понятно, Apple не закладывала в свои устройства возможность работы с ними из консоли. В связи с этим JB ставит различные полезные программки для упрощения своей установки. В итоге на устройстве появляется куча новых утилит, среди которых утилиты для работы JB, файлы самого JB, различные Bundle, Cydia (как правило, но не обязательно), Mobile Substrate и так далее. Часть из этих новинок можно увидеть в измененном/var/mobile/Library/Caches/com.apple.mobile.installation.plist.

Последствие 3: перерасположение папок

Приложения из App Store ставятся в /var/mobile/Applications, а из Cydia — в/Applications. В связи с тем, что системная директория (/) имеет значительно меньший размер, чем пользовательская (/private/var), и приложения из Cydiа ставятся в системную директорию, возникает проблема с доступным местом. Для ее решения с нужных директорий делают символическую ссылку на пользовательскую директорию, где места предостаточно. В итоге метод имеет следующую формулу: /var/stash + symbolic links. То же самое делается и для /Library/Ringtones/Library/Wallpaper/usr/include/usr/lib/pam/usr/libexec,/usr/share.

Вид корня после JB
Вид корня после JB

Последствие 4: поломанная песочница

Данные изменения происходят очень низко, на бинарном уровне, и они нам не особо пригодятся, но не сказать о них нельзя. Во-первых, JB патчит Apple Mobile File Integrity Daemon, который отвечает за проверку подписей. Во-вторых, вносит изменения в само ядро:

// Выключаем MAC для процессов
security.mac.proc_enforce=0

// Выключаем MAC для Vnode
security.mac.vnode_enforce=0

В итоге:

  • появление новых файлов/директорий;
  • измененные свойства;
  • измененное поведение.

Detection

Кто-то может задаться вопросом: зачем мне как разработчику iPhone-приложений проверять, на каком устройстве запущена моя программа? Вопрос хороший и логичный.

Во-первых, чтобы снизить риски для самого пользователя. Если ты разрабатываешь какое-то критичное мобильное приложение, допустим для мобильного банкинга, то в связи с возможностью выполнения на таком устройстве вредоносного ПО ты можешь либо запретить запуск своего приложения, либо ограничить некоторый доступный функционал, например запретить денежные переводы или ограничить их верхним пределом. Я видел такие подходы в российских приложениях для мобильного банкинга. Также это часто используют MDM (Mobile device management) системы.

Во-вторых, не допустить обход ограничений, внесенных в код. Ограничения на клиенте — это зло.

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

Какое-то время назад, а именно с iOS 4.0 до 4.2.1, существовала специальная функция в MDM API от Apple для определения JB. Но просуществовала она недолго — меньше шести месяцев. Причины исключения данной функции Apple не комментировала. По одной из версий, данная функция была опасна и сама могла привести к JB-атаке.

 

Обнаружение JB: новые файлы.

  1. Можно обратиться к файлам от Cydia (например, /Applications/Cydia.app/) или URI-схеме cydia://, которая появляется с ней. Данный метод очень часто встречается, но нужно иметь в виду, что Cydia — это всего лишь bundle и она может не входить в JB или быть удалена. Вот взять, например, последний JB от evad3rs для iOS 7. У них нет Cydia, но есть китайский App Store Taig.
  2. Можно пытаться обращаться просто к любым заранее известным файлам за пределы песочницы, будь то /bin/bash/Application/Preferences.app/General.plist или/Applications/MobileMail.app.
  3. Естественно, файлы от jailbreak не могут остаться без внимания — например,/private/var/stash. Их очень много, и их можно сначала определить по дате модификации в системе.
  4. Существуют и более экзотические способы, как, например, SSH loopback connection — обращение на 127.0.0.1 порт 22, поскольку обычно для взаимодействия с устройством пользователи ставят на него SSH.

Для обращения к URI-схеме можно использовать Objective-C-функцию openURL, а для работы с файлами как Obj-C-функции (BOOL)fileExistsAtPath:(NSString*)path), так и классические С-функции (fopen(), stat() или access()).

 

Обнаружение JB: изменение свойств

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

  • правам доступа на запись;
  • размеру /etc/fstab;
  • обнаруживаем символические ссылки на /var/stash с:/Applications /Library/Ringtones /Library/Wallpaper /usr/arm-apple-darwin9 /usr/include /usr/libexec /usr/share

Тут все просто, как и в предыдущем пункте. Опять же можно использовать как Obj-C-функции из класса NSFileManager, так и стандартные С типа statfs(), stat().

 

Обнаружение JB: измененное поведение или целостность Sandbox

Sandbox запрещает приложениям из App Store использовать такие функции, как fork(), popen(), или любую другую C функцию для создания дочернего процесса на устройстве за пределами jail. Так что пытаемся вызвать эти функции и смотрим результат. Или можно выполнить вызов system(), который вернет 0 в случае, если sandbox работает, и 1 — если jailbreak. Это связано с тем, что на устройстве с JB будет присутствовать /bin/sh. Еще более изощренный способ — это использовать dyldimagecount() и dyldgetimage_name() для просмотра, какие dylibs сейчас загружены, — после JB есть своя специфика. При этом данный метод достаточно сложно пропатчить.

 

Полезные ссылки

Интересный веб-проект для генерации кода для детекта JB: appminder.nesolabs.de

Обходы обнаружения JB

Если можно обнаружить детект, то можно обнаружить и процесс детектирования. А потом его нужным способом изменить :). Можно выделить три основных способа:

  1. Редактирование бинарного файла. Патчим сам код, данные в бинарнике. Например, если приложение определяет наличие JB по присутствию файла/Applications/Cydia.app/, то можно прямо в бинарнике исправить Cydia на Fydia, и такой файл в системе уже не найдется, и проверка провалится. Также можно патчить ARM-код, например условный переход на безусловный. Патчинг инструкций в ARM упрощает и то, что в нем все инструкции имеют фиксированную длину.
  2. Использование MobileSubstrate для хукинга Objective-C-функций. Если проверка реализована на Obj-C, то ее можно очень легко перехватить в runtime и вернуть нужное нам значение. Для примера можно посмотреть проект xCon, который как раз так и работает. В общем, можно посмотреть имена методов в классах на наличие таких, как JailbreakDetect, isJailbreak и так далее, затем пишем tweak, и защита пройдена.
  3. Игры во время выполнения программы (GDB, Cycript). Если проверка реализована как часть другой функции, то полностью заменить ее так просто мы не можем. Тут придется играть с GDB. В общем, ничего нового в этом способе нет по сравнению с Linux-платформой.

Рекомендации разработчикам

Помимо знания, что применять, нужно еще знать, как правильно это применять. Здесь хотелось бы дать несколько советов по защите iOS-приложения.

  1. Используй антиотладочные техники. Это хорошо всем известная функция ptrace(PTDENYATTACH, 0, 0, 0) и флаг P_TRACED.
  2. Используй техники anti hooking. В iOS детектировать hook можно с помощью dladdr() вызова и Dlinfo структуры. А еще лучше критичные фрагменты кода (проверки безопасности, jailbreak detect) в виде inline функций с помощью _attribute_((alwaysinline)).
  3. Обфусцируй свой код и данные. Специфика Objective-C в том, что он хранит много метаинформации о классах, функциях, переменных и так далее. Если в других компилируемых языках, как правило, это символы и они не попадают в финальную сборку, то тут все на виду, и это просто сказка для реверс-инженера — логика сразу понятна. Так что перед выпуском в релиз можно переименовывать имена классов и методов. Что касается критичных данных, то их надо шифровать или динамически генерировать.
  4. Если ты пытаешься определить наличие JB, то используй не одну технику, а несколько.

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

Информация о классах и методах из бинарника Mach-O
Информация о классах и методах из бинарника Mach-O

Для защиты от пиратства приложений можно проверять целостность собственных файлов. Например, целостность исполняемого файла — у всех взломанных/расшифрованных приложений LCENCRYPTIONINFO = 0, так как его расшифровывают. Или еще, как вариант, проверять файлы метаданных: iTunesMetadata.plist, SC_Info, Code Signing, Info.plist.

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

 

INFO

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

 

Цепочка загрузки iOS

Во-первых, существует три режима загрузки iOS: normal boot, DFU (device firmware upgrade) mode и recovery mode. Последние два, если не вдаваться в детали, необходимы для восстановления ОС в определенное состояние. Для обновления ОС через iTunes используется recovery mode. А на приведенном рисунке проиллюстрированы этапы при normal boot.

Во-вторых, при normal boot компоненты системы загружаются в такой последовательности: Bootrom -> LLB -> iBoot -> Kernel -> System Software -> Apps.

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

Возможные атаки на цепочку загрузки iOS
Возможные атаки на цепочку загрузки iOS

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    1 Комментарий
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии