Question

Outre l'astuce LD_PRELOAD et les modules de noyau Linux qui remplacent un certain appel système par celui que vous avez fourni, existe-t-il une possibilité d'intercepter un appel système (ouvert par exemple), de sorte qu'il passe d'abord par votre fonction, avant d'atteindre la réelle ouverte?

Était-ce utile?

La solution

si vous avez vraiment besoin d'une solution, le rootkit DR qui vous permet de le faire vous intéresse, http://www.immunityinc.com/downloads/linux_rootkit_source.tbz2 l'article à ce sujet se trouve ici http://www.theregister.co.uk/2008/09/04/linux_rootkit_released/

Autres conseils

Pourquoi ne pas / ne voulez-vous pas utiliser le astuce LD_PRELOAD ?

Exemple de code ici:

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

D'après ce que j'ai compris ... c'est à peu près le truc de LD_PRELOAD ou un module de noyau. Il n'y a pas de terrain d'entente à moins que vous ne souhaitiez l'exécuter sous un émulateur pouvant intercepter votre fonction ou réécrire du code sur le binaire réel pour intercepter votre fonction.

En supposant que vous ne puissiez pas modifier le programme et que vous ne puissiez pas (ou ne veuille pas) modifier le noyau, l'approche LD_PRELOAD est la meilleure, en supposant que votre application est assez standard et qu'elle n'est pas réellement une tentative malicieuse. pour passer votre interception. (Dans ce cas, vous aurez besoin d’une des autres techniques.)

Valgrind peut être utilisé pour intercepter tout appel de fonction. Si vous devez intercepter un appel système dans votre produit fini, il ne vous sera d'aucune utilité. Cependant, si vous essayez d’intercepter pendant le développement, cela peut être très utile. J'ai fréquemment utilisé cette technique pour intercepter les fonctions de hachage afin de pouvoir contrôler le hachage renvoyé à des fins de test.

Si vous n’êtes pas au courant, Valgrind est principalement utilisé pour rechercher des fuites de mémoire et d’autres erreurs liées à la mémoire. Mais la technologie sous-jacente est essentiellement un émulateur x86. Il émule votre programme et intercepte les appels vers malloc / free, etc. Le point positif est que vous n’avez pas besoin de recompiler pour l’utiliser.

Valgrind possède une fonctionnalité qu’ils appellent Enveloppement de fonctions , qui permet de contrôler l’interception de fonctions. Voir la section 3.2 du manuel Valgrind pour plus de détails. Vous pouvez configurer l'habillage de fonction pour n'importe quelle fonction de votre choix. Une fois l'appel intercepté, la fonction alternative que vous fournissez est ensuite appelée.

Certaines applications peuvent faire en sorte que strace / ptrace ne s'exécute pas. La seule option réelle que j'ai eue est d'utiliser SystemTap

.

Systemtap peut intercepter un grand nombre d'appels système, si nécessaire, en raison de la correspondance de son caractère générique. Systemtap n'est pas C, mais une langue séparée. En mode de base, la capture du système devrait vous empêcher de faire des choses stupides, mais elle peut également s'exécuter en mode "expert". cela revient à autoriser un développeur à utiliser C si cela est nécessaire.

Cela ne vous oblige pas à corriger votre noyau (ou du moins ne le devrait pas), et une fois qu'un module a été compilé, vous pouvez le copier depuis une boîte de test / développement et l'insérer (via insmod) sur un système de production. .

Je n'ai pas encore trouvé d'application Linux capable de contourner le problème / d'éviter de se faire prendre par SystemTap.

Si vous souhaitez simplement regarder ce qui est ouvert, vous souhaitez consulter la fonction ptrace () ou le code source de l'utilitaire strace en ligne de commande. Si vous voulez réellement intercepter l'appel, pour éventuellement le faire faire autre chose, je pense que les options que vous avez énumérées - LD_PRELOAD ou un module de noyau - sont vos seules options.

Je n'ai pas la syntaxe pour le faire gracieusement avec un LKM, mais cet article fournit un bon aperçu de ce que vous devez faire: http://www.linuxjournal.com/article/4378

Vous pouvez également corriger la fonction sys_open. Il commence à la ligne 1084 du fichier / open.c à partir de linux-2.6.26.

Vous pouvez également voir si vous ne pouvez pas utiliser inotify, systemtap ou SELinux pour effectuer toute cette journalisation pour vous sans que vous ayez à créer un nouveau système.

Si vous souhaitez le faire uniquement à des fins de débogage, examinez strace, qui est construit en haut de l'appel système ptrace (2), qui vous permet de raccorder du code lorsqu'un appel système est effectué. Voir la partie PTRACE_SYSCALL de la page de manuel.

On dirait que vous avez besoin d’audit.

Auditd permet un suivi global de tous les appels système ou des accès aux fichiers, avec consignation. Vous pouvez définir des clés pour des événements spécifiques qui vous intéressent.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top