Операционная система macOS от Apple, как и любая другая ОС, генерирует множество событий в процессе работы. Мониторинг событий необходим для аудита безопасности и другое. В статье рассмотрим встроенное в macOS средство отслеживания системных событий, которое называется eslogger (ESF).
Еще по теме: Механизмы защиты macOS
Отслеживание системных событий в macOS
В ОС Windows хорошо изучены инструменты для мониторинга и журналирования событий. Множество руководств предлагают пошаговые инструкции по настройке централизованного сбора событий с помощью Windows Event Forwarding.
Однако гораздо меньше внимания уделяется отслеживанию событий в компьютерах на базе macOS. Причины понятны: немногие организации готовы тратиться на покупку Mac для сотрудников. Кроме того, на рынке мало специалистов по администрированию и обеспечению безопасности macOS, хотя угрозы существуют и для этой ОС.
Есть 3 способа мониторинга событий в macOS:
- Osquery.
- Коммерческий EDR.
- Eslogger (ESF).
Утилиты вроде Red Canary Mac Monitor используют Endpoint Security API и делают упор на визуализацию и красоту.
Мониторинг событий в macOS с eslogger (ESF)
Решение, которое мы запряжем в наш SOC, ориентируется на нативность, полноту и безопасность. Это eslogger, утилита командной строки, она предоставляет прямой доступ непосредственно к генерируемым ядром событиям и поставляется со всеми версиями macOS выше Ventura. Этакий поисковик среди событий.
Достоинства eslogger:
- уже есть на каждой macOS Ventura;
- не грузит систему при использовании;
- выдает лог в текстовом формате, а не бинарном;
- дает отличную видимость активности.
Сначала мы посмотрим список событий, на которые можно подписаться:
1 |
sudo eslogger --list-events |
Эта команда выведет нам внушительный список. Приведу примеры:
Название | Полное название | Функции |
---|---|---|
create | es_event_create_t | Создание файла |
open | es_event_open_t | Открытие файла |
write | es_event_write_t | Запись в файл |
unlink | es_event_unlink_t | Удаление файла |
utimes | es_event_utimes_t | Изменение параметров access time и modification time файла |
exec | es_event_exec_t | Запуск процесса |
uipc_connect | es_event_uipc_connect_t | Подключение через сокет |
kextload | es_event_kextload_t | Загрузка Kernel Extension |
btm_launch_item_add | btm_launch_item_add | Создание нового объекта входа (Launch Item) |
Eslogger на практике
Переведем наши упражнения в практическую плоскость и применим их для решения конкретной задачи. В директории Logs лежит файл 2023.log. Туда записываются чрезвычайно важные данные.
На компьютер Mac попал надоедливый вредоносный скрипт, который прописался как задача в /Library/LaunchAgents/ и постоянно, каждые пять минут, удаляет лог, который лежит в директории Logs.
Файл задачи с расширением .plist выглядит так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?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>Label</key> <string>com.hacker.annoying.task</string> <key>ProgramArguments</key> <array> <string>/bin/sh</string> <string>/Users/tofolt/Downloads/DeleteLogFile.sh</string> </array> <key>StartInterval</key> <integer>300</integer> </dict> </plist> |
А сам скрипт так:
1 |
rm -f "/Users/tofolt/Logs/2023.log" |
Чтобы отловить этот скрипт, нам понадобится следующая команда eslogger:
1 |
sudo eslogger exec open unlink btm_launch_item_add >> result.json |
Предположим, что у нас уже писались логи в момент заражения. Нам не составит труда найти событие добавления скрипта в автозапуск. Большая часть события была отброшена, оставлены только главные строки. В оригинальных событиях много информативных полей, в том числе и очень полезных для связывания событий друг с другом ( btm_launch_item_add):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "event": { "btm_launch_item_add": { "executable_path": "/bin/sh", "instigator": { "signing_id": "com.apple.xpc.smd", "ppid": 1, "tty": null, "start_time": "2023-07-09T10:17:55.546995Z", }, "item": { "item_url": "file:///Library/LaunchAgents/com.hacker.annoying.task.plist", } } }, "time": "2023-07-09T14:08:03.326637707Z", } |
Далее мы найдем момент запуска скрипта ( exec):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
{ "event": { "exec": { "script": { "path": "/Users/tofolt/Downloads/DeleteLogFile.sh", }, "executable": { "path": "/bin/sh", }, "start_time": "2023-07-09T14:33:56.804354Z", "is_platform_binary": true, "group_id": 22017, "audit_token": { "asid": 100005, "pidversion": 49567, "ruid": 503, "euid": 503, "rgid": 20, "auid": 503, "egid": 20, "pid": 22017 }, }, "args": [ "/bin/sh", "/Users/tofolt/Downloads/DeleteLogFile.sh" ], }, "time": "2023-07-09T14:33:56.814464013Z", "action": { "result": { "result": { "auth": 0 }, "result_type": 0 } } |
Финальный аккорд. Событие удаления файла 2023.log ( unlink).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
{ "event": { "unlink": { "target": { "path": "/Users/tofolt/Logs/2023.log", }, "parent_dir": { "path": "/Users/tofolt/Logs", } } }, "time": "2023-07-09T14:34:57.713064962Z", "executable": { "path": "/bin/rm", }, "ppid": 22069, }, "start_time": "2023-07-09T14:34:57.704093Z", } |
В общем, при наличии логов отыскать требуемое событие и получить сведения о нем довольно просто.
Команда kill и eslogger
Как обезопаситься от того, что злоумышленник просто прибьет процесс eslogger командой kill?
Например, можно создать новую учетку на компьютере и назвать ее с нижним подчеркиванием _brew, добавить привилегии, чтобы обычный пользователь не мог прибить процессы, запущенные от ее имени.
Ожидается, что злоумышленик, когда захочет узнать всех пользователей в системе, отфильтрует вывод, убирая записи с нижними подчеркиваниями, потому что так называются системные учетки для внутреннего функционирования системы. А даже если он выведет все учетные записи, _brew замаскируется под пакетный менеджер, который стоит почти на каждом «маке» программиста. Таким образом мы и защитимся от команды kill.
Ну или второй вариант — назвать _ftp_server. Это объяснит столь высокие системные полномочия у учетки.
Использование eslogger в инфраструктуре
Как все это разворачивать?
Конкретную пошаговую инструкцию выдать не получится просто потому, что у всех разные инфраструктуры и очень по‑разному администрируются «маки», но подкинуть пару идей я могу.
- У вас наверняка есть ПО для управления Mac по типу Jamf Pro. Вы можете создать запланированную задачу, запускающую скрипт пересылки данных из файла собранных логов.
- Если у вас есть какой‑то агент на компьютерах, то проверьте, не может ли он собирать дополнительно и файл логов.
- Обязательно нужно настроить ротацию файла с логом, чтобы после пересылки, например, в SIEM, он чистился, иначе он может довольно быстро вырасти до существенных размеров.
В eslogger может возникнуть проблема бутылочного горлышка, если подписать инструмент на слишком большое количество событий. Все они просто не будут успевать сохраняться в журнал. В интернете описывают эту проблему и рассказывают, как ее лечить.
Какова нагрузка на систему? Незначительная. Однако EPS может быть большим, если должным образом не настроить фильтрацию событий.
Напоминаю, что решение бесплатное и всех удобств «из коробки» не гарантирует. Фильтрация тут обязательна.
Нормализация и фильтрация
Сразу уточню, что предложенный ниже вариант лишь вариация на тему «как это можно делать». Итак, для нормализации будем использовать инструмент под названием fx.
Для фильтрации возьмем другой инструмент — jq.
Приведем JSON в нормальный вид с помощью скрипта на Python 3:
1 2 3 4 5 6 7 8 9 10 |
import sys out: str = "[" lines = sys.stdin.readlines() for index, line in enumerate(lines): if index == len(lines)-1: out += "{}".format(line) else: out += "{}{}".format(line, ",") out += "]" print(out) |
Наполненный логами файл мы прогоним через наш нормализатор:
1 |
cat eslogger_output.json | ./normalizer.py | fx . > better_eslogger_output.json |
Нормализованный файл теперь необходимо отфильтровать. Я, например, исключу все события, связанные с процессом Finder:
1 |
cat better_eslogger_output.json | jq '[.[] | select(.process.signing_id == "com.apple.finder" )]' > eslogger_final.json |
Подскажу пути, которые можно (точно так же, как и Finder) исключить из захвата через eslogger, чтобы не создавать мусор. Многие из путей могут показаться важными для мониторинга. Однако в 2015 году Apple добавила механизм System Integrity Protection (SIP), а позже, в 2019-м, разделила диск на защищенный и незащищенный разделы.
SIP предохраняет системные критически важные директории от вмешательства, и поэтому хакер не сможет ничего изменить в них, если только вы не отключили SIP вручную. Поэтому и мониторить их не нужно. Найти список путей для исключения можно в этом репозитории (репозиторий удален автором).
Заключение
Мы рассмотрели работу ESF, узнали о решениях, которые дают доступ к низкоуровневым событиям в системе, а также об особенностях работы с ними.
Хоть утилита eslogger и классная, но она не лишена недостатков. Приходится применять заплатки, чтобы это заработало в масштабах SOC, но зато eslogger не требует денег и не уступает в 90% случаев коммерческим EDR-решениям (видимость сетевых подключений там, конечно, гораздо лучше).
ПОЛЕЗНЫЕ ССЫЛКИ:
- Как убить процесс системы обнаружения атак (EDR)
- Проксирование и перехват трафика приложений macOS
- Защита macOS с помощью файрвола LuLu и Do Not Disturb