macOS Apps - Inspecting, debugging and Fuzzing
Статичний аналіз
otool & objdump & nm
jtool2 & Disarm
Ви можете завантажити disarm звідси.
Ви можете завантажити jtool2 тут або встановити його за допомогою brew
.
jtool застарілий на користь disarm
Codesign / ldid
Codesign
можна знайти в macOS, а ldid
можна знайти в iOS
SuspiciousPackage
SuspiciousPackage - це інструмент, корисний для перевірки .pkg файлів (інсталяторів) та перегляду їх вмісту перед установкою.
Ці інсталятори мають preinstall
та postinstall
bash скрипти, які автори шкідливого ПЗ зазвичай зловживають для постійності шкідливого ПЗ.
hdiutil
Цей інструмент дозволяє монтувати образи дисків Apple (.dmg) для їх перевірки перед запуском чого-небудь:
It will be mounted in /Volumes
Packed binaries
Перевірте на високу ентропію
Перевірте рядки (якщо майже немає зрозумілого рядка, упаковано)
Упаковщик UPX для MacOS генерує секцію під назвою "__XHDR"
Static Objective-C analysis
Metadata
Зверніть увагу, що програми, написані на Objective-C, зберігають свої оголошення класів під час компіляції в Mach-O binaries. Такі оголошення класів включають ім'я та тип:
Визначені інтерфейси
Методи інтерфейсу
Змінні екземпляра інтерфейсу
Визначені протоколи
Зверніть увагу, що ці імена можуть бути обфусцировані, щоб ускладнити реверсування бінарного файлу.
Function calling
Коли функція викликається в бінарному файлі, що використовує Objective-C, скомпільований код замість виклику цієї функції викликає objc_msgSend
. Це викликатиме фінальну функцію:
Параметри, які очікує ця функція:
Перший параметр (self) - "вказівник, що вказує на екземпляр класу, який має отримати повідомлення". Іншими словами, це об'єкт, на якому викликається метод. Якщо метод є класовим, це буде екземпляр об'єкта класу (в цілому), тоді як для методів екземпляра self вказуватиме на створений екземпляр класу як об'єкт.
Другий параметр (op) - "селектор методу, який обробляє повідомлення". Знову ж таки, простіше кажучи, це просто ім'я методу.
Решта параметрів - це будь-які значення, які потрібні методу (op).
Дивіться, як легко отримати цю інформацію за допомогою lldb
в ARM64 на цій сторінці:
x64:
Dump ObjectiveC metadata
Dynadump
Dynadump - це інструмент для класового дампу Objective-C бінарних файлів. GitHub вказує на dylibs, але це також працює з виконуваними файлами.
На момент написання, це в даний час найкраще працює.
Звичайні інструменти
class-dump
class-dump - це оригінальний інструмент для генерації декларацій для класів, категорій та протоколів у форматованому коді ObjectiveC.
Він старий і не підтримується, тому, ймовірно, не буде працювати належним чином.
ICDump
iCDump - це сучасний крос-платформений дамп класів Objective-C. У порівнянні з існуючими інструментами, iCDump може працювати незалежно від екосистеми Apple і надає прив'язки до Python.
Статичний аналіз Swift
З бінарними файлами Swift, оскільки є сумісність з Objective-C, іноді ви можете витягти декларації за допомогою class-dump, але не завжди.
За допомогою команд jtool -l
або otool -l
можна знайти кілька секцій, які починаються з префікса __swift5
:
Ви можете знайти додаткову інформацію про інформацію, що зберігається в цих розділах, у цьому блозі.
Крім того, Swift бінарники можуть мати символи (наприклад, бібліотеки повинні зберігати символи, щоб їх функції можна було викликати). Символи зазвичай містять інформацію про назву функції та атрибути в неохайному вигляді, тому вони дуже корисні, і існують "деманглери", які можуть отримати оригінальну назву:
Динамічний аналіз
Зверніть увагу, що для налагодження бінарних файлів SIP потрібно вимкнути (csrutil disable
або csrutil enable --without debug
) або скопіювати бінарні файли в тимчасову папку та видалити підпис за допомогою codesign --remove-signature <binary-path>
або дозволити налагодження бінарного файлу (ви можете використовувати цей скрипт)
Зверніть увагу, що для інструментування системних бінарних файлів, (таких як cloudconfigurationd
) на macOS, SIP повинен бути вимкнений (просто видалення підпису не спрацює).
API
macOS надає деякі цікаві API, які надають інформацію про процеси:
proc_info
: Це основний API, який надає багато інформації про кожен процес. Вам потрібно бути root, щоб отримати інформацію про інші процеси, але спеціальні права або порти mach не потрібні.libsysmon.dylib
: Дозволяє отримувати інформацію про процеси через функції, які надаються XPC, однак потрібно мати правоcom.apple.sysmond.client
.
Stackshot та мікростекшоти
Stackshotting - це техніка, що використовується для захоплення стану процесів, включаючи стек викликів усіх запущених потоків. Це особливо корисно для налагодження, аналізу продуктивності та розуміння поведінки системи в конкретний момент часу. На iOS та macOS stackshotting можна виконувати за допомогою кількох інструментів і методів, таких як інструменти sample
та spindump
.
Sysdiagnose
Цей інструмент (/usr/bini/ysdiagnose
) в основному збирає багато інформації з вашого комп'ютера, виконуючи десятки різних команд, таких як ps
, zprint
...
Його потрібно запускати як root, а демон /usr/libexec/sysdiagnosed
має дуже цікаві права, такі як com.apple.system-task-ports
та get-task-allow
.
Його plist знаходиться в /System/Library/LaunchDaemons/com.apple.sysdiagnose.plist
, який оголошує 3 MachServices:
com.apple.sysdiagnose.CacheDelete
: Видаляє старі архіви в /var/rmpcom.apple.sysdiagnose.kernel.ipc
: Спеціальний порт 23 (ядро)com.apple.sysdiagnose.service.xpc
: Інтерфейс режиму користувача через класLibsysdiagnose
Obj-C. Три аргументи в словнику можуть бути передані (compress
,display
,run
)
Уніфіковані журнали
MacOS генерує багато журналів, які можуть бути дуже корисними під час запуску програми, намагаючись зрозуміти що вона робить.
Більше того, є деякі журнали, які міститимуть тег <private>
, щоб сховати деяку інформацію, що ідентифікує користувача або комп'ютер. Однак можливо встановити сертифікат для розкриття цієї інформації. Слідуйте поясненням тут.
Hopper
Ліва панель
На лівій панелі Hopper можна побачити символи (Labels) бінарного файлу, список процедур і функцій (Proc) та рядки (Str). Це не всі рядки, а лише ті, що визначені в кількох частинах файлу Mac-O (як cstring або objc_methname
).
Середня панель
На середній панелі ви можете бачити дизасембльований код. І ви можете бачити його у сирому дизасемблюванні, як граф, як декодований і як бінарний, натискаючи на відповідну іконку:
Клацнувши правою кнопкою миші на об'єкті коду, ви можете побачити посилання на/з цього об'єкта або навіть змінити його назву (це не працює в декодованому псевдокоді):
Більше того, в нижній частині середньої панелі ви можете писати команди python.
Права панель
На правій панелі ви можете побачити цікаву інформацію, таку як історія навігації (щоб ви знали, як ви потрапили в поточну ситуацію), граф викликів, де ви можете бачити всі функції, які викликають цю функцію, і всі функції, які викликає ця функція, а також інформацію про локальні змінні.
dtrace
Цей інструмент дозволяє користувачам отримувати доступ до програм на надзвичайно низькому рівні і надає спосіб для користувачів відстежувати програми і навіть змінювати їхній потік виконання. Dtrace використовує пробники, які розміщені по всьому ядру і знаходяться в таких місцях, як початок і кінець системних викликів.
DTrace використовує функцію dtrace_probe_create
для створення пробника для кожного системного виклику. Ці пробники можуть бути активовані в точках входу та виходу кожного системного виклику. Взаємодія з DTrace відбувається через /dev/dtrace, який доступний лише для користувача root.
Щоб увімкнути Dtrace, не вимикаючи повністю захист SIP, ви можете виконати в режимі відновлення: csrutil enable --without dtrace
Ви також можете dtrace
або dtruss
бінарні файли, які ви скомпілювали.
Доступні пробники dtrace можна отримати за допомогою:
Назва зонда складається з чотирьох частин: постачальника, модуля, функції та назви (fbt:mach_kernel:ptrace:entry
). Якщо ви не вкажете якусь частину назви, Dtrace застосує цю частину як шаблон.
Щоб налаштувати DTrace для активації зондів і вказати, які дії виконувати, коли вони спрацьовують, нам потрібно буде використовувати мову D.
Більш детальне пояснення та більше прикладів можна знайти за посиланням https://illumos.org/books/dtrace/chp-intro.html
Приклади
Запустіть man -k dtrace
, щоб перерахувати доступні скрипти DTrace. Приклад: sudo dtruss -n binary
скрипт
dtruss
kdebug
Це засіб трасування ядра. Документовані коди можна знайти в /usr/share/misc/trace.codes
.
Інструменти, такі як latency
, sc_usage
, fs_usage
та trace
, використовують його внутрішньо.
Для взаємодії з kdebug
використовується sysctl
через простір імен kern.kdebug
, а MIB, які можна використовувати, можна знайти в sys/sysctl.h
, де реалізовані функції в bsd/kern/kdebug.c
.
Щоб взаємодіяти з kdebug за допомогою власного клієнта, зазвичай виконуються такі кроки:
Видалити існуючі налаштування з KERN_KDSETREMOVE
Встановити трасування з KERN_KDSETBUF та KERN_KDSETUP
Використовувати KERN_KDGETBUF, щоб отримати кількість записів у буфері
Отримати власного клієнта з трасування за допомогою KERN_KDPINDEX
Увімкнути трасування з KERN_KDENABLE
Прочитати буфер, викликавши KERN_KDREADTR
Щоб зіставити кожен потік з його процесом, викликати KERN_KDTHRMAP.
Щоб отримати цю інформацію, можна використовувати інструмент Apple trace
або спеціальний інструмент kDebugView (kdv).
Зверніть увагу, що Kdebug доступний лише для 1 клієнта одночасно. Тобто лише один інструмент на базі k-debug може бути виконаний одночасно.
ktrace
API ktrace_*
походять з libktrace.dylib
, які обгортують ті, що з Kdebug
. Тоді клієнт може просто викликати ktrace_session_create
та ktrace_events_[single/class]
, щоб встановити зворотні виклики для конкретних кодів, а потім запустити його з ktrace_start
.
Ви можете використовувати це навіть з активованим SIP
Ви можете використовувати утиліту ktrace
як клієнт:
Or tailspin
.
kperf
Це використовується для профілювання на рівні ядра і побудоване за допомогою викликів Kdebug
.
В основному, глобальна змінна kernel_debug_active
перевіряється, і якщо вона встановлена, викликається kperf_kdebug_handler
з кодом Kdebug
та адресою кадру ядра, що викликає. Якщо код Kdebug
відповідає одному з вибраних, отримуються "дії", налаштовані як бітова карта (перевірте osfmk/kperf/action.h
для варіантів).
Kperf також має таблицю MIB sysctl: (як root) sysctl kperf
. Ці коди можна знайти в osfmk/kperf/kperfbsd.c
.
Більше того, підмножина функціональності Kperf знаходиться в kpc
, який надає інформацію про лічильники продуктивності машини.
ProcessMonitor
ProcessMonitor є дуже корисним інструментом для перевірки дій, пов'язаних з процесами, які виконує процес (наприклад, моніторинг нових процесів, які створює процес).
SpriteTree
SpriteTree є інструментом для виведення відносин між процесами.
Вам потрібно моніторити ваш Mac за допомогою команди sudo eslogger fork exec rename create > cap.json
(термінал, що запускає це, вимагає FDA). А потім ви можете завантажити json в цей інструмент, щоб переглянути всі відносини:
FileMonitor
FileMonitor дозволяє моніторити події файлів (такі як створення, модифікації та видалення), надаючи детальну інформацію про такі події.
Crescendo
Crescendo є GUI-інструментом з виглядом і відчуттям, які можуть бути знайомі користувачам Windows з Procmon від Microsoft Sysinternal. Цей інструмент дозволяє записувати різні типи подій, які можна почати і зупинити, дозволяє фільтрувати ці події за категоріями, такими як файл, процес, мережа тощо, і надає функціональність для збереження записаних подій у форматі json.
Apple Instruments
Apple Instruments є частиною інструментів розробника Xcode – використовуються для моніторингу продуктивності додатків, виявлення витоків пам'яті та відстеження активності файлової системи.
fs_usage
Дозволяє відстежувати дії, виконувані процесами:
TaskExplorer
Taskexplorer корисний для перегляду бібліотек, які використовуються бінарним файлом, файлів, які він використовує, та мережевих з'єднань. Він також перевіряє бінарні процеси на virustotal і показує інформацію про бінарний файл.
PT_DENY_ATTACH
У цьому блозі ви можете знайти приклад того, як налагодити працюючий демон, який використовував PT_DENY_ATTACH
, щоб запобігти налагодженню, навіть якщо SIP був вимкнений.
lldb
lldb є де факто інструментом для налагодження бінарних файлів macOS.
Ви можете встановити смак intel, використовуючи lldb, створивши файл .lldbinit
у вашій домашній папці з наступним рядком:
Всередині lldb, збережіть процес за допомогою process save-core
При виклику функції objc_sendMsg
регістр rsi містить назву методу як рядок, закінчений нульовим символом (“C”). Щоб надрукувати назву через lldb, виконайте:
(lldb) x/s $rsi: 0x1000f1576: "startMiningWithPort:password:coreCount:slowMemory:currency:"
(lldb) print (char*)$rsi:
(char *) $1 = 0x00000001000f1576 "startMiningWithPort:password:coreCount:slowMemory:currency:"
(lldb) reg read $rsi: rsi = 0x00000001000f1576 "startMiningWithPort:password:coreCount:slowMemory:currency:"
Анти-динамічний аналіз
Виявлення VM
Команда
sysctl hw.model
повертає "Mac", коли хост є MacOS, але щось інше, коли це VM.Граючи з значеннями
hw.logicalcpu
таhw.physicalcpu
, деякі шкідливі програми намагаються виявити, чи це VM.Деякі шкідливі програми також можуть виявити, чи машина є VMware на основі MAC-адреси (00:50:56).
Також можливо дізнатися, чи процес налагоджується за допомогою простого коду, такого як:
if(P_TRACED == (info.kp_proc.p_flag & P_TRACED)){ //процес налагоджується }
Він також може викликати системний виклик
ptrace
з прапоромPT_DENY_ATTACH
. Це запобігає прикріпленню та трасуванню налагоджувача.Ви можете перевірити, чи функція
sysctl
абоptrace
імпортується (але шкідливе ПЗ може імпортувати її динамічно)Як зазначено в цьому звіті, “Перемога над анти-дебаг техніками: варіанти macOS ptrace” : “Повідомлення Process # exited with status = 45 (0x0000002d) зазвичай є явною ознакою того, що ціль налагодження використовує PT_DENY_ATTACH”
Ядрові дампи
Ядрові дампи створюються, якщо:
kern.coredump
sysctl встановлено на 1 (за замовчуванням)Якщо процес не був suid/sgid або
kern.sugid_coredump
дорівнює 1 (за замовчуванням 0)Ліміт
AS_CORE
дозволяє операцію. Можна подавити створення дампів коду, викликавшиulimit -c 0
і знову увімкнути їх за допомогоюulimit -c unlimited
.
У цих випадках ядрові дампи генеруються відповідно до sysctl kern.corefile
і зазвичай зберігаються в /cores/core/.%P
.
Фаззинг
ReportCrash аналізує процеси, що зазнали краху, і зберігає звіт про крах на диск. Звіт про крах містить інформацію, яка може допомогти розробнику діагностувати причину краху.
Для додатків та інших процесів які працюють у контексті запуску для кожного користувача, ReportCrash працює як LaunchAgent і зберігає звіти про крах у ~/Library/Logs/DiagnosticReports/
користувача.
Для демонів, інших процесів які працюють у системному контексті запуску та інших привілейованих процесів, ReportCrash працює як LaunchDaemon і зберігає звіти про крах у системному /Library/Logs/DiagnosticReports
Якщо ви турбуєтеся про звіти про крах, які надсилаються Apple, ви можете їх вимкнути. Якщо ні, звіти про крах можуть бути корисними для з'ясування, як сервер зазнав краху.
Сон
Під час фуззингу в MacOS важливо не дозволяти Mac засинати:
systemsetup -setsleep Never
pmset, Системні налаштування
Відключення SSH
Якщо ви фуззите через SSH-з'єднання, важливо переконатися, що сесія не закриється. Тому змініть файл sshd_config на:
TCPKeepAlive Yes
ClientAliveInterval 0
ClientAliveCountMax 0
Internal Handlers
Перегляньте наступну сторінку, щоб дізнатися, яка програма відповідає за обробку вказаної схеми або протоколу:
Enumerating Network Processes
Це цікаво, щоб знайти процеси, які керують мережевими даними:
Або використовуйте netstat
або lsof
Libgmalloc
Fuzzers
Працює для CLI інструментів
Він "просто працює" з macOS GUI інструментами. Зверніть увагу, що деякі macOS додатки мають специфічні вимоги, такі як унікальні імена файлів, правильне розширення, необхідність читати файли з пісочниці (~/Library/Containers/com.apple.Safari/Data
)...
Деякі приклади:
Більше інформації про Fuzzing MacOS
Посилання
Last updated