/proc permite inspeccionar directamente buena parte del estado que mantiene el kernel de Linux sobre procesos, memoria, red, namespaces y parámetros de seguridad. Para un administrador de sistemas puede ser especialmente útil cuando necesita auditar rápidamente un servidor, investigar un proceso extraño o comprobar el hardening sin depender exclusivamente de herramientas de nivel superior. A las 18 comprobaciones habituales se pueden añadir dos especialmente útiles en sistemas actuales: revisar NoNewPrivs y Seccomp.
Las claves de /proc para seguridad en 20 segundos
/procofrece información en tiempo real proporcionada por el kernel sobre procesos y configuración.- Permite revisar ASLR, capacidades, namespaces,
ptrace, Seccomp y protecciones del sistema. - También ayuda a detectar ejecutables borrados, memoria RWX, listeners inesperados y variables de entorno sospechosas.
- Un resultado extraño es un indicador para investigar, no una prueba automática de compromiso.
Conviene hacer una precisión antes de empezar. Herramientas como ps, ss, sysctl, lsns, lsof, getpcaps o un EDR resultan normalmente más cómodas para el trabajo diario. Muchas obtienen precisamente parte de su información desde /proc u otras interfaces del kernel.
Consultar /proc directamente tiene otra utilidad: permite entender qué está viendo realmente Linux y contrastar el resultado de las herramientas habituales.
Procesos y memoria: siete comprobaciones rápidas
1. Comprobar que ASLR está activo
Address Space Layout Randomization (ASLR) dificulta determinados ataques de corrupción de memoria al aleatorizar las posiciones utilizadas por ejecutables, bibliotecas, stack, heap y otras regiones.
cat /proc/sys/kernel/randomize_va_space
Los valores posibles son:
0 ASLR desactivado
1 Aleatorización parcial
2 Aleatorización completa
En un servidor convencional debería investigarse por qué aparece un 0.
Para comprobar el valor persistente también puede utilizarse:
sysctl kernel.randomize_va_space
Lenguaje del código: CSS (css)
Modificar parámetros directamente en /proc/sys afecta al sistema en ejecución, pero el cambio no necesariamente sobrevivirá al reinicio. La configuración permanente suele gestionarse mediante /etc/sysctl.conf o archivos de /etc/sysctl.d/.
2. Localizar procesos ejecutándose como root
Linux expone los UID real, efectivo, guardado y de sistema de archivos de cada proceso en /proc/<PID>/status.
grep -H "^Uid:" /proc/[0-9]*/status 2>/dev/null |
grep -E "Uid:[[:space:]]+0[[:space:]]"
Lenguaje del código: JavaScript (javascript)
Que existan procesos con UID 0 es completamente normal. systemd y numerosos servicios del sistema necesitan privilegios.
Lo interesante es encontrar procesos que no deberían ejecutarse como root.
Para identificar rápidamente uno de los PID encontrados:
ps -fp <PID>
Lenguaje del código: HTML, XML (xml)
El administrador debería contrastarlo también con la unidad de systemd, paquete instalado, ejecutable y árbol de procesos correspondiente.
3. Buscar ejecutables borrados que siguen funcionando
Una comprobación especialmente útil durante una investigación:
find /proc/[0-9]*/exe -lname '* (deleted)' -ls 2>/dev/null
Lenguaje del código: JavaScript (javascript)
Linux puede mantener un proceso funcionando después de eliminar del sistema de archivos su ejecutable.
Esto sucede legítimamente después de determinadas actualizaciones. Un daemon puede estar ejecutando todavía la versión anterior de una biblioteca o binario hasta que sea reiniciado.
Pero algo como:
/proc/4281/exe -> /tmp/.update (deleted)
Lenguaje del código: JavaScript (javascript)
merece bastante más atención.
Conviene comprobar:
ps -fp 4281
readlink /proc/4281/exe
ls -l /proc/4281/fd
Un archivo eliminado no significa malware. Un ejecutable inesperado y eliminado es un indicador que necesita contexto.
4. Revisar las capabilities de un proceso
Las Linux capabilities permiten dividir los privilegios tradicionales de root en permisos más concretos.
grep '^Cap' /proc/<PID>/status
Lenguaje del código: JavaScript (javascript)
El resultado incluye:
CapInh
CapPrm
CapEff
CapBnd
CapAmb
Las máscaras hexadecimales pueden decodificarse con:
capsh --decode=<valor>
Lenguaje del código: HTML, XML (xml)
También pueden utilizarse herramientas como:
getpcaps <PID>
Lenguaje del código: HTML, XML (xml)
Especialmente sensibles son capacidades como:
CAP_SYS_ADMIN
CAP_SYS_PTRACE
CAP_SYS_MODULE
CAP_SYS_RAWIO
CAP_NET_ADMIN
CAP_DAC_OVERRIDE
CAP_SYS_ADMIN merece particular atención por el amplio conjunto de operaciones privilegiadas que engloba.
El objetivo de una auditoría no debería ser simplemente buscar capabilities, sino responder a una pregunta: ¿necesita realmente este servicio estos privilegios para funcionar?
5. Buscar regiones de memoria RWX
Las regiones simultáneamente escribibles y ejecutables pueden localizarse mediante:
grep -E '^[0-9a-f]+-[0-9a-f]+ rwx' /proc/<PID>/maps
Lenguaje del código: JavaScript (javascript)
Una política W^X intenta evitar que una misma región sea escribible y ejecutable al mismo tiempo.
Encontrar RWX no demuestra una explotación. Máquinas virtuales, motores JIT y determinado software pueden generar mapeos de este tipo.
Pero en un proceso que no debería crear código dinámicamente merece una revisión.
6. Comprobar si un proceso está siendo trazado
/proc/<PID>/status también indica si otro proceso está utilizando mecanismos de trazado sobre él:
grep '^TracerPid:' /proc/<PID>/status
Lenguaje del código: JavaScript (javascript)
El resultado habitual es:
TracerPid: 0
Un valor diferente de cero identifica al proceso trazador. El manual de Linux confirma que TracerPid contiene precisamente ese PID.
Puede investigarse mediante:
ps -fp <TracerPID>
readlink /proc/<TracerPID>/exe
Lenguaje del código: HTML, XML (xml)
strace, gdb, depuradores, herramientas de observabilidad y determinados agentes de seguridad pueden justificar el resultado.
Si nadie debería estar depurando ese proceso, conviene averiguar quién lo está haciendo.
7. Comparar comm, cmdline y exe
Un proceso tiene varias identidades visibles desde /proc:
cat /proc/<PID>/comm
tr '\0' ' ' < /proc/<PID>/cmdline
echo
readlink /proc/<PID>/exe
Lenguaje del código: PHP (php)
Un ejemplo extraño podría ser:
comm: kworker
cmdline: /tmp/.cache/python /tmp/.cache/update.py
exe: /usr/bin/python3.13
Lenguaje del código: HTTP (http)
No debe automatizarse una regla que considere cualquier diferencia como maliciosa. Intérpretes, scripts, wrappers, nombres modificados por la propia aplicación y el límite de longitud de comm pueden producir discrepancias legítimas.
La comprobación sirve para detectar procesos que merecen ser explicados, no para clasificarlos automáticamente como malware.
Privilegios, aislamiento y contenedores
8. Revisar ptrace_scope
Yama puede limitar qué procesos tienen permiso para utilizar ptrace:
cat /proc/sys/kernel/yama/ptrace_scope
Sus cuatro niveles son:
0 Permisos ptrace clásicos
1 ptrace restringido
2 Solo procesos con CAP_SYS_PTRACE
3 ptrace deshabilitado
El nivel 1 restringe por defecto PTRACE_ATTACH a relaciones previamente permitidas, normalmente descendientes, además de las comprobaciones de permisos habituales. El nivel 2 exige CAP_SYS_PTRACE.
El nivel 3 es especialmente restrictivo: una vez establecido no puede cambiarse durante esa sesión de arranque.
Por eso no debería recomendarse cambiar este parámetro a ciegas en producción. Puede romper depuración, diagnóstico y determinados agentes.
9. Revisar el namespace PID
Para saber en qué PID namespace se encuentra un proceso:
readlink /proc/<PID>/ns/pid
Lenguaje del código: HTML, XML (xml)
Por ejemplo:
pid:[4026532921]
Lenguaje del código: CSS (css)
Puede compararse con PID 1:
readlink /proc/1/ns/pid
readlink /proc/<PID>/ns/pid
Lenguaje del código: HTML, XML (xml)
Identificadores diferentes indican namespaces diferentes.
En servidores Docker, Podman, Kubernetes o LXC resulta útil para comprobar el aislamiento esperado entre procesos.
10. Revisar root y cgroup
Dos comprobaciones adicionales ayudan a determinar el entorno en el que se ejecuta un proceso:
readlink /proc/<PID>/root
cat /proc/<PID>/cgroup
Lenguaje del código: HTML, XML (xml)
En un sistema con contenedores la información puede ayudar a relacionar un PID del host con su contenedor.
Pero hay que evitar una interpretación frecuente: encontrar / en determinados contextos no demuestra un container escape.
Namespaces, configuración del runtime, montajes y cgroups deben analizarse conjuntamente.
11. Revisar NoNewPrivs
Esta es una de las dos comprobaciones que merece la pena añadir a la lista original.
grep '^NoNewPrivs:' /proc/<PID>/status
Lenguaje del código: JavaScript (javascript)
El kernel expone este estado directamente dentro de /proc/<PID>/status.
Cuando no_new_privs está establecido, execve() no puede conceder al proceso nuevos privilegios mediante mecanismos como bits set-user-ID/set-group-ID o capabilities de archivo.
Resulta especialmente interesante al auditar servicios y contenedores que deberían ejecutarse bajo políticas restrictivas.
En systemd puede aparecer relacionado con configuraciones como:
NoNewPrivileges=yes
No todos los procesos necesitan tenerlo activo. Su ausencia tampoco constituye una vulnerabilidad automática.
12. Comprobar Seccomp
La segunda incorporación mejora especialmente la utilidad de la lista para contenedores y servicios modernos:
grep -E '^(Seccomp|Seccomp_filters):' /proc/<PID>/status
Lenguaje del código: JavaScript (javascript)
Los valores de Seccomp son:
0 SECCOMP_MODE_DISABLED
1 SECCOMP_MODE_STRICT
2 SECCOMP_MODE_FILTER
El kernel también puede mostrar Seccomp_filters, que indica el número de filtros conectados al proceso. Estos campos están documentados en /proc/<PID>/status.
Seccomp permite restringir las llamadas al sistema que puede realizar un proceso.
En un servidor con contenedores resulta especialmente interesante comparar procesos:
grep -E '^(Name|Pid|NoNewPrivs|Seccomp|Seccomp_filters):' /proc/<PID>/status
Lenguaje del código: JavaScript (javascript)
Así puede verificarse si el proceso que se suponía confinado realmente tiene filtros Seccomp activos.
Red, kernel y persistencia: ocho controles más
13. Revisar variables de entorno sospechosas
Las variables del proceso están disponibles en:
tr '\0' '\n' < /proc/<PID>/environ
Lenguaje del código: JavaScript (javascript)
Para una revisión rápida:
tr '\0' '\n' < /proc/<PID>/environ |
grep -E '^(LD_PRELOAD|LD_LIBRARY_PATH|HTTP_PROXY|HTTPS_PROXY|ALL_PROXY|NO_PROXY)='
Lenguaje del código: JavaScript (javascript)
Un LD_PRELOAD inesperado merece atención porque puede provocar la carga de bibliotecas adicionales.
También interesa revisar proxies desconocidos que puedan modificar el destino del tráfico.
Hay que tener en cuenta los permisos: el acceso a determinados archivos de /proc/<PID> está sujeto a controles de seguridad y no cualquier usuario puede inspeccionar libremente los procesos de otros usuarios.
14. Buscar listeners directamente en /proc/net/tcp
Los sockets TCP IPv4 pueden examinarse mediante:
cat /proc/net/tcp
Para mostrar los que están en estado LISTEN:
awk '$4 == "0A"' /proc/net/tcp
Lenguaje del código: JavaScript (javascript)
Los puertos aparecen en hexadecimal.
Por ejemplo:
0016
equivale al puerto decimal 22.
En administración diaria será mucho más cómodo:
ss -lntp
Pero /proc/net/tcp resulta útil para comprender de dónde obtiene Linux parte de esta información y para investigaciones de bajo nivel.
También existe:
/proc/net/tcp6
para IPv6.
15. Revisar los parámetros de arranque del kernel
cat /proc/cmdline
El administrador debería buscar parámetros relacionados con las políticas de seguridad de su distribución y servidor, por ejemplo:
lockdown=
selinux=
apparmor=
mitigations=
pti=
vsyscall=
Especialmente preocupantes son modificaciones inesperadas que deshabiliten mitigaciones que deberían estar activas.
No existe una línea de comandos universalmente correcta: depende del kernel, distribución, arquitectura y política de hardening.
16. Revisar los módulos del kernel cargados
cat /proc/modules
Una alternativa más legible es:
lsmod
Durante una investigación interesa localizar módulos desconocidos o inesperados y comprobar su procedencia.
Por ejemplo:
modinfo <modulo>
Lenguaje del código: HTML, XML (xml)
Un módulo del kernel opera con un nivel de privilegio muy elevado. Por eso un módulo que nadie puede relacionar con el hardware, software o configuración del servidor requiere atención.
17. Comprobar kptr_restrict
cat /proc/sys/kernel/kptr_restrict
Este parámetro limita la exposición de direcciones de punteros del kernel mediante interfaces como /proc/kallsyms.
El valor 2 aplica la restricción más fuerte de las opciones disponibles.
Puede consultarse igualmente con:
sysctl kernel.kptr_restrict
Lenguaje del código: CSS (css)
Antes de modificarlo conviene comprobar los requisitos de observabilidad, depuración y herramientas utilizadas en el servidor.
18. Restringir el acceso a dmesg
cat /proc/sys/kernel/dmesg_restrict
Con:
1
el acceso al registro del kernel queda restringido según los controles de privilegios correspondientes.
dmesg puede revelar información interesante para un atacante: hardware, errores, controladores y, dependiendo de la configuración y versión, otros datos internos del kernel.
19. Comprobar la protección de hardlinks
cat /proc/sys/fs/protected_hardlinks
Con valor 1, Linux restringe la creación de hardlinks hacia archivos que el usuario no posee salvo determinadas condiciones.
Esta protección busca reducir una clase histórica de ataques basada en condiciones de carrera y enlaces duros, especialmente en directorios compartidos. La documentación oficial del kernel describe precisamente este objetivo.
20. Revisar symlinks y completar el hardening de /tmp
La comprobación original termina con:
cat /proc/sys/fs/protected_symlinks
Un valor 1 habilita restricciones destinadas a reducir ataques basados en enlaces simbólicos dentro de directorios sticky y escribibles por múltiples usuarios.
Pero un sysadmin actual debería aprovechar esta revisión para comprobar también:
sysctl fs.protected_symlinks
sysctl fs.protected_hardlinks
sysctl fs.protected_fifos
sysctl fs.protected_regular
Lenguaje del código: CSS (css)
Los dos últimos son especialmente interesantes y con frecuencia quedan fuera de las listas antiguas de hardening.
protected_fifos busca evitar escrituras accidentales sobre una FIFO controlada por otro usuario cuando una aplicación esperaba crear un archivo.
protected_regular aplica una idea equivalente a archivos normales en directorios sticky escribibles por varios usuarios. Ambos parámetros están documentados por el propio kernel.
En sistemas que los soporten merece la pena revisar los cuatro conjuntamente.
Un chequeo rápido de /proc para guardar en favoritos
Para una primera fotografía del servidor pueden agruparse varios controles no destructivos:
echo '=== ASLR ==='
cat /proc/sys/kernel/randomize_va_space
echo '=== Yama ptrace ==='
cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null || echo "Yama no disponible"
echo '=== Kernel pointers ==='
cat /proc/sys/kernel/kptr_restrict
echo '=== dmesg ==='
cat /proc/sys/kernel/dmesg_restrict
echo '=== Hardlinks ==='
cat /proc/sys/fs/protected_hardlinks
echo '=== Symlinks ==='
cat /proc/sys/fs/protected_symlinks
echo '=== FIFOs ==='
cat /proc/sys/fs/protected_fifos 2>/dev/null
echo '=== Regular files ==='
cat /proc/sys/fs/protected_regular 2>/dev/null
echo '=== Deleted executables ==='
find /proc/[0-9]*/exe -lname '* (deleted)' -ls 2>/dev/null
Lenguaje del código: PHP (php)
No conviene convertir esta salida en un sistema binario de aprobado o suspenso.
El hardening real depende de la distribución, kernel, función del servidor, aplicaciones, contenedores y modelo de amenazas. Incluso controles recomendables pueden interferir con herramientas legítimas.
Hay otra mejora interesante para servidores multiusuario: comprobar cómo está montado /proc.
findmnt -no TARGET,FSTYPE,OPTIONS /proc
Linux soporta la opción hidepid, que permite limitar la información de los procesos que otros usuarios pueden consultar dentro de /proc. Con hidepid=1, por ejemplo, un usuario pierde acceso a archivos sensibles dentro de los directorios /proc/<PID> de otros usuarios.
No se incluye como uno de los 20 controles porque no es estrictamente una consulta a un archivo de /proc, pero merece incorporarse a cualquier revisión seria de un servidor Linux compartido.
La mejor forma de utilizar estas comprobaciones tampoco es ejecutarlas una vez y olvidar el resultado. Lo realmente útil es conocer el estado normal del servidor y detectar desviaciones.
Un proceso con una capability elevada puede ser legítimo. Un binario eliminado puede proceder de una actualización. Un listener nuevo puede corresponder a un servicio recién desplegado.
La situación cambia cuando aparecen varias señales simultáneamente: un proceso desconocido iniciado como root, ejecutable borrado bajo /tmp, LD_PRELOAD inesperado, capabilities elevadas y un socket escuchando en un puerto que no figura en el inventario.
Ahí /proc deja de ser simplemente una curiosidad del kernel y se convierte en una herramienta muy práctica para empezar una investigación.
Preguntas frecuentes
¿Qué es /proc en Linux?
/proc es un sistema de archivos virtual mediante el que el kernel expone información sobre procesos y diferentes parámetros del sistema. Los directorios /proc/<PID> proporcionan información específica de cada proceso.
¿Qué comprobaciones de /proc son más útiles durante un incidente?
Los ejecutables eliminados, cmdline, exe, capabilities, TracerPid, mapas de memoria, variables de entorno, namespaces y sockets pueden proporcionar rápidamente contexto sobre un proceso sospechoso. Conviene correlacionarlos con logs, systemd, paquetes, conexiones y herramientas de seguridad.
¿Cómo saber si un proceso Linux utiliza Seccomp?
Puede ejecutarse grep -E '^(Seccomp|Seccomp_filters):' /proc/<PID>/status. Un valor Seccomp: 2 indica que el proceso funciona en modo de filtros Seccomp.
¿Es suficiente revisar /proc para auditar la seguridad de Linux?
No. /proc proporciona una excelente vista del estado actual del kernel, pero una auditoría completa debe incluir permisos, usuarios, systemd, paquetes, logs, firewall, SSH, MAC como SELinux o AppArmor, integridad, actualizaciones, configuración de red y otros controles.
Fuentes:
- Linux Kernel Documentation, documentación oficial de
/proc/sys/fs/. - Linux Kernel Documentation, Yama Linux Security Module y
ptrace_scope. - Linux man-pages,
proc(5),proc_pid(5),proc_pid_status(5)ycapabilities(7). - Artículo de partida sobre 18 comprobaciones de seguridad mediante
/proc.







