macOS Apps - Inspecting, debugging and Fuzzing
Статичний аналіз
otool
objdump
jtool2
Цей інструмент може бути використаний як заміна для codesign, otool та objdump, і надає кілька додаткових функцій. Завантажте його тут або встановіть за допомогою brew
.
Codesign / ldid
Codesign
можна знайти в macOS, тоді як ldid
можна знайти в iOS
SuspiciousPackage
SuspiciousPackage - це інструмент, корисний для інспектування файлів .pkg (інсталяторів) та перегляду їх вмісту перед встановленням.
Ці інсталятори мають сценарії bash preinstall
та postinstall
, які зловмисники зазвичай використовують для постійного розповсюдження шкідливого програмного забезпечення.
hdiutil
Цей інструмент дозволяє монтувати образи дисків Apple (.dmg) для їх інспектування перед запуском чого-небудь:
Це буде змонтовано в /Volumes
Objective-C
Метадані
Зверніть увагу, що програми, написані на Objective-C, зберігають свої оголошення класів під час компіляції у бінарні файли Mach-O. Такі оголошення класів включають ім'я та тип:
Клас
Методи класу
Змінні екземпляра класу
Ви можете отримати цю інформацію, використовуючи class-dump:
Виклик функції
Коли функція викликається в бінарному файлі, який використовує Objective-C, скомпільований код замість виклику цієї функції буде викликати objc_msgSend
. Це викличе останню функцію:
Параметри, які очікує ця функція, такі:
Перший параметр (self) - "вказівник, який вказує на екземпляр класу, який має отримати повідомлення". Іншими словами, це об'єкт, на якому викликається метод. Якщо метод є методом класу, це буде екземпляр об'єкта класу (в цілому), тоді як для методу екземпляру self буде вказувати на створений екземпляр класу як на об'єкт.
Другий параметр (op) - "селектор методу, який обробляє повідомлення". Це просто ім'я методу.
Решта параметрів - будь-які значення, які потрібні методу (op).
Дивіться, як легко отримати цю інформацію за допомогою lldb
в ARM64 на цій сторінці:
x64:
Аргумент | Регістр | (для) objc_msgSend |
1-й аргумент | rdi | self: об'єкт, на якому викликається метод |
2-й аргумент | rsi | op: ім'я методу |
3-й аргумент | rdx | 1-й аргумент методу |
4-й аргумент | rcx | 2-й аргумент методу |
5-й аргумент | r8 | 3-й аргумент методу |
6-й аргумент | r9 | 4-й аргумент методу |
7-й+ аргумент | rsp+ (на стеку) | 5-й+ аргумент методу |
Swift
У бінарних файлах Swift, оскільки є сумісність з Objective-C, іноді можна видобути оголошення за допомогою class-dump, але не завжди.
За допомогою командних рядків jtool -l
або otool -l
можна знайти кілька розділів, які починаються з префікса __swift5
:
Ви можете знайти додаткову інформацію про інформацію, збережену в цих розділах, у цьому дописі в блозі.
Більше того, бінарні файли Swift можуть містити символи (наприклад, бібліотеки повинні зберігати символи, щоб їх функції можна було викликати). Символи зазвичай містять інформацію про назву функції та атрибути у вигляді некрасивого тексту, тому вони є дуже корисними, і є "деманглери", які можуть отримати початкову назву:
Упаковані бінарні файли
Перевірте високу ентропію
Перевірте рядки (якщо там майже немає зрозумілих рядків, то файл упакований)
Упаковувач UPX для MacOS генерує розділ під назвою "__XHDR"
Динамічний аналіз
Зверніть увагу, що для налагодження бінарних файлів SIP повинен бути вимкнений (csrutil disable
або csrutil enable --without debug
) або скопіювати файли в тимчасову папку та видалити підпис за допомогою codesign --remove-signature <шлях-до-бінарного-файлу>
або дозволити налагодження бінарного файлу (можна використовувати цей скрипт)
Зверніть увагу, що для інструментування системних бінарних файлів (таких як cloudconfigurationd
) на macOS, SIP повинен бути вимкнений (просто видалення підпису не працюватиме).
Об'єднані журнали
MacOS генерує багато журналів, які можуть бути дуже корисними при запуску додатка для розуміння що він робить.
Більше того, є деякі журнали, які міститимуть тег <private>
, щоб приховати деяку інформацію про користувача або комп'ютер. Однак можна встановити сертифікат для розкриття цієї інформації. Дотримуйтесь пояснень тут.
Hopper
Ліва панель
У лівій панелі hopper можна побачити символи (Мітки) бінарного файлу, список процедур та функцій (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
ktrace
Ви можете використовувати цей навіть з активованим SIP
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 flavour при використанні lldb, створивши файл з назвою .lldbinit
у вашій домашній папці з наступним рядком:
У ллдб виведіть процес за допомогою process save-core
(lldb) Команда | Опис |
run (r) | Початок виконання, яке триватиме безперервно до того, як буде досягнуто точку зупинки або процес завершиться. |
continue (c) | Продовжити виконання відлагоджуваного процесу. |
nexti (n / ni) | Виконати наступну інструкцію. Ця команда пропустить виклики функцій. |
stepi (s / si) | Виконати наступну інструкцію. На відміну від команди nexti, ця команда увійде в виклики функцій. |
finish (f) | Виконати решту інструкцій у поточній функції ("фрейм") повернутися і зупинитися. |
control + c | Призупинити виконання. Якщо процес був запущений (r) або продовжений (c), це призведе до зупинки процесу ...де він в даний момент виконується. |
breakpoint (b) | b main #Будь-яка функція з ім'ям main b <binname>`main #Основна функція бінарного файлу b set -n main --shlib <lib_name> #Основна функція вказаного бінарного файлу b -[NSDictionary objectForKey:] b -a 0x0000000100004bd9 br l #Список точок зупинки br e/dis <num> #Увімкнути/вимкнути точку зупинки breakpoint delete <num> |
help | help breakpoint #Отримати довідку про команду точки зупинки help memory write #Отримати довідку щодо запису в пам'ять |
reg | |
x/s <reg/memory address | Показати пам'ять як рядок з нульовим завершенням. |
x/i <reg/memory address | Показати пам'ять як машинну інструкцію. |
x/b <reg/memory address | Показати пам'ять як байт. |
print object (po) | Це виведе об'єкт, на який посилається параметр po $raw
Зверніть увагу, що більшість API або методів Objective-C Apple повертають об'єкти, тому їх слід відображати за допомогою команди "print object" (po). Якщо po не виводить змістовний результат, використовуйте |
memory | memory read 0x000.... memory read $x0+0xf2a memory write 0x100600000 -s 4 0x41414141 #Записати AAAA за цією адресою memory write -f s $rip+0x11f+7 "AAAA" #Записати AAAA за адресою |
disassembly | dis #Розібрати поточну функцію dis -n <funcname> #Розібрати функцію dis -n <funcname> -b <basename> #Розібрати функцію dis -c 6 #Розібрати 6 рядків dis -c 0x100003764 -e 0x100003768 # Від однієї адреси до іншої dis -p -c 4 # Почати розібрати з поточної адреси |
parray | parray 3 (char **)$x1 # Перевірити масив з 3 компонентами в регістрі x1 |
При виклику функції 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:"
Протидія динамічному аналізу
Виявлення віртуальних машин
Команда
sysctl hw.model
повертає "Mac", коли хост - MacOS, але щось інше, коли це віртуальна машина.Граючи зі значеннями
hw.logicalcpu
таhw.physicalcpu
, деякі шкідливі програми намагаються виявити, чи це віртуальна машина.Деякі шкідливі програми також можуть виявити, чи машина базується на VMware за MAC-адресою (00:50:56).
Також можна виявити, чи процес відлагоджується за допомогою простого коду, наприклад:
if(P_TRACED == (info.kp_proc.p_flag & P_TRACED)){ //процес відлагоджується }
Також можна викликати системний виклик
ptrace
з прапорцемPT_DENY_ATTACH
. Це запобігає приєднанню та відстеженню відлагоджувача.Можна перевірити, чи імпортується функція
sysctl
абоptrace
(але шкідлива програма може імпортувати її динамічно)Як вказано в цьому огляді, “Перемога над анти-відлагоджувальними техніками: варіанти macOS ptrace” : “Повідомлення Процес # завершився з статусом = 45 (0x0000002d) зазвичай є вказівкою на те, що ціль відлагоджування використовує PT_DENY_ATTACH”
Fuzzing
ReportCrash аналізує процеси, які виходять з ладу, та зберігає звіт про збій на диск. Звіт про збій містить інформацію, яка може допомогти розробнику діагностувати причину збою.
Для додатків та інших процесів, які працюють в контексті запуску користувача, ReportCrash працює як LaunchAgent та зберігає звіти про збої в ~/Library/Logs/DiagnosticReports/
користувача
Для демонів, інших процесів, які працюють в контексті запуску системи та інших привілейованих процесів, ReportCrash працює як LaunchDaemon та зберігає звіти про збої в /Library/Logs/DiagnosticReports
Якщо вас турбують звіти про збої, які надсилаються в Apple, ви можете їх вимкнути. Якщо ні, звіти про збої можуть бути корисними для визначення причини збою сервера.
Сон
Під час фаззингу в MacOS важливо не дозволяти Mac спати:
systemsetup -setsleep Never
pmset, System Preferences
Відключення SSH
Якщо ви фаззуєте через SSH-з'єднання, важливо переконатися, що сеанс не завершиться. Тому змініть файл sshd_config наступним чином:
TCPKeepAlive Yes
ClientAliveInterval 0
ClientAliveCountMax 0
Внутрішні обробники
Перевірте наступну сторінку, щоб дізнатися, яка програма відповідає за обробку вказаної схеми або протоколу:
pagemacOS File Extension & URL scheme app handlersПерелік мережевих процесів
Це цікаво виявити процеси, які керують мережевими даними:
Або скористайтеся netstat
або lsof
Libgmalloc
Fuzzers
Працює для інструментів командного рядка
Він "просто працює" з інструментами GUI macOS. Зверніть увагу, що деякі програми macOS мають певні вимоги, такі як унікальні імена файлів, правильне розширення, потрібно читати файли з пісочниці (~/Library/Containers/com.apple.Safari/Data
)...
Деякі приклади:
Додаткова інформація про Fuzzing MacOS
Посилання
Last updated