Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
macos_sandbox — Запись в блоге, исследующая macOS App Sandbox, энтайтлменты через codesign и техники выхода из песочницы с использованием launchd, LaunchAgents и атрибутов карантина. | Kitploit
Инструменты/GitHubGitHub/yo-yo-yo-jbo/macos_sandbox
Механизмы персистентностиАнализ уязвимостейЭксплуатацияПост-эксплуатацияОбучение и ОбразованиеRed Teaming
GitHubyo-yo-yo-jbo/macos_sandbox

macos_sandbox

Запись в блоге, исследующая macOS App Sandbox, энтайтлменты через codesign и техники выхода из песочницы с использованием launchd, LaunchAgents и атрибутов карантина.

Репозиторий
3221 месяц назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Введение в macOS — песочница приложений

Продолжая серию постов о моём переходе на macOS, я хотел бы немного обсудить песочницу приложений macOS.
Настоятельно рекомендуется сначала прочитать пост о структуре приложений macOS — я буду предполагать, что читатель знает разницу между приложениями и процессами (задачами), немного разбирается в launchd и его связи с запуском приложений.

Песочница на примере

Когда я впервые узнал о песочнице macOS, я наивно попытался создать вредоносный макрос Word.
Это (до сих пор) очень распространённый вектор атак в экосистеме Windows, поэтому я хотел проверить, смогу ли я просто запускать процессы и в целом сеять хаос.
Что ж, на macOS всё не так просто — например, процессы я запускать мог, но, похоже, они мало что могли сделать.
При попытке записать файлы я постоянно получал загадочную ошибку Operation not permitted — что происходит?
Я начал читать о macOS и Word и наткнулся на этот отличный пост от Адама Честера (работает в MDSec). Я очень рекомендую прочитать его, но здесь я кратко изложу выводы:

  • Приложения могут использовать технологию под названием App Sandbox.
  • После настройки ОС применяет к приложению настраиваемые правила: какие имена файлов оно может создавать, может ли использовать сетевые возможности и так далее.

В macOS раньше была рабочая утилита sandbox-exec, которая выполняла команды в песочнице. Хотя она устарела, она могла многое прояснить. На её странице руководства видно, что она принимает profile, поэтому можно заключить, что правила песочницы хранятся в профилях. Эти профили могут быть разных видов и форм — файлы, предопределённые имена или даже строковые литералы.
На страницах руководства также сказано, что разработчикам следует использовать функцию App Sandbox. Читая дальше, я понял, что правила песочницы вшиты в бинарник; в нашем случае он находится по пути /Application/Microsoft Word.app/Contents/MacOS/Microsoft Word (если это кажется вам незнакомым, загляните в мой пост о структуре приложений macOS).
Хотя их можно легко извлечь вручную, лучше использовать инструмент codesign:

root@kitploit:~
```jbo@McJbo ~ % codesign -dv --entitlements - /Applications/Microsoft\ Word.app/Contents/MacOS/Microsoft\ Word
Executable=/Applications/Microsoft Word.app/Contents/MacOS/Microsoft Word
Identifier=com.microsoft.Word
Format=app bundle with Mach-O universal (x86_64 arm64)
CodeDirectory v=20500 size=351454 flags=0x10000(runtime) hashes=10972+7 location=embedded
Signature size=8980
Timestamp=Apr 10, 2023 at 8:09:50 AM
Info.plist entries=52
TeamIdentifier=UBF8T346G9
Runtime Version=13.1.0
Sealed Resources version=2 rules=13 files=28766
Internal requirements count=1 size=180
[Dict]
	[Key] com.apple.application-identifier
	[Value]
		[String] UBF8T346G9.com.microsoft.Word
	[Key] com.apple.developer.aps-environment
	[Value]
		[String] production
	[Key] com.apple.developer.team-identifier
	[Value]
		[String] UBF8T346G9
	[Key] com.apple.security.app-sandbox
	[Value]
		[Bool] true
    
...

	[Key] com.apple.security.temporary-exception.files.absolute-path.read-only
	[Value]
		[Array]
			[String] /Library/Preferences/com.microsoft.office.licensingV2.plist
			[String] /Library/Application Support/Microsoft/
      
...

	[Key] com.apple.security.temporary-exception.sbpl
	[Value]
		[Array]
			[String] (allow file-read* file-write* (require-all (vnode-type REGULAR-FILE) (regex #"(^|/)~\$[^/]+$")) )
			[String] (deny file-write* (subpath (string-append (param "_HOME") "/Library/Application Scripts")) (subpath (string-append (param "_HOME") "/Library/LaunchAgents")) )
	[Key] com.apple.security.temporary-exception.shared-preference.read-only
	[Value]
		[Array]
			[String] com.ThomsonResearchSoft.EndNote
			
...

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

  • Во-первых, в нашей команде использовался флаг -dv, который означает display и verbose. Затем --entitlements показывает entitlements (права), связанные с приложением или бинарником (да, codesign может работать с обоими). Мы углубимся в entitlements в отдельном посте, а пока скажем, что они отражают возможности приложения, и одно из них указывает, что приложение находится в песочнице (com.apple.security.app-sandbox имеет логическое значение True).
  • Первые несколько строк вывода — это общая информация о бинарнике, его хэше и многих других интересных вещах. Они выходят за рамки данного поста, но довольно интересны!
  • Далее мы получаем большой словарь. Те, кто помнит мои рассуждения о plist (опять же, в моём [посте о структуре приложений macOS]) возможно, подозревают, что словарь «ключ-значение» является представлением некоего property list, и они будут правы.
  • Правила песочницы указаны в некоторых ключах словаря. Например, com.apple.security.temporary-exception.files.absolute-path.read-only содержит массив абсолютных путей, из которых приложению разрешено читать.
  • Здесь же находится (пре)словутое регулярное выражение из com.apple.security.temporary-exception.sbpl — оно нужно для создания тех печально известных временных файлов , которые так любит Word.

Побег из песочницы через launchd

В посте MDSec от 2018 года, который я упоминал ранее, части deny file-write* в com.apple.security.temporary-exception.sbpl не существовало, что позволяло макросам создавать файлы с произвольным содержимым, например /Library/LaunchAgents/~$evil.plist. Почему это приводит к побегу из песочницы?
LaunchAgents и LaunchDaemons — хорошо известный (легитимный) механизм персистентности в macOS. Я упоминал их раньше, но вы можете думать о них как о службах (если вы пришли из мира Windows): LaunchDaemons запускаются при загрузке ОС (и поэтому работают вне пользовательской сессии), а LaunchAgents запускаются при входе пользователя в систему.
Интересно, что оба описываются в простых plist-файлах. Вот пример для моего обновлятора OneDrive:

root@kitploit:~
jbo@McJbo ~ % plutil -p /Library/LaunchAgents/com.microsoft.OneDriveStandaloneUpdater.plist
{
  "Label" => "com.microsoft.OneDriveStandaloneUpdater"
  "Program" => "/Applications/OneDrive.app/Contents/StandaloneUpdater.app/Contents/MacOS/OneDriveStandaloneUpdater"
  "ProgramArguments" => [
  ]
  "RunAtLoad" => 1
  "StartInterval" => 86400
}

Эти LaunchAgents и LaunchDaemons запускаются launchd (помните этот процесс?), и поэтому это приводит к побегу из песочницы, поскольку launchd не знал, был ли plist записан из процесса, находящегося в песочнице, или нет (а даже если бы знал — как бы он понял, какие правила песочницы применять?).

Эта концепция использования launchd для побега из песочницы macOS широко применялась, и, по сути, я сам использовал её в прошлом.
Экономя вам пару кликов — вот идея:

  • Как вы, возможно, помните, launchd запускает приложения macOS. Эти приложения могут запускаться двойным щелчком или другими способами — например, при щелчке по zip-файлу будет использоваться Archive Utility, поскольку он ассоциирован с zip-файлами.
  • Альтернативный способ запуска приложений через launchd — команда open.
  • Команда open очень богатая — можно использовать некоторые её интересные возможности, например выбрать приложение, выбрать имя файла для открытия или даже передать полные аргументы командной строки.
  • Я специально использовал встроенное приложение Python (которого больше нет на новых чистых устройствах macOS), чтобы запустить Python с аргументом stdin, который по сути перенаправляет стандартный ввод из файла, который я сохранил (этот файл был ~$evil.py из-за ограничений Word).
  • В нашем случае launchd запустил экземпляр приложения Python вне песочницы, который начал читать , содержащий произвольные Python-команды, что по сути обеспечило побег из песочницы.

Похожие идеи были и в других публикациях (один хороший пример — здесь), но идея остаётся той же. Я почти уверен, что их гораздо больше, и они прямо на виду!
Особого упоминания заслуживает отличный пост от Войцеха Регулы — на этот раз основное внимание уделяется приложению Terminal и манипулированию переменными окружения. Обязательно прочитайте!

Исправления и расширенный атрибут quarantine

Проблема, найденная MDSec, была специфична для Office — и была исправлена более строгими правилами.
Атаки, злоупотребляющие LaunchServices (так называется фреймворк для запуска приложений через launchd), носят более общий характер — и поэтому Apple пришлось их исправлять.
Одна из вещей, которые я заметил, — файлы, сохраняемые Word, теперь создаются с расширенным атрибутом com.apple.quarantine, да, тем самым, о котором я упоминал в своём посте введение в Gatekeeper.
Как оказалось, этот атрибут quarantine — своего рода усиление защиты от определённых атак. Например, приложение Terminal отказывалось запускать shell-скрипты, созданные с этим атрибутом. Кстати, именно поэтому мне пришлось использовать опцию --stdin для Python.

Дальнейшие исправления

Как указал Гергей Кальман, Apple добавила дополнительные проверки в бинарник open, чтобы усилить защиту от подобных эксплойтов. Похоже, что --stdin, --args и другие флаги командной строки игнорируются, если вызывающий процесс находится в песочнице. Однако open просто обращается к LaunchServices (в launchd) через IPC, и для этого удобно существуют API, например LSOpenURLsWithRole.
Я не проверял, усилен ли сам LaunchServices тоже; если нет, то, полагаю, аналогичные побеги из песочницы можно легко осуществить.

Резюме

Мы кратко обсудили ещё одну технологию macOS — песочницу. Мы увидели, насколько она мощная и настраиваемая, и как её можно обойти.
Мы также связали некоторые вещи воедино: как приложения работают с правилами песочницы, как запуск приложений через launchd нарушает не только деревья процессов, и как plist-файлы можно использовать во благо или во зло — в этот раз для персистентности (LaunchAgents и LaunchDaemons).
К счастью, мы даже связали расширенный атрибут com.apple.quarantine из поста введение в Gatekeeper и объяснили, как он может использоваться в качестве дополнительной защиты от побегов из песочницы. Неплохо!
В следующих нескольких постах мы рассмотрим другие механизмы безопасности в macOS и, возможно, поговорим о стратегиях их обхода.

Оставайтесь на связи!

Jonathan Bar Or (https://jonathanbaror.com)

Скачать инструмент
~$whatever.docx
  • Конечно, само собой разумеется, что новые дочерние процессы наследуют правила песочницы, иначе в этом нет особого смысла. Обратите внимание, насколько мощны эти правила песочницы!
  • ~$evil.py