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

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

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

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

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

Категории

Все категории
Loading categories
macos_app_structure — Образовательное глубокое погружение в пакеты приложений macOS, plist-файлы и поведение процессов launchd, с заметками по offensive security об упаковке полезных нагрузок в .app-файлы и обходе мониторинга дерева процессов. | Kitploit
Инструменты/GitHubGitHub/yo-yo-yo-jbo/macos_app_structure
Механизмы персистентностиОбход IDS/IPSОбучение и ОбразованиеRed TeamingРазработка Полезной Нагрузки
GitHubyo-yo-yo-jbo/macos_app_structure

macos_app_structure

Образовательное глубокое погружение в пакеты приложений macOS, plist-файлы и поведение процессов launchd, с заметками по offensive security об упаковке полезных нагрузок в .app-файлы и обходе мониторинга дерева процессов.

Популярное

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

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

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

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

Смотреть все инструменты →
Поделиться
Репозиторий
4721 месяц назадПроверено Kitploit

Знакомство с macOS — структура приложений macOS

Переход на macOS с Linux или Windows может ощущаться как прогулка по незнакомой новой земле. Поскольку Linux имеет открытый исходный код, а Windows хорошо документирована и очень популярна (а macOS — ни то, ни другое, если быть точным), macOS иногда может быть сложной. В этом посте я хочу обсудить некоторые из первых вещей, которые вы можете заметить в macOS, — приложения, приложения повсюду!

Приложения против процессов (задач?)

Если вы пришли из мира Windows или Linux, концепция приложений (Apps) может показаться странной. Мы все знаем, что потоки — это «единицы выполнения», а процессы — это контейнеры для потоков с собственным адресным пространством — что ещё тут может быть? Что ж, процессы редко ограничиваются одним файлом. И в Windows, и в Linux коду для работы может требоваться множество вещей, вот некоторые из них:

  • Загружаемые модули (.dll, .so). Например, библиотека времени выполнения C (msvcr<version>.dll в Windows, libc-<version>.so), а также другие зависимости.
  • Ресурсы. Например, в Windows исполняемые файлы имеют формат PE, в котором есть каталоги — одним из них является каталог ресурсов (он даже частично задокументирован здесь), который может содержать ресурсы (изображения, строки и другое). Разумеется, ресурсы также могут загружаться с диска динамически.
  • Цифровые подписи. В Linux они менее распространены (хотя в некоторой форме существуют — например, в пакетах Debian), но они важны. В Windows они могут находиться в самом файле PE (читайте здесь) или в файлах каталогов (то есть внешне).
  • Конфигурация. В Linux это файлы (например, ваши надёжные файлы .bashrc), а в Windows они распределены между файлами (например, xml, ini, json) и реестром Windows.
  • Другие исполняемые файлы.

Что ж, macOS делает большой упор на пакеты приложений. Идея состоит в том, чтобы упаковать (почти) всё необходимое для работы программы в структуру каталогов — включая ресурсы, информацию о локализации и т. д. Конечно, не всё можно аккуратно упаковать (например, библиотеку времени выполнения C), но это всё равно означает, что всё аккуратно упаковано вместе — нет необходимости ориентироваться в огромном реестре или читать man-страницы в поисках малопонятных расположений конфигурационных файлов. Пакеты приложений — это просто каталоги, заканчивающиеся на .app, хотя интерфейс скрывает расширение .app (и тот факт, что это каталог). С точки зрения атакующего это интересно — поскольку Application Bundle может иметь произвольные значки и скрывает расширение .app, доставка вредоносного ПО может быть осуществлена путём обмана ничего не подозревающего пользователя, заставив его кликнуть на такое приложение. Например, представьте файл Resume.app со значком PDF.

Структуру каталога Application Bundle можно легко изучить — например, с помощью встроенного приложения Calculator:

root@kitploit:~
jbo@McJbo ~ % cd /System/Applications/Calculator.app
jbo@McJbo Calculator.app % ll
total 0
drwxr-xr-x   3 root  wheel    96 Mar 17 21:34 .
drwxr-xr-x  43 root  wheel  1376 Mar 17 21:34 ..
drwxr-xr-x   9 root  wheel   288 Mar 17 21:34 Contents
jbo@McJbo Calculator.app % cd Contents
jbo@McJbo Contents % ll
total 16
drwxr-xr-x    9 root  wheel   288 Mar 17 21:34 .
drwxr-xr-x    3 root  wheel    96 Mar 17 21:34 ..
-rw-r--r--    1 root  wheel  2147 Mar 17 21:34 Info.plist
drwxr-xr-x    3 root  wheel    96 Mar 17 21:34 MacOS
-rw-r--r--  204 root  wheel     8 Mar 17 21:34 PkgInfo
drwxr-xr-x    4 root  wheel   128 Mar 17 21:34 PlugIns
drwxr-xr-x   54 root  wheel  1728 Mar 17 21:34 Resources
drwxr-xr-x    3 root  wheel    96 Mar 17 21:34 _CodeSignature
-rw-r--r--    1 root  wheel   461 Mar 17 21:34 version.plist
jbo@McJbo Contents % cd MacOS
jbo@McJbo MacOS % ll
total 344
drwxr-xr-x  3 root  wheel      96 Mar 17 21:34 .
drwxr-xr-x  9 root  wheel     288 Mar 17 21:34 ..
-rwxr-xr-x  1 root  wheel  540912 Mar 17 21:34 Calculator
jbo@McJbo MacOS %

Как вы можете видеть, Calculator.app — это каталог. Внутри него находится один элемент — ещё один каталог с именем Contents. В Contents находятся несколько элементов:

  • Info.plist — содержит метаданные о приложении. Подробнее об этом позже.
  • MacOS — содержит основной исполняемый файл приложения (как видно в третьем листинге каталога).
  • PkgInfo — необязательный. Двоичный файл, содержащий информацию о пакете.
  • PlugIns — необязательный. Каталог, который может содержать плагины для приложения. В Calculator их два — один для «Базовый и научный» и один для «Шестнадцатеричный» (я правда не знаю, зачем они сделали такое разделение, да мне и всё равно).
  • Resources — необязательный. Как следует из названия, содержит ресурсы. Там можно найти несколько элементов, включая файл .icns со значками, а также каталоги с суффиксом .lprroj, связанные с локализацией.
  • _CodeSignature — необязательный. Как следует из названия, содержит информацию о подписи кода.
  • version.plist — необязательный, содержит информацию о версии.

Обратите внимание, что официально обязательных элементов очень мало. На самом деле мы можем создать наше первое собственное приложение, даже ничего не компилируя! Но сначала мы должны обсудить файл Info.plist.

Файлы списков свойств

Чем больше вы смотрите на macOS, тем больше будете находить эти странные файлы. Это не более чем приукрашенные конфигурационные файлы. У них всегда будет расширение .plist, которое является просто сокращением их формального названия: файлы Property list. К сожалению, Apple поддерживает 3 различных формата plist:

  • Формат xml, читаемый человеком.
  • Формат json, не получивший широкого распространения.
  • Бинарный формат — обычно его можно опознать по магическому тексту bplist.

К счастью, существует утилита plutil, которая поддерживает все форматы. Чтобы вывести содержимое файла plist, просто используйте plutil -p. Например:

root@kitploit:~
jbo@McJbo Contents % plutil -p Info.plist | head -n 20
{
  "BuildMachineOSBuild" => "22A380007"
  "CFBundleDevelopmentRegion" => "English"
  "CFBundleExecutable" => "Calculator"
  "CFBundleGetInfoString" => "10.14, Copyright © 2000-2018, Apple Inc."
  "CFBundleHelpBookFolder" => "Calculator.help"
  "CFBundleHelpBookName" => "com.apple.Calculator.help"
  "CFBundleIconFile" => "AppIcon"
  "CFBundleIconName" => "AppIcon"
  "CFBundleIdentifier" => "com.apple.calculator"
  "CFBundleInfoDictionaryVersion" => "6.0"
  "CFBundleName" => "Calculator"
  "CFBundlePackageType" => "APPL"
  "CFBundleShortVersionString" => "10.16"
  "CFBundleSignature" => "????"
  "CFBundleSupportedPlatforms" => [
    0 => "MacOSX"
  ]
  "CFBundleVersion" => "223"
  "CTIgnoreUserFonts" => 1
jbo@McJbo Contents %

В plutil также встроены функции преобразования — сейчас мы их демонстрировать не будем. Apple документирует несколько требований к Info.plist приложения, но по-настоящему обязательных полей очень мало. Вот несколько интересных полей:

  • CFBundleExecutable — имя основного исполняемого файла, который, как ожидается, находится в каталоге MacOS.
  • CFBundleIconFile — имя файла значка. Необязательный.
  • CFBundleIdentifier — идентификатор пакета приложения. Apple рекомендует использовать обратную нотацию DNS (например, com.apple.calculator).
  • CFBundleName — имя пакета.

Имея это в виду, мы можем создать наше первое потрясающее приложение, даже не написав ни строчки кода! Взгляните:

root@kitploit:~
#!/bin/zsh

# Create Bundle structure
mkdir -p ./MyApp.app/Contents/MacOS

# Create main executable file - a shell script in our case
cat <<EOF > ./MyApp.app/Contents/MacOS/MyApp
#!/bin/zsh
osascript -e 'tell app "Finder" to display dialog "Hello from MyApp!"'
EOF
chmod +x ./MyApp.app/Contents/MacOS/MyApp

# Create the Info.plist file
cat <<EOF > ./MyApp.app/Contents/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>MyApp</string>
	<key>CFBundleIdentifier</key>
	<string>com.myapp</string>
	<key>CFBundleName</key>
	<string>MyApp</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
</dict>
</plist>
EOF

Это создаст новое приложение с именем MyApp — при клике на него просто запустится zsh-скрипт (называемый MyApp). Обратите внимание, что в нём используется osascript — интерпретатор AppleScript, а это целая куча проблем, но здесь он просто покажет диалог с текстом Hello from MyApp!. Разумеется, в этот zsh-скрипт можно написать какой угодно код. В новых версиях macOS может появиться запрос на разрешение zsh вызывать osascript — мы обсудим, почему это происходит, в будущем посте, но учтите, что после первого подтверждения запрос появляться не будет.

Запуск приложения

Запуск приложения означает, что всё равно создаётся процесс — очевидно, тот, на который указывает CFBundleExecutable. Под каким процессом он запускается? Давайте посмотрим:

root@kitploit:~
jbo@McJbo ~ % open -a Calculator
jbo@McJbo ~ % ps -A -j | grep Calculator | grep -v grep
jbo              12067     1 12067      0    1 S      ??    0:00.41 /System/Applications/Calculator.app/Contents/MacOS/Calculator
jbo@McJbo ~ %

Команда open эквивалентна двойному клику по приложению Calculator — это довольно интересно, и мы скоро это обсудим. Теперь, когда Calculator запущен, мы используем ps, чтобы показать запущенные процессы. Как и ожидалось, /System/Applications/Calculator.app/Contents/MacOS/Calculator — это процесс, который запущен, и его PID равен 12067. Однако ID его родительского процесса равен 1!

Процесс с ID 1 в macOS — это /sbin/launchd. Это «менеджер демонов/агентов для всей системы и для каждого пользователя». Вы можете представить его как services.exe (если вы из мира Windows) или systemd (если вы знакомы с Linux). Помимо управления службами (которые в macOS называются Launch Agents и Launch Daemons), он также является родителем всех приложений, что является одной из причин, по которым получение осмысленного дерева процессов в macOS может быть затруднительным.

Интересно, что вы всё равно можете запустить приложение Calculator просто как процесс, вызвав /System/Applications/Calculator.app/Contents/MacOS/Calculator напрямую, но тогда оно не будет дочерним процессом launchd:

root@kitploit:~
jbo@McJbo ~ % /System/Applications/Calculator.app/Contents/MacOS/Calculator &
[1] 12502
jbo@McJbo ~ % 2023-04-04 15:54:22.987 Calculator[12502:1297087] XType: XTFontStaticRegistry is enabled by Info.plist.

jbo@McJbo ~ % ps -A -j | grep Calculator | grep -v grep
jbo              12502   951 12502      0    1 SN   s000    0:00.31 /System/Applications/Calculator.app/Contents/MacOS/Calculator
jbo@McJbo ~ % echo $$
951
jbo@McJbo ~ %

Действительно, Calculator работает нормально, но теперь он является дочерним процессом нашего терминала. Одна вещь, которую стоит отметить в том поведении, что мы наблюдали: атакующие могут использовать это в разных целях. Например, атакующие могут легко выйти за пределы дерева процессов, чтобы обойти средства безопасности, а также злоупотребить логическими уязвимостями (если у вас есть время, прочитайте мой разбор уязвимости обхода песочницы macOS).

У launchd есть и другие интересные обязанности (читайте о LaunchAgents и LaunchDaemons), но сейчас мы их обсуждать не будем.

Подробнее о пакетах

Здесь я показал вам один тип пакета, но их гораздо больше (неполный список):

  • .app — этот мы уже видели; это Application Bundles, которые являются контейнерами для приложений.
  • .framework — содержит Frameworks, которые являются загружаемыми пакетами. Да, в macOS вы можете вызвать dlopen для загружаемого файла (.dylib) или загрузить целый пакет framework (с ресурсами, кодом и т. д.).
  • .kext — содержит kernel extensions, которые являются загружаемыми пакетами, но для ядра macOS. В последних версиях ОС Apple действительно очень старается сократить количество расширений ядра.
  • .plugin — как следует из названия, контейнер для плагинов.

Итоги

Это первый пост из серии коротких публикаций, цель которых — помочь людям перейти к исследованиям macOS.
Первое, что я заметил с точки зрения наступательной безопасности, — это то, как легко упаковать полезные нагрузки в аккуратную структуру приложения.
Однако всё не так просто — в следующих нескольких публикациях мы узнаем, что добиться выполнения кода не так-то тривиально из-за множества функций безопасности macOS.

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

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

Скачать инструмент