
Образовательное глубокое погружение в пакеты приложений macOS, plist-файлы и поведение процессов launchd, с заметками по offensive security об упаковке полезных нагрузок в .app-файлы и обходе мониторинга дерева процессов.
Переход на macOS с Linux или Windows может ощущаться как прогулка по незнакомой новой земле. Поскольку Linux имеет открытый исходный код, а Windows хорошо документирована и очень популярна (а macOS — ни то, ни другое, если быть точным), macOS иногда может быть сложной. В этом посте я хочу обсудить некоторые из первых вещей, которые вы можете заметить в macOS, — приложения, приложения повсюду!
Если вы пришли из мира Windows или Linux, концепция приложений (Apps) может показаться странной. Мы все знаем, что потоки — это «единицы выполнения», а процессы — это контейнеры для потоков с собственным адресным пространством — что ещё тут может быть? Что ж, процессы редко ограничиваются одним файлом. И в Windows, и в Linux коду для работы может требоваться множество вещей, вот некоторые из них:
.dll, .so). Например, библиотека времени выполнения C (msvcr<version>.dll в Windows, libc-<version>.so), а также другие зависимости.PE, в котором есть каталоги — одним из них является каталог ресурсов (он даже частично задокументирован здесь), который может содержать ресурсы (изображения, строки и другое). Разумеется, ресурсы также могут загружаться с диска динамически.PE (читайте здесь) или в файлах каталогов (то есть внешне).xml, ini, json) и реестром Windows.Что ж, macOS делает большой упор на пакеты приложений. Идея состоит в том, чтобы упаковать (почти) всё необходимое для работы программы в структуру каталогов — включая ресурсы, информацию о локализации и т. д. Конечно, не всё можно аккуратно упаковать (например, библиотеку времени выполнения C), но это всё равно означает, что всё аккуратно упаковано вместе — нет необходимости ориентироваться в огромном реестре или читать man-страницы в поисках малопонятных расположений конфигурационных файлов. Пакеты приложений — это просто каталоги, заканчивающиеся на .app, хотя интерфейс скрывает расширение .app (и тот факт, что это каталог).
С точки зрения атакующего это интересно — поскольку Application Bundle может иметь произвольные значки и скрывает расширение .app, доставка вредоносного ПО может быть осуществлена путём обмана ничего не подозревающего пользователя, заставив его кликнуть на такое приложение. Например, представьте файл Resume.app со значком PDF.
Структуру каталога Application Bundle можно легко изучить — например, с помощью встроенного приложения Calculator:
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. Например:
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 — имя пакета.Имея это в виду, мы можем создать наше первое потрясающее приложение, даже не написав ни строчки кода! Взгляните:
#!/bin/zsh