Pergunta

Além do truque LD_PRELOAD e dos módulos do kernel do Linux que substituem um determinado syscall por um fornecido por você, existe alguma possibilidade de interceptar um syscall (aberto, por exemplo), para que ele passe primeiro pela sua função, antes de atingir a abertura real?

Foi útil?

Solução

se você realmente precisa de uma solução, pode estar interessado no rootkit DR que faz exatamente isso, http://www.immunityinc.com/downloads/linux_rootkit_source.tbz2 o artigo sobre isso está aqui http://www.theregister.co.uk/2008/09/04/linux_rootkit_released/

Outras dicas

Por que você não pode/não quer usar o Truque LD_PRELOAD?

Código de exemplo aqui:

/*
 * 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);
}

Pelo que entendi...é basicamente o truque LD_PRELOAD ou um módulo do kernel.Não há muito meio-termo, a menos que você queira executá-lo em um emulador que possa capturar sua função ou reescrever o código no binário real para capturar sua função.

Supondo que você não possa modificar o programa e não possa (ou não queira) modificar o kernel, a abordagem LD_PRELOAD é a melhor, assumindo que seu aplicativo seja bastante padrão e não seja realmente um que esteja tentando passar maliciosamente. sua interceptação.(Nesse caso, você precisará de uma das outras técnicas.)

Valgrind pode ser usado para interceptar qualquer chamada de função.Se você precisar interceptar uma chamada do sistema em seu produto final, isso não adiantará.No entanto, se você tentar interceptar durante o desenvolvimento, isso pode ser muito útil.Tenho usado frequentemente essa técnica para interceptar funções de hash para poder controlar o hash retornado para fins de teste.

Caso você não saiba, Valgrind é usado principalmente para localizar vazamentos de memória e outros erros relacionados à memória.Mas a tecnologia subjacente é basicamente um emulador x86.Ele emula seu programa e intercepta chamadas para malloc/free etc.O bom é que você não precisa recompilar para usá-lo.

Valgrind tem um recurso que eles chamam Envolvimento de Função, que é usado para controlar a interceptação de funções.Consulte a seção 3.2 do Manual do Valgrind para detalhes.Você pode configurar o agrupamento de funções para qualquer função que desejar.Depois que a chamada for interceptada, a função alternativa fornecida será invocada.

Alguns aplicativos podem enganar o strace/ptrace para não ser executado, então a única opção real que tive é usar o systemtap

O Systemtap pode interceptar várias chamadas do sistema, se necessário, devido à correspondência de curinga.Systemtap não é C, mas uma linguagem separada.No modo básico, o systemtap deve impedir que você faça coisas estúpidas, mas também pode ser executado no "modo especialista", que permite que um desenvolvedor use C, se necessário.

Não requer que você corrija seu kernel (ou pelo menos não deveria), e uma vez que um módulo tenha sido compilado, você pode copiá-lo de uma caixa de teste/desenvolvimento e inseri-lo (via insmod) em um sistema de produção.

Ainda não encontrei um aplicativo Linux que tenha encontrado uma maneira de contornar/evitar ser pego pelo systemtap.

Se você apenas quiser assistir o que está aberto, você deseja examinar a função ptrace() ou o código-fonte do utilitário strace de linha de comando.Se você realmente quiser interceptar a chamada, para talvez fazer outra coisa, acho que as opções que você listou - LD_PRELOAD ou um módulo do kernel - são suas únicas opções.

Não tenho a sintaxe para fazer isso normalmente com um LKM improvisado, mas este artigo fornece uma boa visão geral do que você precisa fazer: http://www.linuxjournal.com/article/4378

Você também pode corrigir a função sys_open.Ele começa na linha 1084 do arquivo/open.c a partir do linux-2.6.26.

Você também pode ver se não pode usar inotify, systemtap ou SELinux para fazer todo esse registro sem precisar construir um novo sistema.

Se você quiser fazer isso apenas para fins de depuração, procure no strace, que é construído no topo da chamada do sistema ptrace(2), que permite conectar o código quando uma chamada do sistema é feita.Consulte a parte PTRACE_SYSCALL da página do manual.

Parece que você precisa de auditoria.

Auditd permite rastreamento global de todos os syscalls ou acessos a arquivos, com registro.Você pode definir chaves para eventos específicos de seu interesse.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top