Pregunta

Además del truco LD_PRELOAD y los módulos del kernel de Linux que reemplazan una determinada llamada al sistema con una proporcionada por usted, ¿existe alguna posibilidad de interceptar una llamada al sistema (abierta por ejemplo), de modo que primero pase por su función, antes de llegar a la apertura real?

¿Fue útil?

Solución

Si realmente necesita una solución, es posible que le interese el rootkit DR que logra precisamente esto. http://www.immunityinc.com/downloads/linux_rootkit_source.tbz2 el artículo al respecto está aquí http://www.theregister.co.uk/2008/09/04/linux_rootkit_released/

Otros consejos

¿Por qué no puedes o no quieres utilizar el Truco LD_PRELOAD?

Código de ejemplo aquí:

/*
 * File: soft_atimes.c
 * Author: D.J. Capelis
 *
 * Compile:
 * gcc -fPIC -c -o soft_atimes.o soft_atimes.c
 * gcc -shared -o soft_atimes.so soft_atimes.o -ldl
 *
 * Use:
 * LD_PRELOAD="./soft_atimes.so" command
 *
 * Copyright 2007 Regents of the University of California
 */

#define _GNU_SOURCE
#include <dlfcn.h>
#define _FCNTL_H
#include <bits/fcntl.h>

extern int errorno;

int (*_open)(const char * pathname, int flags, ...);
int (*_open64)(const char * pathname, int flags, ...);

int open(const char * pathname, int flags, mode_t mode)
{
    _open = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open");
    if(flags & O_CREAT)
        return _open(pathname, flags | O_NOATIME, mode);
    else
        return _open(pathname, flags | O_NOATIME, 0);
}

int open64(const char * pathname, int flags, mode_t mode)
{
    _open64 = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open64");
    if(flags & O_CREAT)
        return _open64(pathname, flags | O_NOATIME, mode);
    else
        return _open64(pathname, flags | O_NOATIME, 0);
}

Por lo que tengo entendido...es más o menos el truco LD_PRELOAD o un módulo del kernel.No hay mucho término medio a menos que desee ejecutarlo en un emulador que pueda capturar su función o reescribir el código en el binario real para capturar su función.

Suponiendo que no puede modificar el programa y no puede (o no quiere) modificar el kernel, el enfoque LD_PRELOAD es el mejor, asumiendo que su aplicación es bastante estándar y en realidad no intenta pasar maliciosamente tu intercepción.(En cuyo caso necesitará una de las otras técnicas).

Valgrind se puede utilizar para interceptar cualquier llamada de función.Si necesita interceptar una llamada al sistema en su producto terminado, esto no servirá de nada.Sin embargo, si intenta interceptar durante el desarrollo, puede resultar muy útil.Con frecuencia he utilizado esta técnica para interceptar funciones hash de modo que pueda controlar el hash devuelto con fines de prueba.

En caso de que no lo sepas, Valgrind se utiliza principalmente para encontrar pérdidas de memoria y otros errores relacionados con la memoria.Pero la tecnología subyacente es básicamente un emulador x86.Emula su programa e intercepta llamadas a malloc/free, etc.Lo bueno es que no es necesario volver a compilar para usarlo.

Valgrind tiene una característica que ellos denominan Envoltura de funciones, que se utiliza para controlar la interceptación de funciones.Véase la sección 3.2 del manual de valgrind para detalles.Puede configurar el ajuste de funciones para cualquier función que desee.Una vez que se intercepta la llamada, se invoca la función alternativa que usted proporciona.

Algunas aplicaciones pueden engañar a strace/ptrace para que no se ejecute, por lo que la única opción real que he tenido es usar systemtap.

Systemtap puede interceptar un montón de llamadas al sistema si es necesario debido a su coincidencia de comodines.Systemtap no es C, sino un lenguaje independiente.En el modo básico, systemtap debería impedirle hacer cosas estúpidas, pero también puede ejecutarse en "modo experto" que permite a un desarrollador usar C si es necesario.

No requiere que apliques un parche a tu kernel (o al menos no debería hacerlo), y una vez que se ha compilado un módulo, puedes copiarlo desde un cuadro de prueba/desarrollo e insertarlo (a través de insmod) en un sistema de producción.

Todavía tengo que encontrar una aplicación de Linux que haya encontrado una manera de solucionar/evitar ser atrapado por systemtap.

Si solo quieres mirar lo que se abre, desea ver la función ptrace() o el código fuente de la utilidad strace de línea de comandos.Si realmente quieres interceptar la llamada, para tal vez hacer otra cosa, creo que las opciones que enumeró (LD_PRELOAD o un módulo del kernel) son sus únicas opciones.

No tengo la sintaxis para hacer esto correctamente con un LKM de improviso, pero este artículo proporciona una buena descripción general de lo que deberías hacer: http://www.linuxjournal.com/article/4378

También puedes simplemente parchear la función sys_open.Comienza en la línea 1084 del archivo/open.c a partir de linux-2.6.26.

También puede ver si no puede usar inotify, systemtap o SELinux para realizar todo este registro por usted sin tener que crear un nuevo sistema.

Si solo desea hacerlo con fines de depuración, consulte strace, que está integrado en la parte superior de la llamada al sistema ptrace(2) y le permite conectar el código cuando se realiza una llamada al sistema.Consulte la parte PTRACE_SYSCALL de la página de manual.

Parece que necesitas una auditoría.

Auditd permite el seguimiento global de todas las llamadas al sistema o accesos a archivos, con registro.Puede configurar claves para eventos específicos que le interesen.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top