Охоплюються різні аспекти аналізу, налагодження та фазінгу додатків macOS. У ній розглядаються методи статичного та динамічного аналізу, а також різні інструменти та техніки, які можна використовувати для дослідження програм на macOS.
otool -L /bin/ls #List dynamically linked libraries otool -tv /bin/ps #Decompile application
objdump -m --dylibs-used /bin/ls #List dynamically linked libraries objdump -m -h /bin/ls # Get headers information objdump -m --syms /bin/ls # Check if the symbol table exists to get function names objdump -m --full-contents /bin/ls # Dump every section objdump -d /bin/ls # Dissasemble the binary objdump --disassemble-symbols=_hello --x86-asm-syntax=intel toolsdemo #Disassemble a function using intel flavour
Інструмент можна використовувати як заміну для codesign , otool і objdump і надає кілька додаткових функцій. Завантажте його тут або встановіть за допомогою brew.
# Install brew install --cask jtool2 jtool2 -l /bin/ls # Get commands (headers) jtool2 -L /bin/ls # Get libraries jtool2 -S /bin/ls # Get symbol info jtool2 -d /bin/ls # Dump binary jtool2 -D /bin/ls # Decompile binary # Get signature information ARCH=x86_64 jtool2 --sig /System/Applications/Automator.app/Contents/MacOS/Automator # Get MIG information jtool2 -d __DATA.__const myipc_server | grep MIG
Codesign можна знайти в macOS , а ldid в iOS
# Get signer codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier" # Check if the app’s contents have been modified codesign --verify --verbose /Applications/Safari.app # Get entitlements from the binary codesign -d --entitlements :- /System/Applications/Automator.app # Check the TCC perms # Check if the signature is valid spctl --assess --verbose /Applications/Safari.app # Sign a binary codesign -s <cert-name-keychain> toolsdemo # Get signature info ldid -h <binary> # Get entitlements ldid -e <binary> # Change entilements ## /tmp/entl.xml is a XML file with the new entitlements to add ldid -S/tmp/entl.xml <binary>
SuspiciousPackage — це корисний інструмент для перевірки файлів .pkg (інсталяторів) і перегляду того, що всередині, перед встановленням. Ці інсталятори маютьpreinstallскриптиpostinstallbash, якими автори зловмисного програмного забезпечення зазвичай зловживають, щоб зберегти зловмисне програмне забезпечення .
Цей інструмент дозволяє монтувати файли образів дисків Apple ( .dmg ), щоб перевірити їх перед запуском:
hdiutil attach ~/Downloads/Firefox\ 58.0.2.dmg
Його буде встановлено/Volumes
Зауважте, що програми, написані на Objective-C, зберігають свої оголошення класів під час компіляції у двійкові файли Mach-O . Такі оголошення класу включають назву та тип:
Клас
Методи класу
Змінні екземпляра класу
Ви можете отримати цю інформацію за допомогою class-dump :
class-dump Kindle.app
Зауважте, що ці імена можуть бути обфусковані, щоб ускладнити реверсування двійкового коду.
Коли функція викликається у двійковому вигляді, який використовує object-C, скомпільований код замість виклику цієї функції викличе objc_msgSend. Яка буде викликати останню функцію:
Параметри, які очікує ця функція:
Перший параметр ( self ) — це «вказівник, який вказує на екземпляр класу, який має отримати повідомлення ». Або простіше кажучи, це об’єкт, до якого викликається метод. Якщо метод є методом класу, це буде екземпляр об’єкта класу (в цілому), тоді як для методу екземпляра self вказуватиме на створений екземпляр класу як об’єкт.
Другий параметр ( op ) — це «селектор методу, який обробляє повідомлення». Знову ж таки, простіше кажучи, це просто назва методу.
Решта параметрів — це будь-які значення, необхідні для методу (op).
З двійковими файлами Swift, оскільки існує сумісність з Objective-C, іноді ви можете видобувати оголошення за допомогою класу dump , але не завжди.
За допомогою командного рядка jtool -lабо otool -lможна знайти кілька розділів, які починаються з __swift5префікса:
jtool2 -l /Applications/Stocks.app/Contents/MacOS/Stocks
LC 00: LC_SEGMENT_64 Mem: 0x000000000-0x100000000 __PAGEZERO
LC 01: LC_SEGMENT_64 Mem: 0x100000000-0x100028000 __TEXT
[...]
Mem: 0x100026630-0x100026d54 __TEXT.__swift5_typeref
Mem: 0x100026d60-0x100027061 __TEXT.__swift5_reflstr
Mem: 0x100027064-0x1000274cc __TEXT.__swift5_fieldmd
Mem: 0x1000274cc-0x100027608 __TEXT.__swift5_capture
[...]
Ви можете знайти додаткову інформацію про інформацію, що зберігається в цих розділах, у цій публікації блогу .
Крім того, двійкові файли Swift можуть мати символи (наприклад, бібліотеки повинні зберігати символи, щоб можна було викликати їх функції). Символи зазвичай містять інформацію про ім’я функції та attr у негарний спосіб, тому вони дуже корисні, і існують « demanglers» , які можуть отримати оригінальну назву:
# Ghidra plugin https://github.com/ghidraninja/ghidra_scripts/blob/master/swift_demangler.py # Swift cli swift demangle
Перевірте наявність високої ентропії
Перевірте рядки (майже немає зрозумілого рядка, упакований)
Пакувальник UPX для MacOS створює розділ під назвою “__XHDR”
Зауважте, що для налагодження двійкових файлів SIP потрібно вимкнути (
csrutil disableабоcsrutil enable --without debug) або скопіювати двійкові файли до тимчасової папки та видалити підписcodesign --remove-signature <binary-path>або дозволити налагодження двійкового файлу (ви можете використати цей сценарій )Зауважте, що для того, щоб інструментувати двійкові файли системи (наприклад,
cloudconfigurationd) у macOS, SIP має бути вимкнено (просте видалення підпису не спрацює).
MacOS створює багато журналів, які можуть бути дуже корисними під час запуску програми, яка намагається зрозуміти, що вона робить .
Крім того, деякі журнали містять тег, <private>щоб приховати деяку ідентифікаційну інформацію користувача чи комп’ютера . Однак для розкриття цієї інформації можна встановити сертифікат . Слідкуйте за поясненнями звідси .
На лівій панелі бункера можна побачити символи ( Labels ) двійкового файлу, список процедур і функцій ( Proc ) і рядки ( Str ). Це не всі рядки, але ті, що визначені в кількох частинах файлу Mac-O (наприклад, cstring або objc_methname ).
На середній панелі ви можете побачити розібраний код . І ви можете побачити його в необробленому вигляді , у вигляді графіка , у вигляді декомпіляції та у двійковому вигляді , натиснувши відповідну піктограму:
Клацнувши правою кнопкою миші в об’єкті коду, ви можете побачити посилання на/з цього об’єкта або навіть змінити його назву (це не працює в декомпільованому псевдокоді):
Крім того, посередині внизу можна писати команди python .
На правій панелі ви можете побачити цікаву інформацію, таку як історія навігації (щоб ви знали, як ви дійшли до поточної ситуації), графік викликів h, де ви можете побачити всі функції, які викликають цю функцію , і всі функції, які ця функція викликає та інформацію про локальні змінні .
Це дозволяє користувачам отримати доступ до програм на надзвичайно низькому рівні та надає користувачам можливість відстежувати програми та навіть змінювати потік їх виконання. Dtrace використовує зонди , які розміщуються по всьому ядру та знаходяться в таких місцях, як початок і кінець системних викликів.
DTrace використовує dtrace_probe_createфункцію для створення зонду для кожного системного виклику. Ці зонди можуть запускатися в точці входу та виходу кожного системного виклику . Взаємодія з DTrace відбувається через /dev/dtrace, який доступний лише для користувача root.
Щоб увімкнути Dtrace без повного вимкнення захисту SIP, ви можете виконати в режимі відновлення:
csrutil enable --without dtraceВи також можете dtraceабо dtrussдвійкові файли, які ви зібрали .
Доступні зонди dtrace можна отримати за допомогою:
dtrace -l | head
ID PROVIDER MODULE FUNCTION NAME
1 dtrace BEGIN
2 dtrace END
3 dtrace ERROR
43 profile profile-97
44 profile profile-199
Ім’я зонду складається з чотирьох частин: постачальника, модуля, функції та імені ( fbt:mach_kernel:ptrace:entry). Якщо ви не вкажете частину назви, Dtrace застосує цю частину як символ підстановки.
Щоб налаштувати DTrace на активацію зондів і вказати, які дії виконувати під час їх спрацьовування, нам потрібно буде використовувати мову D.
Більш детальне пояснення та більше прикладів можна знайти на https://illumos.org/books/dtrace/chp-intro.html
Запустіть man -k dtrace, щоб отримати список доступних сценаріїв DTrace . приклад:sudo dtruss -n binary
В лінію
#Count the number of syscalls of each running process
sudo dtrace -n 'syscall:::entry {@[execname] = count()}'
syscall:::entry
/pid == $1/
{
}
#Log every syscall of a PID
sudo dtrace -s script.d 1234
syscall::open:entry
{
printf("%s(%s)", probefunc, copyinstr(arg0));
}
syscall::close:entry
{
printf("%s(%d)\n", probefunc, arg0);
}
#Log files opened and closed by a process
sudo dtrace -s b.d -c "cat /etc/hosts"
syscall:::entry
{
;
}
syscall:::return
{
printf("=%d\n", arg1);
}
#Log sys calls with values
sudo dtrace -s syscalls_info.d -c "cat /etc/hosts"
dtruss -c ls #Get syscalls of ls dtruss -c -p 1000 #get syscalls of PID 1000
Ви можете використовувати його, навіть якщо SIP активований
ktrace trace -s -S -t c -c ls | grep "ls("