macOS Apps - Inspección, depuración y Fuzzing
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Análisis Estático
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
Puedes descargar disarm desde aquí.
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
Puedes descargar jtool2 aquí o instalarlo con 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
[!CAUTION] > jtool está en desuso a favor de disarm
Codesign / ldid
[!TIP] >
Codesign
se puede encontrar en macOS mientras queldid
se puede encontrar en 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 es una herramienta útil para inspeccionar archivos .pkg (instaladores) y ver qué hay dentro antes de instalarlos.
Estos instaladores tienen scripts bash preinstall
y postinstall
que los autores de malware suelen abusar para persistir el malware.
hdiutil
Esta herramienta permite montar imágenes de disco de Apple (.dmg) para inspeccionarlas antes de ejecutar cualquier cosa:
hdiutil attach ~/Downloads/Firefox\ 58.0.2.dmg
Se montará en /Volumes
Binarios empaquetados
- Verificar la alta entropía
- Verificar las cadenas (si casi no hay cadenas comprensibles, empaquetado)
- El empaquetador UPX para MacOS genera una sección llamada "__XHDR"
Análisis estático de Objective-C
Metadatos
caution
Tenga en cuenta que los programas escritos en Objective-C retienen sus declaraciones de clase cuando se compilan en Mach-O binaries. Tales declaraciones de clase incluyen el nombre y tipo de:
- Las interfaces definidas
- Los métodos de la interfaz
- Las variables de instancia de la interfaz
- Los protocolos definidos
Tenga en cuenta que estos nombres podrían estar ofuscados para dificultar la inversión del binario.
Llamada a funciones
Cuando se llama a una función en un binario que utiliza Objective-C, el código compilado en lugar de llamar a esa función, llamará a objc_msgSend
. Que llamará a la función final:
Los parámetros que esta función espera son:
- El primer parámetro (self) es "un puntero que apunta a la instancia de la clase que debe recibir el mensaje". O más simplemente, es el objeto sobre el cual se invoca el método. Si el método es un método de clase, esto será una instancia del objeto de la clase (en su totalidad), mientras que para un método de instancia, self apuntará a una instancia instanciada de la clase como un objeto.
- El segundo parámetro, (op), es "el selector del método que maneja el mensaje". Nuevamente, más simplemente, esto es solo el nombre del método.
- Los parámetros restantes son cualquier valor que requiera el método (op).
Vea cómo obtener esta información fácilmente con lldb
en ARM64 en esta página:
x64:
Argumento | Registro | (para) objc_msgSend |
---|---|---|
1er argumento | rdi | self: objeto sobre el cual se invoca el método |
2do argumento | rsi | op: nombre del método |
3er argumento | rdx | 1er argumento al método |
4to argumento | rcx | 2do argumento al método |
5to argumento | r8 | 3er argumento al método |
6to argumento | r9 | 4to argumento al método |
7mo+ argumento | rsp+ | 5to+ argumento al método |
Volcar metadatos de ObjectiveC
Dynadump
Dynadump es una herramienta para volcar clases de binarios de Objective-C. El github especifica dylibs, pero esto también funciona con ejecutables.
./dynadump dump /path/to/bin
En el momento de escribir esto, este es actualmente el que mejor funciona.
Herramientas regulares
nm --dyldinfo-only /path/to/bin
otool -ov /path/to/bin
objdump --macho --objc-meta-data /path/to/bin
class-dump
class-dump es la herramienta original que genera declaraciones para las clases, categorías y protocolos en código formateado en ObjetiveC.
Es antigua y no se mantiene, por lo que probablemente no funcionará correctamente.
ICDump
iCDump es un volcado de clases de Objective-C moderno y multiplataforma. En comparación con las herramientas existentes, iCDump puede ejecutarse de forma independiente del ecosistema de Apple y expone enlaces de Python.
import icdump
metadata = icdump.objc.parse("/path/to/bin")
print(metadata.to_decl())
Análisis estático de Swift
Con los binarios de Swift, dado que hay compatibilidad con Objective-C, a veces puedes extraer declaraciones usando class-dump pero no siempre.
Con los comandos jtool -l
o otool -l
es posible encontrar varias secciones que comienzan con el prefijo __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
[...]
Puedes encontrar más información sobre la información almacenada en esta sección en esta publicación de blog.
Además, los binarios de Swift pueden tener símbolos (por ejemplo, las bibliotecas necesitan almacenar símbolos para que sus funciones puedan ser llamadas). Los símbolos generalmente tienen la información sobre el nombre de la función y atributos de una manera poco legible, por lo que son muy útiles y hay "demanglers" que pueden obtener el nombre original:
# Ghidra plugin
https://github.com/ghidraninja/ghidra_scripts/blob/master/swift_demangler.py
# Swift cli
swift demangle
Análisis Dinámico
warning
Tenga en cuenta que para depurar binarios, SIP debe estar deshabilitado (csrutil disable
o csrutil enable --without debug
) o copiar los binarios a una carpeta temporal y eliminar la firma con codesign --remove-signature <binary-path>
o permitir la depuración del binario (puede usar este script)
warning
Tenga en cuenta que para instrumentar binarios del sistema, (como cloudconfigurationd
) en macOS, SIP debe estar deshabilitado (simplemente eliminar la firma no funcionará).
APIs
macOS expone algunas APIs interesantes que brindan información sobre los procesos:
proc_info
: Este es el principal que proporciona mucha información sobre cada proceso. Necesita ser root para obtener información de otros procesos, pero no necesita derechos especiales o puertos mach.libsysmon.dylib
: Permite obtener información sobre procesos a través de funciones expuestas por XPC, sin embargo, es necesario tener el derechocom.apple.sysmond.client
.
Stackshot y microstackshots
Stackshotting es una técnica utilizada para capturar el estado de los procesos, incluidos los stacks de llamadas de todos los hilos en ejecución. Esto es particularmente útil para la depuración, análisis de rendimiento y comprensión del comportamiento del sistema en un momento específico. En iOS y macOS, el stackshotting se puede realizar utilizando varias herramientas y métodos como las herramientas sample
y spindump
.
Sysdiagnose
Esta herramienta (/usr/bini/ysdiagnose
) básicamente recopila mucha información de su computadora ejecutando decenas de comandos diferentes como ps
, zprint
...
Debe ejecutarse como root y el daemon /usr/libexec/sysdiagnosed
tiene derechos muy interesantes como com.apple.system-task-ports
y get-task-allow
.
Su plist se encuentra en /System/Library/LaunchDaemons/com.apple.sysdiagnose.plist
que declara 3 MachServices:
com.apple.sysdiagnose.CacheDelete
: Elimina archivos antiguos en /var/rmpcom.apple.sysdiagnose.kernel.ipc
: Puerto especial 23 (kernel)com.apple.sysdiagnose.service.xpc
: Interfaz de modo usuario a través de la clase Obj-CLibsysdiagnose
. Se pueden pasar tres argumentos en un dict (compress
,display
,run
)
Registros Unificados
MacOS genera muchos registros que pueden ser muy útiles al ejecutar una aplicación tratando de entender qué está haciendo.
Además, hay algunos registros que contendrán la etiqueta <private>
para ocultar información identificable de usuario o computadora. Sin embargo, es posible instalar un certificado para divulgar esta información. Siga las explicaciones de aquí.
Hopper
Panel izquierdo
En el panel izquierdo de Hopper es posible ver los símbolos (Etiquetas) del binario, la lista de procedimientos y funciones (Proc) y las cadenas (Str). No son todas las cadenas, sino las definidas en varias partes del archivo Mac-O (como cstring o objc_methname
).
Panel medio
En el panel medio puede ver el código desensamblado. Y puede verlo en un desensamblado crudo, como gráfico, como decompilado y como binario haciendo clic en el ícono respectivo:
Al hacer clic derecho en un objeto de código, puede ver referencias a/desde ese objeto o incluso cambiar su nombre (esto no funciona en pseudocódigo decompilado):
Además, en la parte inferior del medio puede escribir comandos de python.
Panel derecho
En el panel derecho puede ver información interesante como el historial de navegación (para que sepa cómo llegó a la situación actual), el gráfico de llamadas donde puede ver todas las funciones que llaman a esta función y todas las funciones que esta función llama, y la información de variables locales.
dtrace
Permite a los usuarios acceder a aplicaciones a un nivel muy bajo y proporciona una forma para que los usuarios rastreen programas e incluso cambien su flujo de ejecución. Dtrace utiliza probes que están colocados a lo largo del kernel y están en ubicaciones como el inicio y el final de las llamadas al sistema.
DTrace utiliza la función dtrace_probe_create
para crear un probe para cada llamada al sistema. Estos probes pueden activarse en el punto de entrada y salida de cada llamada al sistema. La interacción con DTrace ocurre a través de /dev/dtrace que solo está disponible para el usuario root.
tip
Para habilitar Dtrace sin deshabilitar completamente la protección SIP, podría ejecutar en modo de recuperación: csrutil enable --without dtrace
También puede dtrace
o dtruss
binarios que ha compilado.
Los probes disponibles de dtrace se pueden obtener con:
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
El nombre de la sonda consta de cuatro partes: el proveedor, módulo, función y nombre (fbt:mach_kernel:ptrace:entry
). Si no especificas alguna parte del nombre, Dtrace aplicará esa parte como un comodín.
Para configurar DTrace para activar sondas y especificar qué acciones realizar cuando se disparen, necesitaremos usar el lenguaje D.
Una explicación más detallada y más ejemplos se pueden encontrar en https://illumos.org/books/dtrace/chp-intro.html
Ejemplos
Ejecuta man -k dtrace
para listar los scripts de DTrace disponibles. Ejemplo: sudo dtruss -n binary
#Count the number of syscalls of each running process
sudo dtrace -n 'syscall:::entry {@[execname] = count()}'
- guion
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
Es una herramienta de trazado del kernel. Los códigos documentados se pueden encontrar en /usr/share/misc/trace.codes
.
Herramientas como latency
, sc_usage
, fs_usage
y trace
la utilizan internamente.
Para interactuar con kdebug
, se usa sysctl
sobre el espacio de nombres kern.kdebug
y los MIBs que se pueden usar se encuentran en sys/sysctl.h
, teniendo las funciones implementadas en bsd/kern/kdebug.c
.
Para interactuar con kdebug con un cliente personalizado, estos son generalmente los pasos:
- Eliminar configuraciones existentes con KERN_KDSETREMOVE
- Establecer trazado con KERN_KDSETBUF y KERN_KDSETUP
- Usar KERN_KDGETBUF para obtener el número de entradas del búfer
- Obtener el propio cliente del trazado con KERN_KDPINDEX
- Habilitar el trazado con KERN_KDENABLE
- Leer el búfer llamando a KERN_KDREADTR
- Para emparejar cada hilo con su proceso, llamar a KERN_KDTHRMAP.
Para obtener esta información, es posible usar la herramienta de Apple trace
o la herramienta personalizada kDebugView (kdv).
Nota que Kdebug solo está disponible para 1 cliente a la vez. Así que solo se puede ejecutar una herramienta impulsada por k-debug al mismo tiempo.
ktrace
Las APIs ktrace_*
provienen de libktrace.dylib
, que envuelven las de Kdebug
. Luego, un cliente puede simplemente llamar a ktrace_session_create
y ktrace_events_[single/class]
para establecer callbacks en códigos específicos y luego iniciarlo con ktrace_start
.
Puedes usar este incluso con SIP activado.
Puedes usar como clientes la utilidad ktrace
:
ktrace trace -s -S -t c -c ls | grep "ls("
O tailspin
.
kperf
Esto se utiliza para hacer un perfilado a nivel de kernel y está construido utilizando llamadas de Kdebug
.
Básicamente, se verifica la variable global kernel_debug_active
y si está activada, se llama a kperf_kdebug_handler
con el código de Kdebug
y la dirección del marco del kernel que llama. Si el código de Kdebug
coincide con uno seleccionado, se obtienen las "acciones" configuradas como un bitmap (consulta osfmk/kperf/action.h
para las opciones).
Kperf también tiene una tabla MIB de sysctl: (como root) sysctl kperf
. Este código se puede encontrar en osfmk/kperf/kperfbsd.c
.
Además, un subconjunto de la funcionalidad de Kperf reside en kpc
, que proporciona información sobre los contadores de rendimiento de la máquina.
ProcessMonitor
ProcessMonitor es una herramienta muy útil para verificar las acciones relacionadas con el proceso que un proceso está realizando (por ejemplo, monitorear qué nuevos procesos está creando un proceso).
SpriteTree
SpriteTree es una herramienta que imprime las relaciones entre procesos.
Necesitas monitorear tu Mac con un comando como sudo eslogger fork exec rename create > cap.json
(el terminal que lanza esto requiere FDA). Y luego puedes cargar el json en esta herramienta para ver todas las relaciones:
FileMonitor
FileMonitor permite monitorear eventos de archivos (como creación, modificaciones y eliminaciones) proporcionando información detallada sobre dichos eventos.
Crescendo
Crescendo es una herramienta GUI con la apariencia que los usuarios de Windows pueden conocer de Procmon de Microsoft Sysinternal. Esta herramienta permite que la grabación de varios tipos de eventos se inicie y detenga, permite filtrar estos eventos por categorías como archivo, proceso, red, etc., y proporciona la funcionalidad para guardar los eventos grabados en un formato json.
Apple Instruments
Apple Instruments son parte de las herramientas de desarrollador de Xcode – utilizadas para monitorear el rendimiento de aplicaciones, identificar fugas de memoria y rastrear la actividad del sistema de archivos.
fs_usage
Permite seguir las acciones realizadas por los procesos:
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 es útil para ver las bibliotecas utilizadas por un binario, los archivos que está usando y las conexiones de red.
También verifica los procesos binarios contra virustotal y muestra información sobre el binario.
PT_DENY_ATTACH
En esta publicación del blog puedes encontrar un ejemplo sobre cómo depurar un daemon en ejecución que utilizó PT_DENY_ATTACH
para prevenir la depuración incluso si SIP estaba deshabilitado.
lldb
lldb es la herramienta de facto para la depuración de binarios en macOS.
lldb ./malware.bin
lldb -p 1122
lldb -n malware.bin
lldb -n malware.bin --waitfor
Puedes establecer el sabor de intel al usar lldb creando un archivo llamado .lldbinit
en tu carpeta de inicio con la siguiente línea:
settings set target.x86-disassembly-flavor intel
warning
Dentro de lldb, volcar un proceso con process save-core
(lldb) Comando | Descripción |
run (r) | Iniciar la ejecución, que continuará sin interrupciones hasta que se alcance un punto de interrupción o el proceso termine. |
process launch --stop-at-entry | Iniciar la ejecución deteniéndose en el punto de entrada |
continue (c) | Continuar la ejecución del proceso depurado. |
nexti (n / ni) | Ejecutar la siguiente instrucción. Este comando omitirá las llamadas a funciones. |
stepi (s / si) | Ejecutar la siguiente instrucción. A diferencia del comando nexti, este comando entrará en las llamadas a
bash
SueñoMientras se realiza fuzzing en MacOS, es importante no permitir que el Mac entre en modo de suspensión:
Desconexión SSHSi estás realizando fuzzing a través de una conexión SSH, es importante asegurarte de que la sesión no se desconecte. Así que cambia el archivo sshd_config con:
bash
Controladores InternosConsulta la siguiente página para descubrir cómo puedes encontrar qué aplicación es responsable de manejar el esquema o protocolo especificado: macOS File Extension & URL scheme app handlers Enumerando Procesos de RedEsto es interesante para encontrar procesos que están gestionando datos de red: bash
O usa Libgmallocbash
FuzzersAFL++Funciona para herramientas de CLI LitefuzzSimplemente "funciona" con herramientas GUI de macOS. Tenga en cuenta que algunas aplicaciones de macOS tienen requisitos específicos como nombres de archivos únicos, la extensión correcta, necesitan leer los archivos desde el sandbox ( Algunos ejemplos: bash
Más información sobre Fuzzing en MacOS
Referencias
tip Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Support HackTricks
|