macOS Security Audit — Проверка Mac на вирусы, слежку и вторжения
📌 Зачем это нужно
Твой Mac греется без причины, зависает, батарея садится за пару часов? Это может быть банальный Chrome с 50 вкладками, а может — майнер, spyware или MDM-профиль, оставленный предыдущим владельцем.
Аналогия: представь, что твой компьютер — квартира. Ты не ставишь сигнализацию и камеры, пока не проверишь — а может, кто-то уже внутри? Этот читшит — обход квартиры с фонариком перед тем, как ставить замки.
Антивирусы по сути делают то же самое, но через посредника. Здесь ты проверяешь всё сам, через терминал — быстрее, точнее, без лишнего софта.
Что проверяем:
- Кто жрёт ресурсы (CPU/RAM/диск)
- Что запускается автоматически (persistence)
- Куда Mac стучится по сети
- Не отключена ли встроенная защита
- Нет ли чужих профилей управления (MDM)
- Подозрительные файлы и расширения ядра
⚡ Быстрый скрипт — полная проверка за 2 минуты
Скрипт ниже прогоняет все проверки разом. Сохрани его, дай права на выполнение и запусти. Он ничего не меняет в системе — только читает и выводит отчёт.
#!/bin/bash
# macos-audit.sh — PenteStudy Cheatsheet #34
# Быстрый аудит безопасности macOS
# Ничего не устанавливает, не меняет, не отправляет
# Запуск: chmod +x macos-audit.sh && sudo ./macos-audit.sh
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
divider() { echo -e "\n${BLUE}════════════════════════════════════════════════════════${NC}"; }
header() { echo -e "${BLUE}[$1]${NC} $2"; }
ok() { echo -e " ${GREEN}[OK]${NC} $1"; }
warn() { echo -e " ${YELLOW}[!]${NC} $1"; }
alert() { echo -e " ${RED}[ALERT]${NC} $1"; }
echo -e "${BLUE}"
echo "╔══════════════════════════════════════════════════════╗"
echo "║ 🍎 macOS Security Audit — PenteStudy #34 ║"
echo "║ $(date '+%Y-%m-%d %H:%M:%S') ║"
echo "╚══════════════════════════════════════════════════════╝"
echo -e "${NC}"
# ═══════════════════════════════════════════════════
# 1. СИСТЕМНАЯ ЗАЩИТА
# ═══════════════════════════════════════════════════
divider
header "1" "СИСТЕМНАЯ ЗАЩИТА (SIP, Gatekeeper, FileVault)"
# SIP
sip_status=$(csrutil status 2>&1)
if echo "$sip_status" | grep -q "enabled"; then
ok "SIP (System Integrity Protection): включён"
else
alert "SIP ОТКЛЮЧЁН — это серьёзная уязвимость!"
fi
# Gatekeeper
gk_status=$(spctl --status 2>&1)
if echo "$gk_status" | grep -q "assessments enabled"; then
ok "Gatekeeper: включён"
else
alert "Gatekeeper ОТКЛЮЧЁН — любой софт может запуститься!"
fi
# FileVault
fv_status=$(fdesetup status 2>&1)
if echo "$fv_status" | grep -q "On"; then
ok "FileVault: включён (диск зашифрован)"
else
warn "FileVault выключен — диск НЕ зашифрован"
fi
# Firewall
fw_status=$(/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate 2>&1)
if echo "$fw_status" | grep -q "enabled"; then
ok "Firewall: включён"
else
warn "Встроенный файрвол выключен"
fi
# ═══════════════════════════════════════════════════
# 2. ПРОФИЛИ КОНФИГУРАЦИИ (MDM)
# ═══════════════════════════════════════════════════
divider
header "2" "ПРОФИЛИ КОНФИГУРАЦИИ (MDM, удалённое управление)"
profiles_output=$(profiles list 2>&1)
if echo "$profiles_output" | grep -qi "no configuration profiles\|no profiles\|empty"; then
ok "Конфигурационные профили не установлены"
else
alert "Найдены конфигурационные профили:"
echo "$profiles_output" | head -20
fi
# Remote Desktop / Screen Sharing
if pgrep -x "ARDAgent" > /dev/null 2>&1; then
alert "Apple Remote Desktop АКТИВЕН — кто-то может управлять Mac удалённо"
else
ok "Remote Desktop не запущен"
fi
sharing_status=$(sudo systemsetup -getremotelogin 2>&1)
if echo "$sharing_status" | grep -qi "on"; then
warn "Remote Login (SSH) включён"
else
ok "Remote Login (SSH) выключен"
fi
# ═══════════════════════════════════════════════════
# 3. CPU — КТО ЖРЁТ РЕСУРСЫ
# ═══════════════════════════════════════════════════
divider
header "3" "ТОП ПРОЦЕССОВ ПО CPU (причина перегрева/зависаний)"
echo ""
ps -Arco user,pid,%cpu,%mem,comm | head -11 | awk 'NR==1{printf " %-12s %6s %6s %6s %s\n","USER","PID","%CPU","%MEM","COMMAND"} NR>1{printf " %-12s %6s %5s%% %5s%% %s\n",$1,$2,$3,$4,$5}'
echo ""
echo -e " ${YELLOW}Подозрительно:${NC} неизвестные процессы с >30% CPU"
echo -e " ${YELLOW}Особенно:${NC} имена типа .hidden, xmrig, kworker, randomname"
# ═══════════════════════════════════════════════════
# 4. PERSISTENCE — АВТОЗАГРУЗКА
# ═══════════════════════════════════════════════════
divider
header "4" "PERSISTENCE — что запускается автоматически"
# Whitelist известных вендоров
KNOWN_VENDORS="com.apple\.\|com.google\.\|com.microsoft\.\|com.parallels\.\|com.docker\.\|org.mozilla\.\|com.valvesoftware\.\|homebrew\.\|com.openai\.\|us.zoom\.\|com.surfshark\.\|io.tailscale\.\|com.obsproject\.\|com.spotify\.\|com.adobe\.\|com.jetbrains\.\|org.videolan\.\|com.discord\.\|com.1password\.\|com.dropbox\.\|com.nordvpn\."
check_agents() {
local dir="$1"
local label="$2"
echo -e "\n ${BLUE}--- $label ---${NC}"
local files=$(ls "$dir" 2>/dev/null | grep -v "^$")
if [ -z "$files" ]; then
ok "Пусто"
else
echo "$files" | while read filename; do
if [ "$filename" = ".DS_Store" ]; then
continue
elif echo "$filename" | grep -q "$KNOWN_VENDORS"; then
ok "$filename"
else
warn "$filename — ПРОВЕРЬ что это"
fi
done
fi
}
check_agents "$HOME/Library/LaunchAgents" "~/Library/LaunchAgents/ (пользовательские)"
check_agents "/Library/LaunchAgents" "/Library/LaunchAgents/ (системные для пользователей)"
check_agents "/Library/LaunchDaemons" "/Library/LaunchDaemons/ (системные демоны)"
# ═══════════════════════════════════════════════════
# 5. CRON И ПЕРИОДИЧЕСКИЕ ЗАДАЧИ
# ═══════════════════════════════════════════════════
divider
header "5" "CRON И ПЕРИОДИЧЕСКИЕ ЗАДАЧИ"
user_cron=$(crontab -l 2>&1)
if echo "$user_cron" | grep -qi "no crontab"; then
ok "Пользовательский crontab пуст"
else
warn "Найдены задачи в crontab пользователя:"
echo "$user_cron"
fi
root_cron=$(sudo crontab -l 2>&1)
if echo "$root_cron" | grep -qi "no crontab"; then
ok "Root crontab пуст"
else
warn "Найдены задачи в root crontab:"
echo "$root_cron"
fi
# ═══════════════════════════════════════════════════
# 6. СЕТЕВЫЕ СОЕДИНЕНИЯ
# ═══════════════════════════════════════════════════
divider
header "6" "АКТИВНЫЕ СЕТЕВЫЕ СОЕДИНЕНИЯ"
echo ""
established=$(lsof -i -P 2>/dev/null | grep ESTABLISHED)
if [ -z "$established" ]; then
ok "Нет активных исходящих соединений"
else
echo "$established" | awk '{printf " %-18s %-8s %s\n", $1, $2, $9}' | sort -u
echo ""
echo -e " ${YELLOW}Совет:${NC} проверь незнакомые процессы и IP через whois/VirusTotal"
fi
# Listening ports
echo -e "\n ${BLUE}--- Слушающие порты ---${NC}"
listening=$(lsof -i -P 2>/dev/null | grep LISTEN)
if [ -z "$listening" ]; then
ok "Нет открытых портов"
else
echo "$listening" | awk '{printf " %-18s %-8s %s\n", $1, $2, $9}' | sort -u
fi
# ═══════════════════════════════════════════════════
# 7. РАСШИРЕНИЯ ЯДРА И СИСТЕМНЫЕ РАСШИРЕНИЯ
# ═══════════════════════════════════════════════════
divider
header "7" "РАСШИРЕНИЯ ЯДРА И СИСТЕМНЫЕ РАСШИРЕНИЯ"
n 2>/dev/null | grep -v "com.apple\|Executing\|Index")
if [ -z "$non_apple_kext" ]; then
ok "Только Apple kexts загружены"
else
warn "Найдены сторонние kexts:"
echo "$non_apple_kext"
fi
echo -e "\n ${BLUE}--- Системные расширения ---${NC}"
sysext=$(systemextensionsctl list 2>&1)
echo "$sysext" | grep -v "^---\|^$" | head -15
# ═══════════════════════════════════════════════════
# 8. ПОДОЗРИТЕЛЬНЫЕ ФАЙЛЫ
# ═══════════════════════════════════════════════════
divider
header "8" "НЕДАВНО ИЗМЕНЁННЫЕ ФАЙЛЫ В ПОДОЗРИТЕЛЬНЫХ МЕСТАХ"
echo -e "\n ${BLUE}--- /tmp и /var/tmp (последние 7 дней) ---${NC}"
tmp_files=$(find /tmp /var/tmp -mtime -7 -type f 2>/dev/null | grep -v ".sock\|.lock\|.log" | head -15)
if [ -z "$tmp_files" ]; then
ok "Ничего подозрительного"
else
echo "$tmp_files" | while read f; do
echo -e " ${YELLOW}→${NC} $f"
done
fi
echo -e "\n ${BLUE}--- Скрытые файлы в домашней директории ---${NC}"
hidden_exec=$(find ~ -maxdepth 2 -name ".*" -perm +111 -type f 2>/dev/null | grep -v ".Trash\|.zsh\|.bash\|.CFUser\|.DS_Store")
if [ -z "$hidden_exec" ]; then
ok "Нет скрытых исполняемых файлов"
else
alert "Найдены скрытые исполняемые файлы:"
echo "$hidden_exec"
fi
# ═══════════════════════════════════════════════════
# 9. XProtect И ОБНОВЛЕНИЯ БЕЗОПАСНОСТИ
# ═══════════════════════════════════════════════════
divider
header "9" "XProtect И ОБНОВЛЕНИЯ БЕЗОПАСНОСТИ"
xprotect_info=$(system_profiler SPInstallHistoryDataType 2>/dev/null | grep -A 3 "XProtect" | tail -4)
if [ -n "$xprotect_info" ]; then
echo "$xprotect_info" | while read line; do
echo " $line"
done
else
warn "Не удалось получить информацию о XProtect"
fi
# macOS version
echo ""
sw_vers | while read line; do
echo " $line"
done
# ═══════════════════════════════════════════════════
# 10. ПОЛЬЗОВАТЕЛИ И SUDO
# ═══════════════════════════════════════════════════
divider
header "10" "ПОЛЬЗОВАТЕЛИ И ПРИВИЛЕГИИ"
echo -e "\n ${BLUE}--- Пользователи с UID >= 500 (реальные) ---${NC}"
dscl . list /Users UniqueID 2>/dev/null | awk '$2 >= 500 {printf " → %s (UID: %s)\n", $1, $2}'
echo -e "\n ${BLUE}--- Группа admin ---${NC}"
dscl . -read /Groups/admin GroupMembership 2>/dev/null | sed 's/GroupMembership: / → /'
echo -e "\n ${BLUE}--- sudoers NOPASSWD ---${NC}"
nopasswd=$(sudo grep -r "NOPASSWD" /etc/sudoers /etc/sudoers.d/ 2>/dev/null | grep -v "^#")
if [ -z "$nopasswd" ]; then
ok "NOPASSWD не настроен"
else
warn "Найдены NOPASSWD записи:"
echo "$nopasswd"
fi
# ═══════════════════════════════════════════════════
# 11. ИТОГОВАЯ СВОДКА
# ═══════════════════════════════════════════════════
divider
echo -e "\n${BLUE}╔══════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ 📋 ИТОГОВЫЕ РЕКОМЕНДАЦИИ ║${NC}"
echo -e "${BLUE}╚══════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e " 1. Все ${RED}[ALERT]${NC} — требуют немедленного внимания"
echo -e " 2. Все ${YELLOW}[!]${NC} — проверь вручную, может быть ок"
echo -e " 3. Незнакомые процессы → ищи название в Google + 'malware'"
echo -e " 4. Подозрительные IP → проверь через whois или VirusTotal"
echo -e " 5. Незнакомые LaunchAgents → cat файл.plist и смотри ProgramArguments"
echo ""
echo -e " ${BLUE}Дополнительные инструменты (objective-see.org):${NC}"
echo -e " → KnockKnock — глубокий скан persistence"
echo -e " → LuLu — файрвол с UI"
echo -e " → OverSight — мониторинг камеры/микрофона"
echo ""
echo -e "${BLUE}════════════════════════════════════════════════════════${NC}"
echo -e " Аудит завершён: $(date '+%Y-%m-%d %H:%M:%S')"
echo -e "${BLUE}════════════════════════════════════════════════════════${NC}"
🔍 Разбор каждой проверки
Почему SIP — это главное
SIP (System Integrity Protection) — это как бронежилет macOS. Он запрещает изменение системных файлов даже с root-правами. Если SIP отключён — кто-то специально лазил в Recovery Mode и выполнил csrutil disable. Легитимная причина: установка хакинтоша или специфичных kextов. Нелегитимная: подготовка к установке руткита.
Аналогия: SIP — это пломба на счётчике. Если она сорвана, не факт что воруют электричество, но проверить стоит.
# Проверка вручную
csrutil status
# Ожидаемый ответ:
# System Integrity Protection status: enabled.
Профили конфигурации — тихий контроль
MDM-профили позволяют удалённо управлять Mac: устанавливать/удалять софт, читать данные, отслеживать геолокацию. Корпоративные Mac — норма. Личный Mac с профилем — красный флаг.
Аналогия: профиль MDM — это как доверенность на твою квартиру, выданную кому-то без твоего ведома.
# Проверка
sudo profiles list -all
# Если видишь профили — читай что в них:
sudo profiles show -all
Также проверь визуально: System Settings → General → Device Management. Если этого пункта нет — профилей нет.
LaunchAgents и LaunchDaemons — автозагрузка
Это основной механизм persistence в macOS. Любой вредонос, который хочет пережить перезагрузку, создаёт .plist файл в одной из этих папок:
~/Library/LaunchAgents/— запускается при логине пользователя/Library/LaunchAgents/— для всех пользователей при логине/Library/LaunchDaemons/— запускается при загрузке системы (до логина)
Аналогия: LaunchAgent — это как автозапуск в Windows. Если кто-то подсунул туда свой .plist — его софт стартует каждый раз.
# Посмотреть все
ls -la ~/Library/LaunchAgents/
ls -la /Library/LaunchAgents/
ls -la /Library/LaunchDaemons/
# Если нашёл подозрительный — читай что запускает:
cat ~/Library/LaunchAgents/suspicious.plist
# Ищи ключ ProgramArguments — там путь к исполняемому файлу
Что нормально: com.apple.*, com.google.*, com.docker.*, org.mozilla.*
Что подозрительно: случайные имена, .hidden.*, неизвестные bundle ID
Сетевые соединения — куда стучится Mac
Вредонос должен передавать данные наружу. lsof -i покажет все активные соединения с именами процессов.
Аналогия: это как проверка детализации звонков — ты видишь кто, куда и когда звонил.
# Все установленные соединения
lsof -i -P | grep ESTABLISHED
# Конкретный подозрительный процесс (замени PID)
lsof -i -P | grep 12345
# Проверить IP
# Скопируй подозрительный IP и проверь на:
# https://www.virustotal.com/gui/home/search
# или через whois:
whois 185.123.45.67
🛡 Дополнительные проверки вручную
Проверка браузерных расширений
Расширения браузера — один из главных векторов. Они могут читать все посещаемые страницы, пароли, куки.
# Chrome расширения
ls ~/Library/Application\ Support/Google/Chrome/Default/Extensions/
# Safari расширения — проверяй через Safari → Settings → Extensions
# Firefox
ls ~/Library/Application\ Support/Firefox/Profiles/*/extensions/
Каждое расширение — папка с ID. Если ID незнакомый — загугли его.
Проверка DNS (перенаправление трафика)
Если кто-то подменил DNS — весь трафик может идти через злоумышленника.
# Текущие DNS
scutil --dns | grep "nameserver\[" | head -10
# Проверь /etc/hosts на подозрительные записи
cat /etc/hosts
# Должны быть только localhost записи
Подозрительно: неизвестные DNS-серверы, записи в /etc/hosts, перенаправляющие известные домены на другие IP.
Проверка SSH-ключей
Если в ~/.ssh/authorized_keys есть чужие ключи — кто-то может подключаться к твоему Mac.
# Есть ли authorized_keys
cat ~/.ssh/authorized_keys 2>/dev/null
# Если файл существует — проверь каждый ключ, твой ли он
# Все SSH ключи на машине
ls -la ~/.ssh/
🔧 Что скрипт НЕ ловит и чем добить
Скрипт покрывает ~80% базовой диагностики. Остальные 20% требуют дополнительных инструментов.
Файловые сигнатуры — известные вирусы
Скрипт не сканирует файлы по антивирусным базам. Он проверяет поведение (кто запускается, кто жрёт CPU, кто лезет в сеть), но не знает, что конкретный файл — это троян.
Аналогия: скрипт — это охранник, который видит подозрительное поведение. Антивирус — это база ориентировок с фотороботами. Лучше иметь оба.
Решение: KnockKnock (objective-see.org) — сканирует все persistence-точки и проверяет каждый файл через VirusTotal. Или ClamAV для полного сканирования:
# Установка ClamAV
brew install clamav
# Обновление баз
sudo freshclam
# Полный скан домашней папки (долго!)
clamscan -r --bell -i ~/
# Быстрый скан только опасных мест
clamscan -r -i ~/Downloads ~/Applications /tmp
Руткиты уровня ядра
Если атакующий установил руткит, который прячет свои процессы — ps, lsof, top его не покажут, потому что руткит подменяет их вывод. Ты смотришь через «заражённые очки».
Аналогия: это как если бы вор перекрасил камеры наблюдения — ты смотришь запись и видишь пустую комнату, а он стоит рядом.
Реальность: на M1/M2/M3 с включённым SIP руткиты уровня ядра практически невозможны. Apple Silicon + Secure Boot + SIP = тройная защита. Если SIP включён — эту угрозу можно считать теоретической.
Если паранойя обоснована: загрузка с внешнего USB (macOS Recovery или Linux) и проверка диска оттуда — единственный способ обойти потенциальный руткит.
Шпионское ПО уровня Pegasus
Zero-click эксплойты стоимостью миллионы долларов. Используются против журналистов, активистов, политиков. Обычному пользователю это не грозит — но если ты в зоне риска:
# Mobile Verification Toolkit от Amnesty International
pip3 install mvt
# Сделай бэкап iPhone через Finder/iTunes, затем:
mvt-ios check-backup --output /tmp/mvt-results ~/Library/Application\ Support/MobileSync/Backup/*
MVT анализирует бэкап на известные индикаторы Pegasus и других государственных шпионских инструментов.
Мониторинг трафика в реальном времени
Скрипт показывает соединения в один момент — как фотография. Для постоянного наблюдения нужно «видео».
Решение 1 — LuLu (рекомендую): файрвол с UI от Objective-See. При каждом новом исходящем соединении показывает алерт: «Процесс X хочет подключиться к IP Y. Разрешить?» Скачивай с objective-see.org.
Решение 2 — tcpdump для разового анализа:
# Записать весь трафик на 60 секунд
sudo tcpdump -i en0 -w ~/Desktop/capture.pcap -G 60 -W 1
# Потом открой capture.pcap в Wireshark для анализа
Минимальный план после скрипта
Если скрипт не нашёл ничего критичного, но хочется убедиться:
- KnockKnock — одноразовый глубокий скан persistence + VirusTotal (5 минут)
- LuLu — поставь и забудь, будет мониторить сеть постоянно (2 минуты на установку)
- OverSight — мониторит доступ к камере и микрофону (1 минута на установку)
Все три — бесплатные, open-source, с objective-see.org. Написаны Patrick Wardle, бывшим сотрудником NSA и известным исследователем macOS-безопасности.
Если после всего этого Mac всё равно тормозит — проблема не в безопасности, а в софте, диске или RAM.
🧠 Готовые комбо
Комбо 1: Быстрая проверка за 30 секунд (без скрипта)
csrutil status && spctl --status && fdesetup status
Три команды — три столпа защиты. Все должны быть enabled/On.
Комбо 2: Кто жрёт CPU прямо сейчас
ps aux --sort=-%cpu | head -6
Если наверху не Chrome/Safari/Xcode, а что-то неизвестное — гугли имя процесса.
Комбо 3: Полная карта сетевой активности
lsof -i -P | grep -E "ESTABLISHED|LISTEN" | awk '{print $1, $9}' | sort -u
Комбо 4: Все точки persistence разом
ls ~/Library/LaunchAgents/ /Library/LaunchAgents/ /Library/LaunchDaemons/ 2>/dev/null | grep -v "^$\|^/"
Комбо 5: Проверка после подозрительного инцидента
# Свежие файлы в опасных местах
find /tmp /var/tmp ~/Downloads -mtime -1 -type f 2>/dev/null
# Последние логины
last | head -10
# Кто сейчас залогинен
w
⚠️ Важные моменты
- Скрипт не заменяет антивирус полностью — он проверяет системные индикаторы компрометации (IoC). Для сканирования файлов по сигнатурам используй KnockKnock или ClamAV
- Запускай с sudo — без root-прав часть проверок не сработает (профили, системные демоны, sudoers)
- Не удаляй LaunchAgents вслепую — сначала загугли имя.
com.docker.helper— это Docker, не вирус - Сохраняй отчёт — если найдёшь что-то подозрительное, перенаправь вывод в файл:
sudo ./macos-audit.sh > ~/Desktop/audit-$(date +%F).txt 2>&1 - macOS сама по себе хорошо защищена — M1/M2/M3 с актуальной ОС, включённым SIP и FileVault — одна из самых безопасных потребительских платформ. Большинство проблем с перегревом — это runaway-процессы, а не малварь
- Objective-See утилиты (objective-see.org) — бесплатные, open-source инструменты от бывшего сотрудника NSA. KnockKnock, LuLu, BlockBlock, OverSight — must have для параноиков
- После аудита — если всё чисто, а Mac всё равно тормозит: проверь свободное место на диске (
df -h), перезагрузись, сбрось SMC/NVRAM