0,1
рейтинг
5 февраля 2013 в 15:43

Разработка → Evasi0n под микроскопом перевод

Совсем недавно вышел свежий набор утилит для «джейла» iOS. Пришло время разобрать его и посмотреть, какие эксплойты и механизмы проникновения он использует. Сейчас «джейлить» iOS стало настолько просто, что люди забывают, насколько это сложный процесс. Механизмы защиты, встроенные в пространство пользователя, такие как песочница, ASLR (Address Space Layout Randomisation – рандомизация расположения в адресном пространстве) и механим цифровых подписей, делают процесс написания «джейла» невероятно сложным.

Стоит отметить, что, в отличие от предыдущих эксплойтов jailbreak.me, которые можно было использовать на ничего не подозревающих жертвах, «джейлы», которые требуют подключения по USB, обычно несут меньшие угрозы безопасности, и типично полезны только самому владельцу устройства. Злоумышленники заинтересованы в них меньше, так как айфон с установленным пин-кодом откажется общаться по USB, если он заблокирован, если он, конечно, ранее не был синхронизирован с компьютером, куда его подключают. Таким образом, если телефон был украден и на нем был установлен пин-код, злоумышленник не сможет «джейлнуть» его. Только вредоносный код, выполняемый на вашем компьютере, может иметь хоть какую-то возможность выполнить «джейл» незаметно.

Evasi0n в пространстве пользователя


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

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

MobileBackup использует домен, например MediaDomain, и относительный путь в пределах домена для идентификации каждого файла. За каждым доменом константно зафиксирована определенная директория, и комбинация из пути к этой директории и относительного пути к файлу дает полный путь. Evasi0n создает все рабочие файлы в домене MediaDomain, таким образом у всех файлов рабочий префикс это /var/mobile/Media.

Этап 1


Во время первого этапа, Evasi0n создает новую пустую архивную копию для восстановления на устройство, содержащую следующие файлы:

directory: Media/
directory: Media/Recordings/
symlink:   Media/Recordings/.haxx -> /var/mobile
directory: Media/Recordings/.haxx/DemoApp.app/
file:      Media/Recordings/.haxx/DemoApp.app/Info.plist
file:      Media/Recordings/.haxx/DemoApp.app/DemoApp
file:      Media/Recordings/.haxx/DemoApp.app/Icon.png
file:      Media/Recordings/.haxx/DemoApp.app/Icon@2x.png
file:      Media/Recordings/.haxx/DemoApp.app/Icon-72.png
file:      Media/Recordings/.haxx/DemoApp.app/Icon-72@2x.png
file:      Media/Recordings/.haxx/Library/Caches/com.apple.mobile.installation.plist


Символьная ссылка из .haxx в /var/mobile создается для обхода ограничения работы с файлами только в пределах домена, т.е. хотя стандартное ограничение не допустит копирования фалов вне /var/mobile/Media, но с помощью символьной ссылки файлы фактически попадают в /var/mobile. Этот подход уже использовался в «джейлах» и ранее.

Далее, DemoApp.app, обычное iOS приложение, создается в /var/mobile. Это обычное приложение, с иконками и прочими сопроводительными файлами. Так же обновляется файл com.apple.mobile.installation.plist, где Springboard хранит кеш путей к приложениям, чтобы иконка DemoApp появилась среди остальных.

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

#!/bin/launchctl submit -l remount -o /var/mobile/Media/mount.stdout -e /var/mobile/Media/mount.stderr -- /sbin/mount -v -t hfs -o rw /dev/disk0s1s1


Фактически, при запуске программы DemoApp, на самом деле запускается launchctl с заданными аргументами.

Помимо этого, в com.apple.mobile.installation.plist немного модифицируется окружение для запуска DemoApp:

<key>EnvironmentVariables</key>
<dict>
  <key>LAUNCHD_SOCKET</key>
  <string>/private/var/tmp/launchd/sock</string>
</dict>


Устройство перезагружается, Springboard перечитывает кеш и отображает иконку.

Этап 2.1


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

directory: Media/
directory: Media/Recordings/
symlink:   Media/Recordings/.haxx -> /var/db
symlink:   Media/Recordings/.haxx/timezone -> /var/tmp/launchd


Фактически, это просто создание символьной ссылки /var/db/timezone на файл /var/tmp/launchd. Типичные права доступа на /var/tmp/launchd такие:

drwx------ 2 root   wheel  102 Feb  4 12:17 launchd


Эти права доступа не дают обычным приложениям (запущенным от пользователя mobile) исследовать данный каталог.

Следующим шагом, Evasi0n общается c lockdownd, путем отправки неправильно сформированной команды PairRequest. Lockdownd – это основной демон, который выполняет коммуникацию по USB, так же он используется для запуска/остановки других сервисов, таких как MobileBackup и AFC (Apple File Connection – сервис который позволяет обмениватся файлами с iTunes). Поскольку lockdownd работает с правами root-пользователя и пользователь может общаться с ним, злоупотребление его возможностями или уязвимостями стало популярным в последних «джейлах».

Теперь мы подошли к первой уязвимости. Отправка некорректного пакета PairRequest заставляет lockdownd изменить права доступа к /var/db/timezone на 777, таким образом делая /var/tmp/launchd доступным для всех пользователей. Не ясно, уязвимость ли это непосредственно lockdownd или какой-то из библиотек, которуе он использует.

Этап 2.2


Evasi0n проникает вглубь /var/tmp/launchd и модифицирует права доступа таким образом, что сокет launchd становится доступным обычному пользователю. Также на этом этапе обновляется символьная ссылка на timezone:

symlink:   Media/Recordings/.haxx/timezone -> /var/tmp/launchd/sock


Потом Evasi0n повторяет трюк с PairRequest, делая /var/tmp/launchd/sock доступным пользователю mobile.

Этап 2.3


Этот этап начинается с установки Cydia и архива пакетов на устройство. Они не будут использоваться прямо сейчас, но будут доступны уже после «джейла».

Далее, пользователю дается указание запустить приложение Jailbreak (фактически – DemoApp). Напомню еще раз, что оно делает:

#!/bin/launchctl submit -l remount -o /var/mobile/Media/mount.stdout -e /var/mobile/Media/mount.stderr -- /sbin/mount -v -t hfs -o rw /dev/disk0s1s1


с установленным окружением

LAUNCHD_SOCKET = /private/var/tmp/launchd/sock


Если заглянуть в man по launchctl то можно выяснить, что команда submit описана следующим образом:

  submit -l label [-p executable] [-o path] [-e path] -- command [args]
                A simple way of submitting a program to run without a configura-
                tion file. This mechanism also tells launchd to keep the program
                alive in the event of failure.

                -l label
                         What unique label to assign this job to launchd.

                -p program
                         What program to really execute, regardless of what fol-
                         lows the -- in the submit sub-command.

                -o path  Where to send the stdout of the program.

                -e path  Where to send the stderr of the program.


А в man по launchd указано:

ENVIRONMENTAL VARIABLES

LAUNCHD_SOCKET
  This variable is exported when invoking a command via the launchd command line. It informs launchctl how to find the correct launchd to talk to.


В отличие от большинства других вещей в iOS, IPC в launchd основан на unix-сокетах. Так же, есть несколько процессов launchd – по одному для каждого активного пользователя. На iOS один работает с правами root, другой – с правами mobile. Пользователь mobile выполняет launchctl через DemoApp, но этот launchctl общается не с launchd пользователя mobile, вместо этого он общается с launchd пользователя root из-за явно указанного пути к сокету и расширенных прав доступа, полученных через уязвимость с /var/db/timezone.

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

Этап 3


Финальный этап «джейла», и снова используется MobileBackup, но на этот раз уже есть полный доступ в системный раздел:

directory: Media/
directory: Media/Recordings/
symlink:   Media/Recordings/.haxx -> /
symlink:   Media/Recordings/.haxx/private/etc/launchd.conf -> /private/var/evasi0n/launchd.conf
directory: Media/Recordings/.haxx/var/evasi0n
file:      Media/Recordings/.haxx/var/evasi0n/evasi0n
file:      Media/Recordings/.haxx/var/evasi0n/amfi.dylib
file:      Media/Recordings/.haxx/var/evasi0n/udid
file:      Media/Recordings/.haxx/var/evasi0n/launchd.conf


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

Собственно, при загрузке будут выполнены следующие команды:

bsexec .. /sbin/mount -u -o rw,suid,dev /
setenv DYLD_INSERT_LIBRARIES /private/var/evasi0n/amfi.dylib
load /System/Library/LaunchDaemons/com.apple.MobileFileIntegrity.plist
bsexec .. /private/var/evasi0n/evasi0n
unsetenv DYLD_INSERT_LIBRARIES
bsexec .. /bin/rm -f /private/var/evasi0n/sock
bsexec .. /bin/ln -f /var/tmp/launchd/sock /private/var/evasi0n/sock


Сделают они следующее:

  • перемонтируют системный раздел с правами на запись;
  • amfi.dylib будет внедрен в любое приложение, начиная с этого момента;
  • запускается сервис MobileFileIntegrity;
  • запускается «вредоносный» код, записанный на предыдущем этапе;
  • amfi.dylib больше не будет внедрятся;
  • удаляется старая символьная ссылка на сокет в /private/var/evasi0n/sock;
  • обновляется символьная ссылка /private/var/evasi0n/sock указывающая на /var/tmp/launchd/sock, позволяющая другому коду непосредственно взаимодействовать с launchd пользователя root.


Evasi0n перзагружает устройство, что выполняет описанную конфигурацию. Интересный момент связан с тем что ни amfi.dylib, ни evasi0n не содержат цифровой подписи. Если изучить файл amfi.dylib с помощью otool, выясняется что в нем нет секции __text (прим переводчика: в секции __text сегмента __TEXT хранится машинный код). А если нет секции __text – то и подписывать нечего, и проверка на цифровую подпись выполняться не будет. Работает amfi.dylib с помощью информации о позднем связывании:

$ dyldinfo -export amfi.dylib 
export information (from trie):
[re-export] _kMISValidationOptionValidateSignatureOnly (_kCFUserNotificationTokenKey from CoreFoundation)
[re-export] _kMISValidationOptionExpectedHash (_kCFUserNotificationTimeoutKey from CoreFoundation)
[re-export] _MISValidateSignature (_CFEqual from CoreFoundation)


Эта техника рассмотрена в http://networkpx.blogspot.com/2009/09/compiling-iphoneos-31-apps-with-xcode.html:

Если мы сможем заставить MISValidateSignature() всегда возвращать 0, любые файлы пройдут тест. Эта функция – часть libmis.dylib, которая сейчас хранится в разделяемом кеше, так что сложно пропатчить саму функцию. Заменить реализацию этой функции с помощью MobileSubstrate было бы замечательно, но как я ни пытался, MS не мог ее подменить. Тогда я использовал трюк: создал «проксирующую» библиотеку, которая переадресует MISValidateSignature().


С помощью хитрого использования динамической библиотеки без кода, существующие настоящие функции (такие как CFEqual()) повторно экспортируются как другие функции с идентичными аргументами, что приводит к тому, что MISValidateSignature() всегда возвращает 0, позволяя выполнять любой исполняемый файл.

Итог


Evasi0n интересен тем, что он повышает привилегии и получает полный доступ к системному разделу без повреждений памяти процессов. С помощью уязвимости /var/db/timezone он получает доступ к launchd и модифицирует MobileFileIntegrity так, чтобы он всегда подтверждал, что цифровые подписи корректны.
Перевод: Peter Morgan, Ryan Smith, Braden Thomas, & Josh Thomas
Владимир Пузанов @farcaller
карма
181,7
рейтинг 0,1
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (46)

  • +22
    Красиво!
    • +1
      я бы сказал: красиво, но мало, что понятно :)
      • +7
        Старался переводить понятным языком. Давайте уточню какие-то моменты?
        • +4
          нет, перевод то может быть и хороший, я к тому, что я далек от iOS разработки и мало, что понятно. А вообще да, интересно было бы понимать это все.
          • +2
            тут больше по UNIX и Objective-C Runtime окружению, а не чисто iOS (ну разве кроме MISValidation...)
            • +7
              Прикольные слова :)
              • +2
                думаю Вы сами все прекрасно понимаете — iOS — это UNIX/Mach просто сильно запиленный под ARM, с дополнением Cocoa Touch и проприетарными фишками поверх стандартной инфраструктуры (кстати именно поэтому и баг с неподписанным кодом так успешно прошел — если бы была проверка сигнатуры для всех секций ELF — то тогда да, было бы веселее).
                • +1
                  Дело в том, что у остальных секций иногда есть легитимные права на изменения (и да, там не ELF, там Mach-O, но не суть). Но идея в библиотеке без __text просто шикарна, конечно.
                  • 0
                    Точно, путаю — действительно для Mach — Mach Object File.
                    Дело в том что проверка подписи секций технически должна идти сразу и после проверки релоков — а в Apple решили проверять только код в секции __text (за что им конечно огромное спасибо)
    • +7
      Они вообще молодцы. Jailbreak всех Apple девайсов, при чем одной кнопкой, простой и лаконичный интерфейс программы, поддержка Linux. По сравнению со всякими Redsn0w это просто небо и земля.
      • 0
        Absinthe тоже ставился в одну кнопку, и работал на 3х системах.
      • +1
        Apple-way
      • +1
        Не всех, Apple TV 3 так и не сломали.
        • 0
          Это ведь шутка, да?
          • 0
            Увы нет.
            Мне-то и Apple TV 2 хватает, но их сейчас только на ебее достать можно, причём в два раза дороже, чем новые Apple TV 3 и 3.2 :)
            • 0
              Вы ожидали, что jailbreak для iOS 6.1 сломает Apple TV 3?
              • +1
                Мне всё равно, так как у меня уже есть джейлбрейкнутый Apple TV 2.
                Я лишь поправил вас, когда вы заявили:
                Jailbreak всех Apple девайсов, при чем одной кнопкой
              • 0
                Если он ломает ATV2 (с iOS 5.2), то лично я да, ожидал что он сломает Apple TV 3.
  • +1
    symlink: Media/Recordings/.haxx -> /var/mobile
    Символьная ссылка из .haxx в /var/mobile создается для обхода ограничения работы с файлами только в пределах домена, т.е. хотя стандартное ограничение не допустит копирования фалов вне /var/mobile/Media, но с помощью символьной ссылки файлы фактически попадают в /var/mobile.
    Далее, DemoApp.app, обычное iOS приложение, создается в /var/mobile.
    Правильно я понял, что iOS проверяет права доступа только у символьных ссылок, а не у файлов, на которые они ссылаются? Странно, что не закрыли такой явный баг, если
    Этот подход уже использовался в «джейлах» и ранее.
    Или я чего-то не понимаю, и это не баг, но фича?

    Получается, что Apple может очень просто закрыть дыру пофиксив функцию PairRequest и/или проверку прав доступа к символьным ссылкам. Если так, то апдейт iOS может выйти уже через через пару дней — нужно поспешить апдейтнуться до iOS 6,1 и сделать джейл, пока не закрыли дыру.
    • +1
      Правильно я понял, что iOS проверяет права доступа только у символьных ссылок, а не у файлов, на которые они ссылаются


      Нет, тут скорее вопрос побега из «песочницы». Права у фалов бекапа вообще не проверяются.

      Получается, что Apple может очень просто закрыть дыру пофиксив функцию PairRequest


      Да, скорее всего.
      • +1
        Нет, тут скорее вопрос побега из «песочницы». Права у фалов бекапа вообще не проверяются.
        Теперь понял. Получается, что iOS подсовывают «некорректный» образ, в котором есть папка Media/Recordings/.haxx/DemoApp.app/, но при этом папка Media/Recordings/.haxx — это символьная ссылка в защищённую область /var/mobile. Вот файлы из образа и восстанавливаются непредназначенное для них место. Хитро.

    • 0
      Надо не забыть на всякий случай, даже если и не обновляться на iOS 6.1, сохранить SHSH Blob через TinyUmbella на будущее.
      Что-то мне кажется ошибку могут быстро поправить, если конечно у Apple не будет какого-то скрытого интереса оставить её открытой еще какое-то время.
  • +3
    Интересно как быстро среагирует на это Apple?
    • +2
      Я думаю, что в следующей версии прошивки дыра уже будет закрыта. Жаль, что чип пока не взломали, Comex не зря старался…
      • +7
        Подозреваю, что у этих ребят наготове ещё несколько уязвимостей, ожидающих своей очереди до следующего обновления.
      • 0
        Ломать чипы без спец оборудования проблематично.
    • 0
      Как только прочитает статью :)
    • 0
      Если они будут сильно урезать права на запись то тогда восстановление системных файлов будет невозможно.
      А по поводу бага с пакетом — мб. это не баг а специальная недокументированная функция?
      • 0
        Ну симлинки, кстати, можно урезать с чистой совестью, они, по идее, не используются.
  • 0
    Стоит особо отметить, что вопреки вступлению, эксплоит использует не только файловую систему, но и уязвимость в lockdownd, позволяющую поднять права доступа к файлу до 777.
    • 0
      Во вступлении имелось в виду, что проникновение сделано без участия memory corruption, как это делалось в джейлах ранее.
  • +8
    Замечательная статья, прочёл час назад в оригинале. Спасибо за перевод!
  • +16
    Наконец то начал более менее предстаавлять что у джейла под капотом. Всегда было интересно. Головы конечно у ребят что надо.
    • +4
      Очень подробно ещё расписано в iOS Hacker's Handbook. Только там про предыдущие версии, которые эксплуатировали уязвимость в железе. Интересно, выпустят её новую версию про iOS 6?
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Подозреваю, что так долго из-за этого:
      Отправка некорректного пакета PairRequest заставляет lockdownd изменить права доступа к /var/db/timezone на 777

      И
      Address Space Layout Randomisation – рандомизация расположения в адресном пространстве

      Часто при эксплуатации уязвимостей приходится перебирать какой-нибудь параметр.
      • +1
        Часто при эксплуатации уязвимостей приходится перебирать какой-нибудь параметр


        Это вы о «fuzzing». В данном случае, ASLR к эксплойту не имеет отношения. ASLR вообще защищает от «повреждений памяти», например buffer overrun. Защита обеспечивается тем, что мы имеем возможность выполнить буквально несколько инструкций, и мы не знаем внутреннее состояние процесса (где в памяти что лежит).
  • +1
    Это всё конечно замечательно. Только теперь у всех проблемы с простыми программами вроде погоды и другими приложениями(
    • +3
      Инструкция по починке погоды, может кому пригодится.
    • 0
      А что ещё сломалось?
      iTunes Match? iBooks?
    • +2
      Интереснее было бы узнать почему джейл повлиял на погоду.
  • 0
    Понял от силы половину. В восторге от искуссной работы.
  • 0
    Интересно, а та китайская программа работает этим же способом устанавливая пиратские приложения?
    • 0
      Скопировать файлы приложения туда, где их найдет Springboard – это совершенно не проблема. Проблема только с цифровой подписью, а обойти ее уже существенно проблематичнее. Если конечно этот механизм не был отключен целиком во время джейла.
      • 0
        Я имею ввиду некий ksetup вышедший ранее и умеющий ставить любые приложения без джейла.
    • 0
      Я проводил небольшое исследование. Как я понял, она не ставит взломанные приложения. Все приложения были легально куплены в AppStore. Если посмотреть ipa пакеты, то все приложения подписаны Apple и куплены с одного AppleID. Задача программы лишь в передаче девайсу данных этого AppleID. Это так же подтверждает тот факт, что все бинарники шифрованы (взломанные приложения всегда расшифрованы) и при необходимости просят ввести тот самый AppleID. Именно поэтому нельзя установить через китайскую программу крякнутые ipa — iOS отказывается их устанавливать, потому что у них недействительная цифровая подпись.

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