Abuso de Procesos en macOS

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

Informaci贸n B谩sica sobre Procesos

Un proceso es una instancia de un ejecutable en ejecuci贸n, sin embargo, los procesos no ejecutan c贸digo, estos son hilos. Por lo tanto, los procesos son solo contenedores para hilos en ejecuci贸n que proporcionan la memoria, descriptores, puertos, permisos...

Tradicionalmente, los procesos se iniciaban dentro de otros procesos (excepto el PID 1) llamando a fork, que crear铆a una copia exacta del proceso actual y luego el proceso hijo generalmente llamar铆a a execve para cargar el nuevo ejecutable y ejecutarlo. Luego, se introdujo vfork para hacer este proceso m谩s r谩pido sin copiar memoria.
Luego se introdujo posix_spawn combinando vfork y execve en una sola llamada y aceptando flags:

  • POSIX_SPAWN_RESETIDS: Restablecer ids efectivos a ids reales
  • POSIX_SPAWN_SETPGROUP: Establecer la afiliaci贸n del grupo de procesos
  • POSUX_SPAWN_SETSIGDEF: Establecer el comportamiento predeterminado de la se帽al
  • POSIX_SPAWN_SETSIGMASK: Establecer la m谩scara de se帽al
  • POSIX_SPAWN_SETEXEC: Ejecutar en el mismo proceso (como execve con m谩s opciones)
  • POSIX_SPAWN_START_SUSPENDED: Iniciar suspendido
  • _POSIX_SPAWN_DISABLE_ASLR: Iniciar sin ASLR
  • _POSIX_SPAWN_NANO_ALLOCATOR: Usar el asignador Nano de libmalloc
  • _POSIX_SPAWN_ALLOW_DATA_EXEC: Permitir rwx en segmentos de datos
  • POSIX_SPAWN_CLOEXEC_DEFAULT: Cerrar todas las descripciones de archivo en exec(2) por defecto
  • _POSIX_SPAWN_HIGH_BITS_ASLR: Aleatorizar los bits altos del deslizamiento de ASLR

Adem谩s, posix_spawn permite especificar un array de posix_spawnattr que controla algunos aspectos del proceso generado, y posix_spawn_file_actions para modificar el estado de los descriptores.

Cuando un proceso muere, env铆a el c贸digo de retorno al proceso padre (si el padre muri贸, el nuevo padre es PID 1) con la se帽al SIGCHLD. El padre necesita obtener este valor llamando a wait4() o waitid() y hasta que eso suceda, el hijo permanece en un estado zombi donde todav铆a est谩 listado pero no consume recursos.

PIDs

Los PIDs, identificadores de procesos, identifican un proceso 煤nico. En XNU, los PIDs son de 64 bits aumentando monotonamente y nunca se envuelven (para evitar abusos).

Grupos de Procesos, Sesiones y Coaliciones

Los procesos pueden ser insertados en grupos para facilitar su manejo. Por ejemplo, los comandos en un script de shell estar谩n en el mismo grupo de procesos, por lo que es posible se帽alarlos juntos usando kill, por ejemplo.
Tambi茅n es posible agrupar procesos en sesiones. Cuando un proceso inicia una sesi贸n (setsid(2)), los procesos hijos se establecen dentro de la sesi贸n, a menos que inicien su propia sesi贸n.

La coalici贸n es otra forma de agrupar procesos en Darwin. Un proceso que se une a una coalici贸n le permite acceder a recursos compartidos, compartiendo un libro de contabilidad o enfrent谩ndose a Jetsam. Las coaliciones tienen diferentes roles: L铆der, servicio XPC, Extensi贸n.

Credenciales y Personas

Cada proceso tiene credenciales que identifican sus privilegios en el sistema. Cada proceso tendr谩 un uid primario y un gid primario (aunque puede pertenecer a varios grupos).
Tambi茅n es posible cambiar el id de usuario y el id de grupo si el binario tiene el bit setuid/setgid.
Hay varias funciones para establecer nuevos uids/gids.

La syscall persona proporciona un conjunto alternativo de credenciales. Adoptar una persona asume su uid, gid y membres铆as de grupo a la vez. En el c贸digo fuente es posible encontrar la estructura:

c
struct kpersona_info { uint32_t persona_info_version;
uid_t    persona_id; /* overlaps with UID */
int      persona_type;
gid_t    persona_gid;
uint32_t persona_ngroups;
gid_t    persona_groups[NGROUPS];
uid_t    persona_gmuid;
char     persona_name[MAXLOGNAME + 1];

/* TODO: MAC policies?! */
}

Informaci贸n B谩sica sobre Hilos

  1. Hilos POSIX (pthreads): macOS soporta hilos POSIX (pthreads), que son parte de una API est谩ndar de hilos para C/C++. La implementaci贸n de pthreads en macOS se encuentra en /usr/lib/system/libsystem_pthread.dylib, que proviene del proyecto libpthread disponible p煤blicamente. Esta biblioteca proporciona las funciones necesarias para crear y gestionar hilos.
  2. Creaci贸n de Hilos: La funci贸n pthread_create() se utiliza para crear nuevos hilos. Internamente, esta funci贸n llama a bsdthread_create(), que es una llamada al sistema de nivel inferior espec铆fica del n煤cleo XNU (el n煤cleo en el que se basa macOS). Esta llamada al sistema toma varios flags derivados de pthread_attr (atributos) que especifican el comportamiento del hilo, incluyendo pol铆ticas de programaci贸n y tama帽o de pila.
  • Tama帽o de Pila por Defecto: El tama帽o de pila por defecto para nuevos hilos es de 512 KB, lo cual es suficiente para operaciones t铆picas, pero puede ajustarse a trav茅s de atributos de hilo si se necesita m谩s o menos espacio.
  1. Inicializaci贸n de Hilos: La funci贸n __pthread_init() es crucial durante la configuraci贸n del hilo, utilizando el argumento env[] para analizar variables de entorno que pueden incluir detalles sobre la ubicaci贸n y tama帽o de la pila.

Terminaci贸n de Hilos en macOS

  1. Salida de Hilos: Los hilos se terminan t铆picamente llamando a pthread_exit(). Esta funci贸n permite que un hilo salga de manera limpia, realizando la limpieza necesaria y permitiendo que el hilo env铆e un valor de retorno a cualquier hilo que lo haya unido.
  2. Limpieza de Hilos: Al llamar a pthread_exit(), se invoca la funci贸n pthread_terminate(), que maneja la eliminaci贸n de todas las estructuras de hilo asociadas. Desasigna puertos de hilo Mach (Mach es el subsistema de comunicaci贸n en el n煤cleo XNU) y llama a bsdthread_terminate, una syscall que elimina las estructuras a nivel de n煤cleo asociadas con el hilo.

Mecanismos de Sincronizaci贸n

Para gestionar el acceso a recursos compartidos y evitar condiciones de carrera, macOS proporciona varias primitivas de sincronizaci贸n. Estas son cr铆ticas en entornos de m煤ltiples hilos para asegurar la integridad de los datos y la estabilidad del sistema:

  1. Mutexes:
  • Mutex Regular (Firma: 0x4D555458): Mutex est谩ndar con una huella de memoria de 60 bytes (56 bytes para el mutex y 4 bytes para la firma).
  • Mutex R谩pido (Firma: 0x4d55545A): Similar a un mutex regular pero optimizado para operaciones m谩s r谩pidas, tambi茅n de 60 bytes de tama帽o.
  1. Variables de Condici贸n:
  • Utilizadas para esperar a que ocurran ciertas condiciones, con un tama帽o de 44 bytes (40 bytes m谩s una firma de 4 bytes).
  • Atributos de Variable de Condici贸n (Firma: 0x434e4441): Atributos de configuraci贸n para variables de condici贸n, con un tama帽o de 12 bytes.
  1. Variable Once (Firma: 0x4f4e4345):
  • Asegura que un fragmento de c贸digo de inicializaci贸n se ejecute solo una vez. Su tama帽o es de 12 bytes.
  1. Bloqueos de Lectura-Escritura:
  • Permite m煤ltiples lectores o un escritor a la vez, facilitando el acceso eficiente a datos compartidos.
  • Bloqueo de Lectura-Escritura (Firma: 0x52574c4b): Tama帽o de 196 bytes.
  • Atributos de Bloqueo de Lectura-Escritura (Firma: 0x52574c41): Atributos para bloqueos de lectura-escritura, de 20 bytes de tama帽o.

tip

Los 煤ltimos 4 bytes de esos objetos se utilizan para detectar desbordamientos.

Variables Locales de Hilo (TLV)

Variables Locales de Hilo (TLV) en el contexto de archivos Mach-O (el formato para ejecutables en macOS) se utilizan para declarar variables que son espec铆ficas de cada hilo en una aplicaci贸n multihilo. Esto asegura que cada hilo tenga su propia instancia separada de una variable, proporcionando una forma de evitar conflictos y mantener la integridad de los datos sin necesidad de mecanismos de sincronizaci贸n expl铆citos como mutexes.

En C y lenguajes relacionados, puedes declarar una variable local de hilo utilizando la palabra clave __thread. Aqu铆 te mostramos c贸mo funciona en tu ejemplo:

c
cCopy code__thread int tlv_var;

void main (int argc, char **argv){
tlv_var = 10;
}

Este fragmento define tlv_var como una variable local de hilo. Cada hilo que ejecute este c贸digo tendr谩 su propio tlv_var, y los cambios que un hilo haga en tlv_var no afectar谩n a tlv_var en otro hilo.

En el binario Mach-O, los datos relacionados con las variables locales de hilo est谩n organizados en secciones espec铆ficas:

  • __DATA.__thread_vars: Esta secci贸n contiene los metadatos sobre las variables locales de hilo, como sus tipos y estado de inicializaci贸n.
  • __DATA.__thread_bss: Esta secci贸n se utiliza para variables locales de hilo que no est谩n expl铆citamente inicializadas. Es una parte de la memoria reservada para datos inicializados a cero.

Mach-O tambi茅n proporciona una API espec铆fica llamada tlv_atexit para gestionar variables locales de hilo cuando un hilo sale. Esta API permite registrar destructores鈥攆unciones especiales que limpian los datos locales de hilo cuando un hilo termina.

Prioridades de Hilo

Entender las prioridades de hilo implica observar c贸mo el sistema operativo decide qu茅 hilos ejecutar y cu谩ndo. Esta decisi贸n est谩 influenciada por el nivel de prioridad asignado a cada hilo. En macOS y sistemas similares a Unix, esto se maneja utilizando conceptos como nice, renice y clases de Calidad de Servicio (QoS).

Nice y Renice

  1. Nice:
  • El valor nice de un proceso es un n煤mero que afecta su prioridad. Cada proceso tiene un valor nice que var铆a de -20 (la prioridad m谩s alta) a 19 (la prioridad m谩s baja). El valor nice predeterminado cuando se crea un proceso es t铆picamente 0.
  • Un valor nice m谩s bajo (m谩s cercano a -20) hace que un proceso sea m谩s "ego铆sta", d谩ndole m谩s tiempo de CPU en comparaci贸n con otros procesos con valores nice m谩s altos.
  1. Renice:
  • renice es un comando utilizado para cambiar el valor nice de un proceso que ya se est谩 ejecutando. Esto se puede usar para ajustar din谩micamente la prioridad de los procesos, ya sea aumentando o disminuyendo su asignaci贸n de tiempo de CPU seg煤n nuevos valores nice.
  • Por ejemplo, si un proceso necesita m谩s recursos de CPU temporalmente, podr铆as bajar su valor nice usando renice.

Clases de Calidad de Servicio (QoS)

Las clases de QoS son un enfoque m谩s moderno para manejar las prioridades de hilo, particularmente en sistemas como macOS que soportan Grand Central Dispatch (GCD). Las clases de QoS permiten a los desarrolladores categorizar el trabajo en diferentes niveles seg煤n su importancia o urgencia. macOS gestiona la priorizaci贸n de hilos autom谩ticamente seg煤n estas clases de QoS:

  1. Interacci贸n del Usuario:
  • Esta clase es para tareas que est谩n interactuando actualmente con el usuario o requieren resultados inmediatos para proporcionar una buena experiencia de usuario. Estas tareas reciben la prioridad m谩s alta para mantener la interfaz receptiva (por ejemplo, animaciones o manejo de eventos).
  1. Iniciadas por el Usuario:
  • Tareas que el usuario inicia y espera resultados inmediatos, como abrir un documento o hacer clic en un bot贸n que requiere c谩lculos. Estas tienen alta prioridad pero por debajo de la interacci贸n del usuario.
  1. Utilidad:
  • Estas tareas son de larga duraci贸n y t铆picamente muestran un indicador de progreso (por ejemplo, descargar archivos, importar datos). Tienen menor prioridad que las tareas iniciadas por el usuario y no necesitan finalizar de inmediato.
  1. Fondo:
  • Esta clase es para tareas que operan en segundo plano y no son visibles para el usuario. Estas pueden ser tareas como indexaci贸n, sincronizaci贸n o copias de seguridad. Tienen la prioridad m谩s baja y un impacto m铆nimo en el rendimiento del sistema.

Usando clases de QoS, los desarrolladores no necesitan gestionar los n煤meros de prioridad exactos, sino que se centran en la naturaleza de la tarea, y el sistema optimiza los recursos de CPU en consecuencia.

Adem谩s, hay diferentes pol铆ticas de programaci贸n de hilos que fluyen para especificar un conjunto de par谩metros de programaci贸n que el programador tendr谩 en cuenta. Esto se puede hacer usando thread_policy_[set/get]. Esto podr铆a ser 煤til en ataques de condiciones de carrera.

Abuso de Procesos en MacOS

MacOS, como cualquier otro sistema operativo, proporciona una variedad de m茅todos y mecanismos para que los procesos interact煤en, se comuniquen y compartan datos. Si bien estas t茅cnicas son esenciales para el funcionamiento eficiente del sistema, tambi茅n pueden ser abusadas por actores maliciosos para realizar actividades maliciosas.

Inyecci贸n de Bibliotecas

La Inyecci贸n de Bibliotecas es una t茅cnica en la que un atacante fuerza a un proceso a cargar una biblioteca maliciosa. Una vez inyectada, la biblioteca se ejecuta en el contexto del proceso objetivo, proporcionando al atacante los mismos permisos y acceso que el proceso.

macOS Library Injection

Hooking de Funciones

El Hooking de Funciones implica interceptar llamadas a funciones o mensajes dentro de un c贸digo de software. Al enganchar funciones, un atacante puede modificar el comportamiento de un proceso, observar datos sensibles o incluso tomar control sobre el flujo de ejecuci贸n.

macOS Function Hooking

Comunicaci贸n entre Procesos

La Comunicaci贸n entre Procesos (IPC) se refiere a diferentes m茅todos por los cuales procesos separados comparten e intercambian datos. Si bien IPC es fundamental para muchas aplicaciones leg铆timas, tambi茅n puede ser mal utilizado para subvertir la aislamiento de procesos, filtrar informaci贸n sensible o realizar acciones no autorizadas.

macOS IPC - Inter Process Communication

Inyecci贸n de Aplicaciones Electron

Las aplicaciones Electron ejecutadas con variables de entorno espec铆ficas podr铆an ser vulnerables a la inyecci贸n de procesos:

macOS Electron Applications Injection

Inyecci贸n de Chromium

Es posible usar las banderas --load-extension y --use-fake-ui-for-media-stream para realizar un ataque man in the browser que permite robar pulsaciones de teclas, tr谩fico, cookies, inyectar scripts en p谩ginas...:

macOS Chromium Injection

NIB Sucio

Los archivos NIB definen elementos de interfaz de usuario (UI) y sus interacciones dentro de una aplicaci贸n. Sin embargo, pueden ejecutar comandos arbitrarios y Gatekeeper no detiene una aplicaci贸n ya ejecutada de ser ejecutada si un archivo NIB es modificado. Por lo tanto, podr铆an ser utilizados para hacer que programas arbitrarios ejecuten comandos arbitrarios:

macOS Dirty NIB

Inyecci贸n de Aplicaciones Java

Es posible abusar de ciertas capacidades de Java (como la variable de entorno _JAVA_OPTS) para hacer que una aplicaci贸n Java ejecute c贸digo/comandos arbitrarios.

macOS Java Applications Injection

Inyecci贸n de Aplicaciones .Net

Es posible inyectar c贸digo en aplicaciones .Net abusando de la funcionalidad de depuraci贸n de .Net (no protegida por las protecciones de macOS como el endurecimiento en tiempo de ejecuci贸n).

macOS .Net Applications Injection

Inyecci贸n de Perl

Consulta diferentes opciones para hacer que un script de Perl ejecute c贸digo arbitrario en:

macOS Perl Applications Injection

Inyecci贸n de Ruby

Tambi茅n es posible abusar de las variables de entorno de Ruby para hacer que scripts arbitrarios ejecuten c贸digo arbitrario:

macOS Ruby Applications Injection

Inyecci贸n de Python

Si la variable de entorno PYTHONINSPECT est谩 configurada, el proceso de Python caer谩 en un CLI de Python una vez que haya terminado. Tambi茅n es posible usar PYTHONSTARTUP para indicar un script de Python que se ejecute al comienzo de una sesi贸n interactiva.
Sin embargo, ten en cuenta que el script PYTHONSTARTUP no se ejecutar谩 cuando PYTHONINSPECT cree la sesi贸n interactiva.

Otras variables de entorno como PYTHONPATH y PYTHONHOME tambi茅n podr铆an ser 煤tiles para hacer que un comando de Python ejecute c贸digo arbitrario.

Ten en cuenta que los ejecutables compilados con pyinstaller no usar谩n estas variables ambientales incluso si se est谩n ejecutando usando un Python embebido.

caution

En general, no pude encontrar una manera de hacer que Python ejecute c贸digo arbitrario abusando de variables de entorno.
Sin embargo, la mayor铆a de las personas instalan Python usando Homebrew, que instalar谩 Python en una ubicaci贸n escribible para el usuario administrador predeterminado. Puedes secuestrarlo con algo como:

mv /opt/homebrew/bin/python3 /opt/homebrew/bin/python3.old
cat > /opt/homebrew/bin/python3 <<EOF
#!/bin/bash
# C贸digo de secuestro adicional
/opt/homebrew/bin/python3.old "$@"
EOF
chmod +x /opt/homebrew/bin/python3

Incluso root ejecutar谩 este c贸digo al ejecutar Python.

Detecci贸n

Shield

Shield (Github) es una aplicaci贸n de c贸digo abierto que puede detectar y bloquear acciones de inyecci贸n de procesos:

  • Usando Variables Ambientales: Monitorear谩 la presencia de cualquiera de las siguientes variables ambientales: DYLD_INSERT_LIBRARIES, CFNETWORK_LIBRARY_PATH, RAWCAMERA_BUNDLE_PATH y ELECTRON_RUN_AS_NODE
  • Usando llamadas task_for_pid: Para encontrar cu谩ndo un proceso quiere obtener el puerto de tarea de otro que permite inyectar c贸digo en el proceso.
  • Par谩metros de aplicaciones Electron: Alguien puede usar los argumentos de l铆nea de comando --inspect, --inspect-brk y --remote-debugging-port para iniciar una aplicaci贸n Electron en modo de depuraci贸n, y as铆 inyectar c贸digo en ella.
  • Usando symlinks o hardlinks: T铆picamente, el abuso m谩s com煤n es colocar un enlace con nuestros privilegios de usuario, y apuntarlo a una ubicaci贸n de mayor privilegio. La detecci贸n es muy simple tanto para hardlinks como para symlinks. Si el proceso que crea el enlace tiene un nivel de privilegio diferente al del archivo objetivo, creamos una alerta. Desafortunadamente, en el caso de symlinks, el bloqueo no es posible, ya que no tenemos informaci贸n sobre el destino del enlace antes de su creaci贸n. Esta es una limitaci贸n del marco de EndpointSecurity de Apple.

Llamadas realizadas por otros procesos

En esta publicaci贸n de blog puedes encontrar c贸mo es posible usar la funci贸n task_name_for_pid para obtener informaci贸n sobre otros procesos que inyectan c贸digo en un proceso y luego obtener informaci贸n sobre ese otro proceso.

Ten en cuenta que para llamar a esa funci贸n necesitas ser el mismo uid que el que ejecuta el proceso o root (y devuelve informaci贸n sobre el proceso, no una forma de inyectar c贸digo).

Referencias

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