¿Es posible vincular la ejecución de un script en cada creación de proceso?
Esencialmente el equivalente de inotifywait para monitorear la actividad del disco pero aplicado a la tabla de procesos.
Sería para permitir realizar una acción al generar los procesos, por ejemplo, iniciar sesión, configurarlo, etc. Puedo ver el desafío que se aplicaría de forma recursiva en los nuevos procesos. Pero en lugar de sondear la mesa de proceso lo más rápido posible para detectar cambios que serían vulnerables a las condiciones raciales, ¿existe una mejor manera?
Gracias
Respuesta1
En primer lugar, la creación de procesos rara vez es un evento útil para registrar y es irrelevante para la seguridad (excepto para la limitación de recursos). Creo que te refieres a enganchar la ejecución de programas, lo cual se realiza medianteexecve
, nofork
.
En segundo lugar, los casos de uso que usted cita generalmente se solucionan mejor utilizando un mecanismo existente creado para ese propósito, en lugar de implementar el suyo propio.
- Para iniciar sesión,contabilidad de procesos BSDproporciona una pequeña cantidad de información y está disponible en la mayoría de las variantes de Unix; en Linux, instale elUtilidades de contabilidad GNU(instala el paquete de tu distribución). Para un registro más sofisticado en Linux, puede utilizar elsubsistema de auditoría(el
auditctl
la página de manual tiene ejemplos; como expliqué anteriormente, la llamada al sistema que querrás registrar esexecve
). - Si desea aplicar restricciones de seguridad a ciertos programas, utilice un marco de seguridad comoSELinuxoArmadura de aplicaciones.
- Si desea ejecutar un programa específico en un contenedor, o con ciertas configuraciones, mueva el ejecutable y coloque en su lugar un script contenedor que establezca las configuraciones que desea y llame al ejecutable original.
Si desea modificar la forma en que un programa específico llama a otros programas, sin afectar el comportamiento de otros programas, hay dos casos: o el programa es potencialmente hostil o no.
- Si el programa es potencialmente hostil, ejecútelo en una máquina virtual dedicada.
- Si el programa es cooperativo, el ángulo de ataque más obvio es ejecutarlo con un archivo
PATH
. Si el programa utiliza rutas absolutas que no son fáciles de configurar, en un sistema Linux no antiguo, puede ejecutarlo en una ruta separada.montar espacio de nombres(ver tambiénkernel: soporte de espacios de nombres). Si realmente necesita un control preciso, puede cargar una biblioteca que anule algunas llamadas a la biblioteca invocando el programa conLD_PRELOAD=my_override_library.so theprogram
. VerRedirigir un descriptor de archivo antes de la ejecuciónpara un ejemplo. Tenga en cuenta que, además deexecve
, deberá anular todas las funciones de la biblioteca C que llamanexecve
internamente, porqueLD_PRELOAD
no afecta las llamadas internas de la biblioteca C. Puede obtener un control más preciso ejecutando el programa enptrace
; esto le permite anular una llamada al sistema incluso si se realiza mediante una función de biblioteca C, pero es más difícil de configurar (no conozco ninguna manera fácil de hacerlo).
Respuesta2
//fakeExec.c
#include <unistd.h>
#include <stdio.h>
#include <sys/syscall.h>
int execve(const char *path, char *const argv[], char *const envp[]) {
printf("Execing \"%s\"\n", path);
return syscall(SYS_execve, path, argv, envp);
}
En la terminal:
$ gcc -fPIC -shared fakeExec.c -o fakeExec.so
$ export LD_PRELOAD=$PWD/fakeExec.so
Y ahora debería registrar cada nuevo archivo ejecutado en stdout
.
Aparentemente, un envoltorio de tenedor requeriría un poco más de trabajo para hacerlo bien.
fork
(El contenedor trivial (como el anterior, pero en fork
lugar de execve
) funciona en cierto modo, pero genera algunos setgpid
errores en los procesos generados con él.
Aparentemente, la libc fork
funciona con algunas cosas adicionales, que no entiendo del todo. )