macOS Apps - Inspecting, debugging and Fuzzing

Wsparcie dla HackTricks

Analiza statyczna

otool & objdump & nm

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
nm -m ./tccd # List of symbols

jtool2 & Disarm

Możesz pobrać disarm stąd.

ARCH=arm64e disarm -c -i -I --signature /path/bin # Get bin info and signature
ARCH=arm64e disarm -c -l /path/bin # Get binary sections
ARCH=arm64e disarm -c -L /path/bin # Get binary commands (dependencies included)
ARCH=arm64e disarm -c -S /path/bin # Get symbols (func names, strings...)
ARCH=arm64e disarm -c -d /path/bin # Get disasembled
jtool2 -d __DATA.__const myipc_server | grep MIG # Get MIG info

Możesz pobrać jtool2 tutaj lub zainstalować go za pomocą 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

jtool jest przestarzały na rzecz disarm

Codesign / ldid

Codesign można znaleźć w macOS, podczas gdy ldid można znaleźć w 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

SuspiciousPackage to narzędzie przydatne do inspekcji plików .pkg (instalatorów) i zobaczenia, co się w nich znajduje przed ich zainstalowaniem. Te instalatory mają skrypty bash preinstall i postinstall, które autorzy złośliwego oprogramowania zazwyczaj nadużywają, aby utrzymać złośliwe oprogramowanie.

hdiutil

To narzędzie pozwala na zamontowanie obrazów dysków Apple (.dmg) w celu ich inspekcji przed uruchomieniem czegokolwiek:

hdiutil attach ~/Downloads/Firefox\ 58.0.2.dmg

It will be mounted in /Volumes

Packed binaries

  • Sprawdź wysoką entropię

  • Sprawdź ciągi (jeśli prawie nie ma zrozumiałego ciągu, spakowane)

  • Packer UPX dla MacOS generuje sekcję o nazwie "__XHDR"

Static Objective-C analysis

Metadata

Zauważ, że programy napisane w Objective-C zachowują swoje deklaracje klas po skompilowaniu do binariów Mach-O. Takie deklaracje klas zawierają nazwę i typ:

  • Zdefiniowane interfejsy

  • Metody interfejsu

  • Zmienne instancji interfejsu

  • Zdefiniowane protokoły

Zauważ, że te nazwy mogą być zafałszowane, aby utrudnić odwracanie binariów.

Function calling

Gdy funkcja jest wywoływana w binarium, które używa Objective-C, skompilowany kod zamiast wywoływać tę funkcję, wywoła objc_msgSend. Który wywoła finalną funkcję:

Parametry, których ta funkcja oczekuje, to:

  • Pierwszy parametr (self) to "wskaźnik, który wskazuje na instancję klasy, która ma otrzymać wiadomość". Mówiąc prościej, jest to obiekt, na którym wywoływana jest metoda. Jeśli metoda jest metodą klasy, będzie to instancja obiektu klasy (jako całość), natomiast dla metody instancji, self będzie wskazywać na zainstancjonowaną instancję klasy jako obiekt.

  • Drugi parametr (op) to "selekcja metody, która obsługuje wiadomość". Mówiąc prościej, to po prostu nazwa metody.

  • Pozostałe parametry to wszelkie wartości wymagane przez metodę (op).

Zobacz, jak łatwo uzyskać te informacje za pomocą lldb w ARM64 na tej stronie:

Introduction to ARM64v8

x64:

Argument

Rejestr

(dla) objc_msgSend

1. argument

rdi

self: obiekt, na którym wywoływana jest metoda

2. argument

rsi

op: nazwa metody

3. argument

rdx

1. argument do metody

4. argument

rcx

2. argument do metody

5. argument

r8

3. argument do metody

6. argument

r9

4. argument do metody

7. i więcej

rsp+ (na stosie)

5. i więcej argumentów do metody

Dump ObjectiveC metadata

Dynadump

Dynadump to narzędzie do zrzucania klas binariów Objective-C. Github określa dyliby, ale działa to również z plikami wykonywalnymi.

./dynadump dump /path/to/bin

W momencie pisania, to jest aktualnie to, co działa najlepiej.

Regular tools

nm --dyldinfo-only /path/to/bin
otool -ov /path/to/bin
objdump --macho --objc-meta-data /path/to/bin

class-dump

class-dump to oryginalne narzędzie do generowania deklaracji dla klas, kategorii i protokołów w kodzie sformatowanym w ObjectiveC.

Jest stare i nieutrzymywane, więc prawdopodobnie nie będzie działać poprawnie.

ICDump

iCDump to nowoczesny i wieloplatformowy zrzut klas Objective-C. W porównaniu do istniejących narzędzi, iCDump może działać niezależnie od ekosystemu Apple i udostępnia powiązania Pythona.

import icdump
metadata = icdump.objc.parse("/path/to/bin")

print(metadata.to_decl())

Statyczna analiza Swift

Z binariów Swift, ponieważ istnieje kompatybilność z Objective-C, czasami można wyodrębnić deklaracje za pomocą class-dump, ale nie zawsze.

Za pomocą poleceń jtool -l lub otool -l można znaleźć kilka sekcji, które zaczynają się od prefiksu __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
[...]

Możesz znaleźć więcej informacji na temat informacji przechowywanych w tej sekcji w tym poście na blogu.

Ponadto, binarne pliki Swift mogą mieć symbole (na przykład biblioteki muszą przechowywać symbole, aby ich funkcje mogły być wywoływane). Symbole zazwyczaj zawierają informacje o nazwie funkcji i atrybucie w nieczytelny sposób, więc są bardzo przydatne i istnieją "demanglery", które mogą uzyskać oryginalną nazwę:

# Ghidra plugin
https://github.com/ghidraninja/ghidra_scripts/blob/master/swift_demangler.py

# Swift cli
swift demangle

Dynamic Analysis

Zauważ, że aby debugować binaria, SIP musi być wyłączony (csrutil disable lub csrutil enable --without debug) lub skopiować binaria do tymczasowego folderu i usunąć podpis za pomocą codesign --remove-signature <binary-path> lub zezwolić na debugowanie binariów (możesz użyć tego skryptu)

Zauważ, że aby instrumentować binaria systemowe, (takie jak cloudconfigurationd) na macOS, SIP musi być wyłączony (same usunięcie podpisu nie zadziała).

APIs

macOS udostępnia kilka interesujących API, które dostarczają informacji o procesach:

  • proc_info: To główne API, które dostarcza wiele informacji o każdym procesie. Musisz być rootem, aby uzyskać informacje o innych procesach, ale nie potrzebujesz specjalnych uprawnień ani portów mach.

  • libsysmon.dylib: Umożliwia uzyskanie informacji o procesach za pomocą funkcji XPC, jednak potrzebne jest posiadanie uprawnienia com.apple.sysmond.client.

Stackshot & microstackshots

Stackshotting to technika używana do uchwycenia stanu procesów, w tym stosów wywołań wszystkich działających wątków. Jest to szczególnie przydatne do debugowania, analizy wydajności i zrozumienia zachowania systemu w określonym momencie. Na iOS i macOS, stackshotting można przeprowadzić za pomocą kilku narzędzi i metod, takich jak narzędzia sample i spindump.

Sysdiagnose

To narzędzie (/usr/bini/ysdiagnose) zasadniczo zbiera wiele informacji z twojego komputera, wykonując dziesiątki różnych poleceń, takich jak ps, zprint...

Musi być uruchomione jako root, a demon /usr/libexec/sysdiagnosed ma bardzo interesujące uprawnienia, takie jak com.apple.system-task-ports i get-task-allow.

Jego plist znajduje się w /System/Library/LaunchDaemons/com.apple.sysdiagnose.plist, który deklaruje 3 MachServices:

  • com.apple.sysdiagnose.CacheDelete: Usuwa stare archiwa w /var/rmp

  • com.apple.sysdiagnose.kernel.ipc: Specjalny port 23 (jądro)

  • com.apple.sysdiagnose.service.xpc: Interfejs trybu użytkownika przez klasę Obj-C Libsysdiagnose. Można przekazać trzy argumenty w słowniku (compress, display, run)

Unified Logs

MacOS generuje wiele logów, które mogą być bardzo przydatne podczas uruchamiania aplikacji, próbując zrozumieć co ona robi.

Co więcej, są pewne logi, które będą zawierać tag <private>, aby ukryć niektóre informacje identyfikowalne użytkownika lub komputera. Jednak możliwe jest zainstalowanie certyfikatu, aby ujawnić te informacje. Postępuj zgodnie z wyjaśnieniami tutaj.

Hopper

Left panel

W lewym panelu Hopper można zobaczyć symbole (Labels) binariów, listę procedur i funkcji (Proc) oraz ciągi (Str). To nie są wszystkie ciągi, ale te zdefiniowane w różnych częściach pliku Mac-O (takich jak cstring lub objc_methname).

Middle panel

W środkowym panelu można zobaczyć zdekompilowany kod. Można go zobaczyć jako surowy dekompilat, jako graf, jako zdekompilowany i jako binarne klikając na odpowiednią ikonę:

Klikając prawym przyciskiem myszy na obiekt kodu, można zobaczyć odniesienia do/od tego obiektu lub nawet zmienić jego nazwę (to nie działa w zdekompilowanym pseudokodzie):

Co więcej, w dolnej części środkowego panelu można pisać polecenia Pythona.

Right panel

W prawym panelu można zobaczyć interesujące informacje, takie jak historia nawigacji (aby wiedzieć, jak dotarłeś do obecnej sytuacji), graf wywołań, w którym można zobaczyć wszystkie funkcje, które wywołują tę funkcję oraz wszystkie funkcje, które ta funkcja wywołuje, oraz informacje o zmiennych lokalnych.

dtrace

Umożliwia użytkownikom dostęp do aplikacji na niezwykle niskim poziomie i zapewnia sposób dla użytkowników na śledzenie programów i nawet zmianę ich przepływu wykonania. Dtrace używa probes, które są umieszczane w całym jądrze i znajdują się w miejscach takich jak początek i koniec wywołań systemowych.

DTrace używa funkcji dtrace_probe_create, aby utworzyć sondę dla każdego wywołania systemowego. Te sondy mogą być uruchamiane w punkcie wejścia i wyjścia każdego wywołania systemowego. Interakcja z DTrace odbywa się przez /dev/dtrace, który jest dostępny tylko dla użytkownika root.

Aby włączyć Dtrace bez całkowitego wyłączania ochrony SIP, możesz wykonać w trybie odzyskiwania: csrutil enable --without dtrace

Możesz również dtrace lub dtruss binaria, które skompilowałeś.

Dostępne sondy dtrace można uzyskać za pomocą:

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

Nazwa sondy składa się z czterech części: dostawcy, modułu, funkcji i nazwy (fbt:mach_kernel:ptrace:entry). Jeśli nie określisz jakiejś części nazwy, Dtrace zastosuje tę część jako symbol wieloznaczny.

Aby skonfigurować DTrace do aktywacji sond i określenia, jakie działania wykonać, gdy zostaną uruchomione, będziemy musieli użyć języka D.

Bardziej szczegółowe wyjaśnienie i więcej przykładów można znaleźć w https://illumos.org/books/dtrace/chp-intro.html

Przykłady

Uruchom man -k dtrace, aby wyświetlić dostępne skrypty DTrace. Przykład: sudo dtruss -n binary

  • W linii

#Count the number of syscalls of each running process
sudo dtrace -n 'syscall:::entry {@[execname] = count()}'
  • skrypt

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

dtruss -c ls #Get syscalls of ls
dtruss -c -p 1000 #get syscalls of PID 1000

kdebug

To jest funkcja śledzenia jądra. Udokumentowane kody można znaleźć w /usr/share/misc/trace.codes.

Narzędzia takie jak latency, sc_usage, fs_usage i trace używają go wewnętrznie.

Aby zintegrować się z kdebug, używa się sysctl w przestrzeni nazw kern.kdebug, a MIB-y do użycia można znaleźć w sys/sysctl.h, mając funkcje zaimplementowane w bsd/kern/kdebug.c.

Aby interagować z kdebug za pomocą niestandardowego klienta, zazwyczaj wykonuje się następujące kroki:

  • Usuń istniejące ustawienia za pomocą KERN_KDSETREMOVE

  • Ustaw śledzenie za pomocą KERN_KDSETBUF i KERN_KDSETUP

  • Użyj KERN_KDGETBUF, aby uzyskać liczbę wpisów w buforze

  • Wyciągnij własnego klienta z śledzenia za pomocą KERN_KDPINDEX

  • Włącz śledzenie za pomocą KERN_KDENABLE

  • Odczytaj bufor, wywołując KERN_KDREADTR

  • Aby dopasować każdy wątek do jego procesu, wywołaj KERN_KDTHRMAP.

Aby uzyskać te informacje, można użyć narzędzia Apple trace lub niestandardowego narzędzia kDebugView (kdv).

Uwaga: Kdebug jest dostępny tylko dla 1 klienta na raz. Więc tylko jedno narzędzie zasilane k-debug może być uruchomione w tym samym czasie.

ktrace

API ktrace_* pochodzi z libktrace.dylib, które opakowuje te z Kdebug. Następnie klient może po prostu wywołać ktrace_session_create i ktrace_events_[single/class], aby ustawić wywołania zwrotne dla konkretnych kodów, a następnie rozpocząć je za pomocą ktrace_start.

Możesz używać tego nawet z aktywnym SIP

Możesz używać jako klientów narzędzia ktrace:

ktrace trace -s -S -t c -c ls | grep "ls("

Or tailspin.

kperf

To narzędzie służy do profilowania na poziomie jądra i jest zbudowane przy użyciu wywołań Kdebug.

W zasadzie, globalna zmienna kernel_debug_active jest sprawdzana, a jeśli jest ustawiona, wywołuje kperf_kdebug_handler z kodem Kdebug i adresem ramki jądra, która wywołuje. Jeśli kod Kdebug pasuje do jednego z wybranych, otrzymuje "akcje" skonfigurowane jako bitmapa (sprawdź osfmk/kperf/action.h dla opcji).

Kperf ma również tabelę MIB sysctl: (jako root) sysctl kperf. Te kody można znaleźć w osfmk/kperf/kperfbsd.c.

Ponadto, podzbiór funkcjonalności Kperf znajduje się w kpc, który dostarcza informacji o licznikach wydajności maszyny.

ProcessMonitor

ProcessMonitor to bardzo przydatne narzędzie do sprawdzania działań związanych z procesami, które dany proces wykonuje (na przykład, monitorowanie, które nowe procesy tworzy dany proces).

SpriteTree

SpriteTree to narzędzie do wyświetlania relacji między procesami. Musisz monitorować swojego maca za pomocą polecenia sudo eslogger fork exec rename create > cap.json (terminal uruchamiający to wymaga FDA). A następnie możesz załadować json w tym narzędziu, aby zobaczyć wszystkie relacje:

FileMonitor

FileMonitor pozwala monitorować zdarzenia związane z plikami (takie jak tworzenie, modyfikacje i usunięcia), dostarczając szczegółowych informacji o takich zdarzeniach.

Crescendo

Crescendo to narzędzie GUI, które wygląda i działa jak znane użytkownikom Windows narzędzie Microsoft Sysinternal’s Procmon. To narzędzie pozwala na rozpoczęcie i zatrzymanie nagrywania różnych typów zdarzeń, umożliwia filtrowanie tych zdarzeń według kategorii, takich jak plik, proces, sieć itp., oraz zapewnia funkcjonalność zapisywania nagranych zdarzeń w formacie json.

Apple Instruments

Apple Instruments są częścią narzędzi deweloperskich Xcode – używane do monitorowania wydajności aplikacji, identyfikowania wycieków pamięci i śledzenia aktywności systemu plików.

fs_usage

Pozwala śledzić działania wykonywane przez procesy:

fs_usage -w -f filesys ls #This tracks filesystem actions of proccess names containing ls
fs_usage -w -f network curl #This tracks network actions

TaskExplorer

Taskexplorer jest przydatny do zobaczenia bibliotek używanych przez binarny plik, plików, które wykorzystuje oraz połączeń sieciowych. Sprawdza również procesy binarne w stosunku do virustotal i pokazuje informacje o binarnym pliku.

PT_DENY_ATTACH

W tym wpisie na blogu można znaleźć przykład, jak debugować działający demon, który używał PT_DENY_ATTACH, aby zapobiec debugowaniu, nawet jeśli SIP był wyłączony.

lldb

lldb jest de facto narzędziem do debugowania binarnych plików macOS.

lldb ./malware.bin
lldb -p 1122
lldb -n malware.bin
lldb -n malware.bin --waitfor

Możesz ustawić smak intel podczas używania lldb, tworząc plik o nazwie .lldbinit w swoim katalogu domowym z następującą linią:

settings set target.x86-disassembly-flavor intel

Wewnątrz lldb, zrzutuj proces za pomocą process save-core

(lldb) Komenda

Opis

run (r)

Rozpoczęcie wykonania, które będzie kontynuowane, aż do osiągnięcia punktu przerwania lub zakończenia procesu.

process launch --stop-at-entry

Rozpocznij wykonanie zatrzymując się w punkcie wejścia

continue (c)

Kontynuuj wykonanie debugowanego procesu.

nexti (n / ni)

Wykonaj następną instrukcję. Ta komenda pominie wywołania funkcji.

stepi (s / si)

Wykonaj następną instrukcję. W przeciwieństwie do komendy nexti, ta komenda wejdzie w wywołania funkcji.

finish (f)

Wykonaj resztę instrukcji w bieżącej funkcji (“ramce”), zwróć i zatrzymaj.

control + c

Wstrzymaj wykonanie. Jeśli proces był uruchomiony (r) lub kontynuowany (c), spowoduje to zatrzymanie procesu ...gdziekolwiek aktualnie się wykonuje.

breakpoint (b)

b main #Każda funkcja o nazwie main

b <binname>`main #Funkcja main bin

b set -n main --shlib <lib_name> #Funkcja main wskazanej bin

breakpoint set -r '\[NSFileManager .*\]$' #Każda metoda NSFileManager

breakpoint set -r '\[NSFileManager contentsOfDirectoryAtPath:.*\]$'

break set -r . -s libobjc.A.dylib # Zatrzymaj w wszystkich funkcjach tej biblioteki

b -a 0x0000000100004bd9

br l #Lista punktów przerwania

br e/dis <num> #Włącz/Wyłącz punkt przerwania

breakpoint delete <num>

help

help breakpoint #Uzyskaj pomoc dotyczącą komendy punktu przerwania

help memory write #Uzyskaj pomoc w zapisywaniu do pamięci

reg

reg read

reg read $rax

reg read $rax --format <format>

reg write $rip 0x100035cc0

x/s <reg/adres pamięci>

Wyświetl pamięć jako łańcuch zakończony znakiem null.

x/i <reg/adres pamięci>

Wyświetl pamięć jako instrukcję asemblera.

x/b <reg/adres pamięci>

Wyświetl pamięć jako bajt.

print object (po)

To wydrukuje obiekt wskazywany przez parametr

po $raw

{

dnsChanger = {

"affiliate" = "";

"blacklist_dns" = ();

Należy zauważyć, że większość API lub metod Objective-C firmy Apple zwraca obiekty, a zatem powinny być wyświetlane za pomocą komendy “print object” (po). Jeśli po nie produkuje sensownego wyniku, użyj x/b

memory

memory read 0x000.... memory read $x0+0xf2a memory write 0x100600000 -s 4 0x41414141 #Zapisz AAAA w tym adresie memory write -f s $rip+0x11f+7 "AAAA" #Zapisz AAAA w adresie

disassembly

dis #Disas bieżącą funkcję

dis -n <funcname> #Disas funkcję

dis -n <funcname> -b <basename> #Disas funkcję dis -c 6 #Disas 6 linii dis -c 0x100003764 -e 0x100003768 # Od jednego adresu do drugiego dis -p -c 4 # Rozpocznij w bieżącym adresie disassembling

parray

parray 3 (char **)$x1 # Sprawdź tablicę 3 komponentów w rejestrze x1

image dump sections

Wydrukuj mapę pamięci bieżącego procesu

image dump symtab <library>

image dump symtab CoreNLP #Uzyskaj adres wszystkich symboli z CoreNLP

Podczas wywoływania funkcji objc_sendMsg, rejestr rsi zawiera nazwę metody jako łańcuch zakończony znakiem null (“C”). Aby wydrukować nazwę za pomocą lldb, wykonaj:

(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:"

Anty-analiza dynamiczna

Wykrywanie VM

  • Komenda sysctl hw.model zwraca "Mac", gdy host to MacOS, ale coś innego, gdy jest to VM.

  • Bawiąc się wartościami hw.logicalcpu i hw.physicalcpu, niektóre złośliwe oprogramowanie próbują wykryć, czy to VM.

  • Niektóre złośliwe oprogramowanie mogą również wykrywać, czy maszyna jest oparta na VMware na podstawie adresu MAC (00:50:56).

  • Możliwe jest również sprawdzenie czy proces jest debugowany za pomocą prostego kodu, takiego jak:

  • if(P_TRACED == (info.kp_proc.p_flag & P_TRACED)){ //proces jest debugowany }

  • Może również wywołać wywołanie systemowe ptrace z flagą PT_DENY_ATTACH. To zapobiega dołączeniu i śledzeniu przez debuger.

  • Możesz sprawdzić, czy funkcja sysctl lub ptrace jest importowana (ale złośliwe oprogramowanie mogłoby zaimportować ją dynamicznie)

  • Jak zauważono w tym artykule, “Defeating Anti-Debug Techniques: macOS ptrace variants” : “Wiadomość Process # exited with status = 45 (0x0000002d) jest zazwyczaj oznaką, że cel debugowania używa PT_DENY_ATTACH

Zrzuty rdzenia

Zrzuty rdzenia są tworzone, jeśli:

  • kern.coredump sysctl jest ustawiony na 1 (domyślnie)

  • Jeśli proces nie był suid/sgid lub kern.sugid_coredump jest 1 (domyślnie 0)

  • Limit AS_CORE pozwala na operację. Możliwe jest stłumienie tworzenia zrzutów rdzenia, wywołując ulimit -c 0 i ponowne włączenie ich za pomocą ulimit -c unlimited.

W tych przypadkach zrzuty rdzenia są generowane zgodnie z kern.corefile sysctl i zazwyczaj przechowywane w /cores/core/.%P.

Fuzzing

ReportCrash analizuje procesy, które uległy awarii i zapisuje raport o awarii na dysku. Raport o awarii zawiera informacje, które mogą pomóc programiście zdiagnozować przyczynę awarii. Dla aplikacji i innych procesów uruchamianych w kontekście launchd dla użytkownika, ReportCrash działa jako LaunchAgent i zapisuje raporty o awariach w ~/Library/Logs/DiagnosticReports/ użytkownika. Dla demonów, innych procesów uruchamianych w kontekście launchd systemu i innych procesów z uprawnieniami, ReportCrash działa jako LaunchDaemon i zapisuje raporty o awariach w /Library/Logs/DiagnosticReports systemu.

Jeśli obawiasz się, że raporty o awariach są wysyłane do Apple, możesz je wyłączyć. Jeśli nie, raporty o awariach mogą być przydatne do ustalenia, jak serwer uległ awarii.

#To disable crash reporting:
launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist

#To re-enable crash reporting:
launchctl load -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist

Sen

Podczas fuzzingu w MacOS ważne jest, aby nie pozwolić Macowi na uśpienie:

Rozłączenie SSH

Jeśli fuzzujesz przez połączenie SSH, ważne jest, aby upewnić się, że sesja nie zostanie zakończona. Zmień więc plik sshd_config na:

  • TCPKeepAlive Yes

  • ClientAliveInterval 0

  • ClientAliveCountMax 0

sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist
sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist

Internal Handlers

Sprawdź następującą stronę, aby dowiedzieć się, która aplikacja jest odpowiedzialna za obsługę określonego schematu lub protokołu:

macOS File Extension & URL scheme app handlers

Enumerating Network Processes

To interesujące, aby znaleźć procesy, które zarządzają danymi sieciowymi:

dtrace -n 'syscall::recv*:entry { printf("-> %s (pid=%d)", execname, pid); }' >> recv.log
#wait some time
sort -u recv.log > procs.txt
cat procs.txt

Lub użyj netstat lub lsof

Libgmalloc

lldb -o "target create `which some-binary`" -o "settings set target.env-vars DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib" -o "run arg1 arg2" -o "bt" -o "reg read" -o "dis -s \$pc-32 -c 24 -m -F intel" -o "quit"

Fuzzers

Działa z narzędziami CLI

To "po prostu działa" z narzędziami GUI macOS. Należy zauważyć, że niektóre aplikacje macOS mają specyficzne wymagania, takie jak unikalne nazwy plików, odpowiednie rozszerzenie, konieczność odczytu plików z piaskownicy (~/Library/Containers/com.apple.Safari/Data)...

Kilka przykładów:

# iBooks
litefuzz -l -c "/System/Applications/Books.app/Contents/MacOS/Books FUZZ" -i files/epub -o crashes/ibooks -t /Users/test/Library/Containers/com.apple.iBooksX/Data/tmp -x 10 -n 100000 -ez

# -l : Local
# -c : cmdline with FUZZ word (if not stdin is used)
# -i : input directory or file
# -o : Dir to output crashes
# -t : Dir to output runtime fuzzing artifacts
# -x : Tmeout for the run (default is 1)
# -n : Num of fuzzing iterations (default is 1)
# -e : enable second round fuzzing where any crashes found are reused as inputs
# -z : enable malloc debug helpers

# Font Book
litefuzz -l -c "/System/Applications/Font Book.app/Contents/MacOS/Font Book FUZZ" -i input/fonts -o crashes/font-book -x 2 -n 500000 -ez

# smbutil (using pcap capture)
litefuzz -lk -c "smbutil view smb://localhost:4455" -a tcp://localhost:4455 -i input/mac-smb-resp -p -n 100000 -z

# screensharingd (using pcap capture)
litefuzz -s -a tcp://localhost:5900 -i input/screenshared-session --reportcrash screensharingd -p -n 100000

Więcej informacji o fuzzingu MacOS

Referencje

Wsparcie HackTricks

Last updated