macOS Apps - Inspecting, debugging and Fuzzing
WhiteIntel es un motor de búsqueda alimentado por la dark web que ofrece funcionalidades gratuitas para verificar si una empresa o sus clientes han sido comprometidos por malwares de robo.
El objetivo principal de WhiteIntel es combatir los secuestros de cuentas y los ataques de ransomware resultantes de malwares que roban información.
Puedes visitar su sitio web y probar su motor de forma gratuita en:
Análisis estático
otool
objdump
jtool2
La herramienta se puede utilizar como un reemplazo para codesign, otool y objdump, y proporciona algunas características adicionales. Descárgalo aquí o instálalo con brew
.
Codesign / ldid
Codesign
se puede encontrar en macOS mientras que ldid
se puede encontrar en iOS
SuspiciousPackage
SuspiciousPackage es una herramienta útil para inspeccionar archivos .pkg (instaladores) y ver qué hay dentro antes de instalarlo.
Estos instaladores tienen scripts bash preinstall
y postinstall
que los autores de malware suelen abusar para persistir el malware.
hdiutil
Esta herramienta permite montar archivos de imágenes de disco de Apple (.dmg) para inspeccionarlos antes de ejecutar cualquier cosa:
Será montado en /Volumes
Objective-C
Metadatos
Tenga en cuenta que los programas escritos en Objective-C conservan sus declaraciones de clase cuando se compilan en binarios Mach-O. Tales declaraciones de clase incluyen el nombre y tipo de:
La clase
Los métodos de clase
Las variables de instancia de clase
Puede obtener esta información utilizando class-dump:
Llamada de función
Cuando se llama a una función en un binario que utiliza Objective-C, en lugar de llamar directamente a esa función, el código compilado llamará a objc_msgSend
. Lo cual 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 va a recibir el mensaje". O de forma más simple, es el objeto sobre el cual se invoca el método. Si el método es un método de clase, este 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, de forma más simple, este es simplemente el nombre del método.
Los parámetros restantes son cualquier valor que sea requerido por 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 para el método |
4to argumento | rcx | 2do argumento para el método |
5to argumento | r8 | 3er argumento para el método |
6to argumento | r9 | 4to argumento para el método |
7mo+ argumento | rsp+ (en la pila) | 5to+ argumento para el método |
Swift
Con binarios de Swift, dado que hay compatibilidad con Objective-C, a veces se pueden extraer declaraciones usando class-dump pero no siempre.
Con las líneas de comando jtool -l
o otool -l
es posible encontrar varias secciones que comienzan con el prefijo __swift5
:
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 suelen contener información sobre el nombre de la función y los atributos de una manera fea, por lo que son muy útiles y existen "demanglers" que pueden obtener el nombre original:
Binarios empaquetados
Verificar la entropía alta
Revisar las cadenas de texto (si hay casi ninguna cadena comprensible, está empaquetado)
El empaquetador UPX para MacOS genera una sección llamada "__XHDR"
Análisis Dinámico
Ten 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 <ruta-del-binario>
o permitir la depuración del binario (puedes usar este script)
Ten en cuenta que para instrumentar binarios del sistema (como cloudconfigurationd
) en macOS, SIP debe estar deshabilitado (simplemente quitar la firma no funcionará).
Registros Unificados
macOS genera muchos registros que pueden ser muy útiles al ejecutar una aplicación para entender qué está haciendo.
Además, hay algunos registros que contendrán la etiqueta <private>
para ocultar cierta información identificable del usuario o computadora. Sin embargo, es posible instalar un certificado para revelar esta información. Sigue 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 de texto (Str). Estas no son todas las cadenas, sino las definidas en varias partes del archivo Mac-O (como cstring o objc_methname
).
Panel central
En el panel central puedes ver el código desensamblado. Puedes verlo como un desensamblado en bruto, como gráfico, como decompilado y como binario haciendo clic en el icono respectivo:
Al hacer clic derecho en un objeto de código, puedes ver las referencias desde/hacia ese objeto o incluso cambiar su nombre (esto no funciona en el pseudocódigo decompilado):
Además, en la parte inferior central puedes escribir comandos de Python.
Panel derecho
En el panel derecho puedes ver información interesante como el historial de navegación (para saber cómo llegaste a la situación actual), el grafo de llamadas donde puedes ver todas las funciones que llaman a esta función y todas las funciones que esta función llama, e información sobre variables locales.
dtrace
Permite a los usuarios acceder a las aplicaciones a un nivel extremadamente bajo y proporciona una forma para que los usuarios rastreen programas e incluso cambien su flujo de ejecución. Dtrace utiliza sondas que se colocan en todo el kernel y están en ubicaciones como el inicio y fin de las llamadas al sistema.
DTrace utiliza la función dtrace_probe_create
para crear una sonda para cada llamada al sistema. Estas sondas 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.
Para habilitar Dtrace sin deshabilitar completamente la protección SIP, puedes ejecutar en modo de recuperación: csrutil enable --without dtrace
También puedes dtrace
o dtruss
binarios que hayas compilado.
Las sondas disponibles de dtrace se pueden obtener con:
El nombre de la sonda consta de cuatro partes: el proveedor, módulo, función y nombre (fbt:mach_kernel:ptrace:entry
). Si no se especifica 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 activen, 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
En línea
script
dtruss
ktrace
Puedes usar este incluso con SIP activado
ProcessMonitor
ProcessMonitor es una herramienta muy útil para verificar las acciones relacionadas con procesos 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
(se requiere FDA para lanzar este terminal). Y luego puedes cargar el json en esta herramienta para ver todas las relaciones:
FileMonitor
FileMonitor permite monitorear eventos de archivos (como creaciones, 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 Sysinternals. Esta herramienta permite iniciar y detener la grabación de varios tipos de eventos, permite filtrar estos eventos por categorías como archivo, proceso, red, etc., y proporciona la funcionalidad para guardar los eventos grabados en formato json.
Apple Instruments
Apple Instruments son parte de las herramientas de desarrollador de Xcode, utilizadas para monitorear el rendimiento de la aplicación, identificar fugas de memoria y rastrear la actividad del sistema de archivos.
fs_usage
Permite seguir las acciones realizadas por los procesos:
TaskExplorer
Taskexplorer es útil para ver las bibliotecas utilizadas por un binario, los archivos que está utilizando y las conexiones de red. También verifica los procesos binarios en virustotal y muestra información sobre el binario.
PT_DENY_ATTACH
En esta publicación de blog puedes encontrar un ejemplo sobre cómo depurar un daemon en ejecución que utilizaba PT_DENY_ATTACH
para evitar la depuración incluso si SIP estaba deshabilitado.
lldb
lldb es la herramienta de hecho para depurar binarios en macOS.
Puedes establecer el sabor de Intel al usar lldb creando un archivo llamado .lldbinit
en tu carpeta de inicio con la siguiente línea:
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. |
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 funciones. |
finish (f) | Ejecutar el resto de las instrucciones en la función actual ("frame") y detener. |
control + c | Pausar la ejecución. Si el proceso ha sido ejecutado (r) o continuado (c), esto hará que el proceso se detenga ...donde sea que esté ejecutándose actualmente. |
breakpoint (b) | b main #Cualquier función llamada main b <nombre_binario>`main #Función principal del binario b set -n main --shlib <nombre_lib> #Función principal del binario indicado b -[NSDictionary objectForKey:] b -a 0x0000000100004bd9 br l #Lista de puntos de interrupción br e/dis <número> #Habilitar/Deshabilitar punto de interrupción breakpoint delete <número> |
help | help breakpoint #Obtener ayuda del comando breakpoint help memory write #Obtener ayuda para escribir en la memoria |
reg | |
x/s <registro/dirección de memoria> | Mostrar la memoria como una cadena terminada en nulo. |
x/i <registro/dirección de memoria> | Mostrar la memoria como instrucción de ensamblador. |
x/b <registro/dirección de memoria> | Mostrar la memoria como byte. |
print object (po) | Esto imprimirá el objeto referenciado por el parámetro po $raw
Nota que la mayoría de las APIs o métodos Objective-C de Apple devuelven objetos, y por lo tanto deben mostrarse mediante el comando "print object" (po). Si po no produce una salida significativa, usa |
memory | memory read 0x000.... memory read $x0+0xf2a memory write 0x100600000 -s 4 0x41414141 #Escribir AAAA en esa dirección memory write -f s $rip+0x11f+7 "AAAA" #Escribir AAAA en la dirección |
disassembly | dis #Desensamblar la función actual dis -n <nombre_func> #Desensamblar función dis -n <nombre_func> -b <nombre_base> #Desensamblar función dis -c 6 #Desensamblar 6 líneas dis -c 0x100003764 -e 0x100003768 # Desde una dirección hasta la otra dis -p -c 4 # Comenzar en la dirección actual desensamblando |
parray | parray 3 (char **)$x1 # Verificar el array de 3 componentes en el registro x1 |
Al llamar a la función objc_sendMsg
, el registro rsi contiene el nombre del método como una cadena terminada en nulo ("C"). Para imprimir el nombre a través de lldb haz:
(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:"
Anti-Análisis Dinámico
Detección de Máquinas Virtuales
El comando
sysctl hw.model
devuelve "Mac" cuando el host es un MacOS pero algo diferente cuando es una VM.Jugando con los valores de
hw.logicalcpu
yhw.physicalcpu
algunos malwares intentan detectar si es una VM.Algunos malwares también pueden detectar si la máquina es basada en VMware según la dirección MAC (00:50:56).
También es posible encontrar si un proceso está siendo depurado con un código simple como:
if(P_TRACED == (info.kp_proc.p_flag & P_TRACED)){ //proceso siendo depurado }
También se puede invocar la llamada al sistema
ptrace
con la banderaPT_DENY_ATTACH
. Esto impide que un debugger se adjunte y haga seguimiento.Puedes verificar si la función
sysctl
optrace
está siendo importada (pero el malware podría importarla dinámicamente)Como se señala en este artículo, “Derrotando Técnicas Anti-Depuración: variantes de ptrace en macOS” : “El mensaje Proceso # salió con estado = 45 (0x0000002d) suele ser una clara señal de que el objetivo de depuración está usando PT_DENY_ATTACH”
Fuzzing
ReportCrash analiza los procesos que se bloquean y guarda un informe de bloqueo en el disco. Un informe de bloqueo contiene información que puede ayudar a un desarrollador a diagnosticar la causa de un bloqueo.
Para aplicaciones y otros procesos que se ejecutan en el contexto de lanzamiento por usuario, ReportCrash se ejecuta como un LaunchAgent y guarda los informes de bloqueo en ~/Library/Logs/DiagnosticReports/
del usuario.
Para demonios, otros procesos que se ejecutan en el contexto de lanzamiento del sistema y otros procesos privilegiados, ReportCrash se ejecuta como un LaunchDaemon y guarda los informes de bloqueo en /Library/Logs/DiagnosticReports
del sistema.
Si te preocupa que los informes de bloqueo sean enviados a Apple, puedes desactivarlos. Si no, los informes de bloqueo pueden ser útiles para descubrir cómo se bloqueó un servidor.
Suspensión
Mientras se realiza fuzzing en un MacOS, es importante evitar que la Mac entre en suspensión:
systemsetup -setsleep Never
pmset, Preferencias del Sistema
Desconexión de SSH
Si estás realizando fuzzing a través de una conexión SSH, es importante asegurarse de que la sesión no se cierre. Por lo tanto, cambia el archivo sshd_config con:
TCPKeepAlive Yes
ClientAliveInterval 0
ClientAliveCountMax 0
Manipuladores Internos
Consulta la siguiente página para descubrir cómo puedes encontrar qué aplicación es responsable de manejar el esquema o protocolo especificado:
pagemacOS File Extension & URL scheme app handlersEnumeración de Procesos de Red
O utiliza netstat
o lsof
Libgmalloc
Fuzzers
Funciona para herramientas de línea de comandos.
Funciona con herramientas de interfaz gráfica de usuario (GUI) de macOS. Ten en cuenta que algunas aplicaciones de macOS tienen requisitos específicos como nombres de archivo únicos, la extensión correcta, necesidad de leer los archivos desde el sandbox (~/Library/Containers/com.apple.Safari/Data
)...
Algunos ejemplos:
Más información sobre Fuzzing en MacOS
Referencias
WhiteIntel es un motor de búsqueda alimentado por la dark web que ofrece funcionalidades gratuitas para verificar si una empresa o sus clientes han sido comprometidos por malwares de robo.
El objetivo principal de WhiteIntel es combatir los secuestros de cuentas y los ataques de ransomware resultantes de malwares que roban información.
Puedes visitar su sitio web y probar su motor de forma gratuita en:
Última actualización