Главная » Хабрахабр » [Перевод] Я могу стать Apple, и ты тоже

[Перевод] Я могу стать Apple, и ты тоже

Публичное раскрытие уязвимости в сторонней проверке подписи кода Apple

В отличие от некоторых предыдущих работ, данная уязвимость не требует прав администратора, не требует JIT-кода или повреждения памяти для обхода проверки подписи кода. Всё что нужно — правильно отформатированный файл Fat/Universal, и проверка подписи кода покажет валидный результат.

Резюме

  • Найденный обход применяемого сторонними разработчиками API для подписи кода позволяет представить любой код как подписанный Apple.
  • Все известные вендоры и проекты с открытым исходным кодом уведомлены (см. список ниже). Для них доступны патчи.
  • Есть вероятность, что проблема затрагивает другие сторонние программы, где используются официальные API подписи кода от Apple.
  • Разработчики несут ответственность за правильное использование API подписи кода. Есть инструменты демо-взлома (PoC) для тестов.
  • Относится только к macOS и более старым версиям OSX.

Затронутые вендоры

  • VirusTotal – CVE-2018-10408
  • Google – Santa, molcodesignchecker – CVE-2018-10405
  • Facebook – OSQuery – CVE-2018-6336
  • Objective Development – LittleSnitch – CVE-2018-10470
  • F-Secure – xFence (также LittleFlocker) CVE-2018-10403
  • Objective-See – WhatsYourSign, ProcInfo, KnockKnock, LuLu, TaskExplorer (и другие) – CVE-2018-10404
  • Yelp – OSXCollector – CVE-2018-10406
  • Carbon Black – Cb Response – CVE-2018-10407

Важность подписи кода и как это работает на macOS/iOS

Подпись кода — это конструкция безопасности, которая использует инфраструктуру открытых ключей (PKI) для цифровой подписи скомпилированного кода или даже скриптов, чтобы удостоверить надёжное происхождение и гарантировать аутентичность кода. На Windows вы можете криптографически подписать почти что угодно: от бинарников .NET до скриптов PowerShell. На macOS/iOS подпись кода относится в основном к двоичным файлам Mach-O и пакетам приложений, чтобы допускать к выполнению в памяти только доверенного кода.

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

В отличие от некоторых предыдущих работ, данная уязвимость не требует прав администратора, не требует JIT-кода или повреждения памяти для обхода проверки подписи кода. В подписи кода уже находили проблемы (1, 2, 3, 4, 5). Всё что нужно — правильно отформатированный файл Fat/Universal, и проверка подписи кода покажет валидный результат.

Подробности об уязвимости

Суть уязвимости в неодинаковой проверке подписи кода загрузчиком Mach-O и Code Signing API, которые используются неправильно. Эту разницу можно эксплуатировать с помощью специально сформированного двоичного файла Universal/Fat.

Что такое файл Fat/Universal?

Fat/Universal — это двоичный формат, который содержит несколько файлов Mach-O (исполняемый файл, dyld или пакет), каждый из которых ориентирован на определенную архитектуру CPU (например, i386, x86_64 или PPC).

Необходимые условия

  • Первый Mach-O в файле Fat/Universal должен быть подписан Apple, это может быть файл i386, x86_64 или даже PPC.
  • Самоподписанный вредоносный бинарник или посторонний код должен быть скомпилирован под i386 для macOS x86_64.
  • CPU_TYPE в заголовке Fat бинарника Apple должен быть установлен на недопустимый тип или тип процессора, не родной для чипсета хоста.

Без прохождения соответствующих SecRequirementRef и SecCSFlags программный интерфейс Code Signing API (SecCodeCheckValidity) проверит первый бинарник в файле Fat/Universal на предмет происхождения подписи (например, Apple) и убедится в аутентичности подписи. Затем API проверит все остальные бинарники в файле Fat/Universal на соответствие Team Identifiers и аутентичность подписи, но без проверки корня доверия центра сертификации. Причина, почему вредоносный код или «неподписанный» код, должен быть i386, заключается в том, что Code Signing API по умолчанию настроен на проверку в первую очередь подписи кода для нативной архитектуры CPU (x86_64).

На иллюстрации ниже показаны валидный бинарник Mach-O, подписанный Apple (python.х64), рядом с самоподписанным Mach-O (ncat.i386). Одна из причин, почему самоподписанный код успешно проходит проверку — потому что даже в основных бинарниках Apple поле TeamIdentifier установлено как not set. У обоих указано `TeamIdentifier=not set`.

Такой вариант подписи кода не проходит. Например, я подписал бинарник с помощью ID разработчика и попытался в lipo объединить его с бинарником от Apple в один файл Fat/Universal.

Здесь итоговый файл Fat содержит подписанный Apple двоичный файл python x86_64 и самоподписанный (adhoc) двоичный файл ncat i386. Мой первоначальный PoC — это ncat (от nmap), который я назвал ncat.frankenstein. Вот как он выглядит в MachOView: Самоподписанный бинарник легко создаётся командой codesign -s - target_mach-o_or_fat_binary.

Если запустить этот файл, то запустится именно python x86_64:

А подпись кода проходит проверку:

Как я запустил самоподписанный двоичный файл ncat?

Тогда загрузчик Mach-O пропускает двоичный файл Mach-O с действительной подписью и выполнит вредоносный (не подписанный Apple) код: Это делается путём установки недопустимого типа CPU_Type или ненативного CPU (например, PPC).

Потом выполняется ncat.frankenstein, и результатом проверки будет valid:

Мы опубликовали ncat.frankenstein и четыре других примера, чтобы разработчики могли проверить наличие уязвимости в своих продуктах.

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

В командной строке

Если используете codesign, то наверное знакомы со следующими командами: Зависит от того, как вы проверяете подписанный код.

  • codesign –dvvvv — дамп центра сертификации и TeamIdentifier (ID разработчика)
  • codesign –vv — строгая проверка всех архитектур

Но для правильной проверки этого типа злоупотреблений нужно добавить требование anchor-сертификата следующими командами:

  • codesign -vv -R='anchor apple' ./some_application_or_mach-o # для кода, подписанного Apple
  • codesign -vv -R='anchor apple generic' ./some_application_or_mach-o # для кода, подписанного Apple и разработчиком Apple

Такая команда покажет ошибку при проверке кода с чужой подписью:

Например, бинарник Mach-O с подписью Apple (/bin/ls) и Safari возвращает следующее: Можно использовать команду spctl, но она требует тщательного анализа вывода команды.

А вот результат приложения, подписанного Apple:

Для сравнения, вот результат файла Fat/Universal ncat.frankenstein: Обратите внимание на строку “(the code is valid but does not seem to be an app)” для /bin/ls, который не проходит проверку.

Таким образом, я не могу рекомендовать spctl для ручной проверки автономных двоичных файлов Mach-O. Для файла ncat.frankenstein Fat/Universal не отображается, что код действителен. Просто используйте codesign с соответствующими флагами.

Для разработчиков

Как правило, разработчики проверяют бинарники Mach-O или Fat/Universal с помощью API SecStaticCodeCheckValidityWithErrors() или SecStaticCodeCheckValidity() со следующими флагами:

Эти флаги должны гарантировать, что весь загруженный в память код в файле Mach-O или Fat/Universal криптографически подписан. Тем не менее, эти API по умолчанию не обеспечивают должную проверку, так что сторонним разработчикам требуется вычленять каждую архитектуру в файле Fat/Universal и проверять, что identities совпадают и криптографически надёжны.

Лучший способ проверить каждую вложенную архитектуру в файле Fat/Universal — это сначала вызвать SecRequirementCreateWithString с требованием “anchor apple”, затем SecStaticCodeCheckValidity с флагами kSecCSDefaultFlags | kSecCSCheckNestedCode | kSecCSCheckAllArchitectures | kSecCSEnforceRevocationChecks со ссылкой на требование; как показано в пропатченном исходном кодеWhatsYourSign.

Кроме того, передавая флаги и требование к SecStaticCodeCheckValidity, все архитектуры проверяются на это требование, и применяются проверки отзыва. Передавая “anchor apple”, в функцию SecRequirmentCreateWithString, такой вызов действует аналогично команде codesign -vv -R=’anchor apple’ , требуя наличия цепочки доверия Apple Software Signing для всех вложенных бинарников в файле Fat/Universal.

Демонстрации

Инструмент codesign от Apple и необходимость использовать флаг -R.

LittleSnitch — проверка файла Fat/Universal на диске не проходит, но LittleSnitch корректно проверяет процесс в памяти.

LittleFlocker — F-Secure купила LittleFlocker, и теперь он называется xFence.

F-Secure xFence (бывший LittleFlocker)

Инструменты Objective-See

TaskExplorer

WhatsYourSign

Facebook OSquery — результат проверки вредоносных образцов и /bin/ls в качестве валидного примера.

Выдача Google Santa – Fileinfo показывает, что ncat.frankenstein в белом списке:

Запрет выполнения ncat (неподписанного) и разрешение выполнения ncat.frankenstein:

Журнал santa.log с демонстрацией событий из предыдущего примера:

Carbon Black Response

VirusTotal — пример bash_ppc_adhoc до установки патча в VirusTotal:

Сроки раскрытия

22.02.2018: в Apple отправлен отчёт и PoC для обхода сторонних систем безопасности.

03. 01. 2018: Apple ответила, что сторонние разработчики должны использовать kSecCSCheckAllArchitectures и kSecCSStrictValidate с SecStaticCodeCheckValidity API, и документация для разработчиков будет соответствующим образом обновлена.

03. 06. 2018: в Apple отправлен отчёт и PoC для обхода флагов и строгой проверки codesign.

03. 16. 2018: отправлена дополнительная информация в Apple.

03. 20. 2018: Apple заявила, что не рассматривает это как проблему безопасности, которую следует решать напрямую.

03. 29. 2018: Apple заявила, что документация может быть обновлена, но «[...] сторонним разработчикам следует выполнить дополнительную работу для проверки, что все identities в универсальном двоичном файле одинаковы, если они хотят представить осмысленный результат».

04. 02. 2018: первый контакт с CERT/CC и последующее сотрудничество для уточнения масштабов и влияния уязвимости.

04. 09. 2018: все известные сторонние разработчики, которых затронула уязвимость, уведомлены в координации с CERT/CC.

04. 18. 2018: последний контакт с CERT/CC с рекомендацией, что публичное раскрытие информации в блоге лучше всего подходит для уведомления остальных сторонних разработчиков, которые используют API подписи кода от Apple в частном порядке.

06. 05. 2018: окончательный контакт с разработчиками перед публикацией.

06. 12. 2018: раскрытие информации.

В заключение

Спасибо всем сторонним разработчикам за их кропотливую работу и профессионализм в решении этого вопроса. Уязвимости подписи кода — это особенно деморализующие баги, тем более для компаний, которые пытаются обеспечить безопасность лучше, чем по умолчанию в операционной системе.
АКЦИЯ GMO GlobalSign Russia для подписчиков Habr

Дополнительную информацию вы можете получить, связавшись с менеджером GlobalSign по телефону: +7 (499) 678 2210, либо заполнив форму на сайте с указанием промо-кода CS002HBFR.


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

[Перевод] Как Apple пошла вопреки пяти общепринятым PR-нормам, но сохранила своё доброе имя

Спустя несколько дней после запуска iPhone 4 (самый успешный из когда-либо запускаемых Apple продуктов) – пошли слухи о том, что при определённом способе захвата мобильника (при т.н. В январе 2010 Apple столкнулась с огромным кризисом, который сулил резкое падение репутации. ...

[Из песочницы] Локальный NPM репозиторий за 5 минут со своими пакетами и кэширование

Доброго времени суток! Рано или поздно в организациях возникают проблемы с распространением js модулей между проектами, настало то время когда в нашей компании встал этот вопрос. Копировать и вставлять код это путь на темную сторону, поэтому было принято решение писать ...