web-dev-qa-db-fra.com

Surveillance des appels système (de manière fiable et sécurisée)

Existe-t-il une méthode fiable de "surveillance" des appels système sous Linux?

Il y a strace par exemple pour surveiller les appels et les signaux du système. Existe-t-il un moyen pour un processus d'esquiver de strace? Si oui, existe-t-il une autre méthode fiable et sécurisée de "surveillance" des appels système (et, peut-être, de réception de signaux), à laquelle un processus ne peut pas échapper (en supposant une implémentation Linux appropriée)?

15

Sous Linux, vous pouvez surveiller de manière fiable une sélection d'appels système ou d'accès aux fichiers avec le sous-système d'audit . Assurez-vous que le démon auditd est en cours d'exécution, puis configurez ce que vous souhaitez enregistrer avec auditctl . Chaque opération enregistrée est enregistrée dans /var/log/audit/audit.log (sur les configurations typiques).

Vous trouverez des exemples simples d'utilisation de auditctlsur ce site , sur Server Fault , et sur nix Stack Exchange .

strace ou des programmes associés utilisant ptrace sont des moyens fiables de surveiller les appels système, mais je me méfierais de les utiliser sur un programme malveillant. Je ne pourrais pas vous dire à quel point je suis hors de ma tête, mais il devrait être possible pour un programme surveillé de faire les bons appels ptrace pour échapper à la surveillance.

Notez qu'un programme malveillant pourrait engendrer un processus qui n'est pas audité et peut exécuter du code qui ne sera pas enregistré. Par exemple, il pourrait utiliser mmap pour écrire dans un fichier sans que le contenu du fichier apparaisse comme arguments des appels système, rendre ce fichier exécutable et générer un processus l'exécutant. Le processus généré peut généralement casser l'arborescence des processus avec quelque chose comme ssh localhost. Si vous auditez tous les processus exécutés par un utilisateur donné (par opposition à un seul processus et à ses descendants), vous pourrez tout enregistrer.

Si oui, existe-t-il une autre méthode fiable et sécurisée de "surveillance" des appels système (et, peut-être, de réception de signaux), ce processus ne peut pas s'arrêter (en supposant une mise en œuvre appropriée de Linux)?

Pour réitérer de manière légèrement différente ce que D.W. a déjà dit, ptrace est un appel système que strace, gdb et autres font pour surveiller les actions d'un processus. Il y a deux problèmes avec cette approche:

  1. Comme vous le savez probablement, le raccordement d'appels système est une technique préférée des auteurs de rootkits. Il est tout à fait possible de remplacer ptrace, de vous fournir la sortie d'un autre processus ou d'une autre anomalie de ce type.
  2. Les processus ne sont pas toujours écrits pour se soumettre volontairement aux débogueurs. Vous aimerez peut-être lire cet ensemble de défis (axé sur win32 - voir la toute première entrée et continuer à lire pour le rendre difficile) d'une entreprise appsec (je n'ai aucun lien avec eux). Bien que focalisé sur le mécanisme IsDebuggerPresent(), similaire des solutions existent pour ptrace . Si vous voulez voir cela dans la nature et avoir skype installé sur une boîte Linux, essayez de le déboguer.

    En répétant ces techniques ici, il existe deux mécanismes anti-trace clairs:

    if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
        printf("being ptraced\n");
        exit(1);
    }
    

    Cette méthode repose sur le fait qu'un processus ne peut pas être tracé deux fois. Si vous ne pouvez pas vous retracer, vous êtes tracé.

    struct timespec spec;
    
    signal(SIGALRM, SIG_IGN);
    alarm(1);
    spec.tv_sec = 2;
    spec.tv_nsec = 0;
    if (nanosleep(&spec, NULL) < 0) {
        /* EINTR */
        printf("being ptraced\n");
        exit(1);
    }
    

    Pour expliquer celui-ci, jetez un œil à nanosleep() et lisez l'article original. En termes simples, nanosleep() est un appel système qui ne peut pas être redémarré et reviendra plus tôt lorsqu'un signal est traité par le processus. Ce processus particulier, lorsqu'il n'est pas débogué, ne gère tout simplement pas ce signal particulier et ne sera donc pas réveillé. Cependant, un processus ptracé le traitera, provoquant un retour précoce de nanosleep. Un autre exemple où cela se produit est l'appel système select().

En fin de compte, vous pouvez atténuer les effets de 1 en garantissant l'intégrité de votre système avant de démarrer et d'appliquer des mesures de sécurité suffisantes et un noyau correctement configuré.

Que pouvez-vous faire de manière fiable sur 2? Pas beaucoup sans modifier le code binaire d'origine, car toute technique de débogage va introduire quelque part des incohérences ou des problèmes d'implémentation observables.

tl; dr ptrace vous aidera si le processus cible n'a pas été écrit avec des débogueurs à l'esprit.

10
user2213

Le Linux Audit Framework prend en charge la surveillance syscall - je crois que c'est ce que vous recherchez.

5
john

Oui. strace est un moyen raisonnable de surveiller les appels système et leurs arguments, tant que le processus surveillé n'est pas malveillant. Si le processus surveillé est malveillant et a été écrit pour échapper à Strace, je m'attends à ce qu'il puisse le faire. strace n'a pas été écrit comme un outil de sécurité, et je peux émettre l'hypothèse que le processus pourrait le vaincre de plusieurs manières. Voir, par exemple, Robert Watson, Exploiting Vulnerabilities Concurrency in System Call Wrappers ou Tal Garfinkel, Traps and Pitfalls: Practical Problems in System Call Interposition Based Security Tools .

Si vous vous inquiétez du code malveillant, vous voudrez utiliser un sandbox qui a été conçu pour la sécurité, plutôt qu'un outil comme strace qui n'a pas été conçu pour la sécurité. L'approche générale de la construction d'un tel bac à sable consiste à utiliser l'interposition des appels système à la fois pour contenir le processus surveillé et pour surveiller ses actions. Une méthode portable consiste à utiliser ptrace, bien que cela puisse introduire une surcharge de performances non triviale car elle force un changement de contexte à chaque appel système. Sous Solaris, vous pouvez utiliser/proc;/proc vous permet de spécifier le sous-ensemble d'appels système que vous souhaitez encapsuler, ce qui vous permet d'obtenir de meilleures performances au détriment de la compatibilité.

Jetez un oeil à Plash, Systrace et Subterfugue, pour voir quelques systèmes qui utilisent ce type de méthodes. Regardez également le sandbox de Chrome, qui utilise une variété de mécanismes (y compris seccomp sur Linux).

4
D.W.

Qu'en est-il de la surveillance des appels système du côté du noyau à l'aide d'une instance gdb externe.

Cela pourrait être fait en installant une machine virtuelle qui est configurée pour exécuter le code d'intérêt. Ensuite, QEMU et KVM (à ma connaissance) doivent être configurés pour ouvrir un port pour le débogage gdb du noyau (voir les guides coup).)

Si ceci VM est démarré, gdb pourrait être attaché à son noyau pendant le démarrage.

L'étape suivante consiste à définir les propriétés gdb et les points d'arrêt pour qu'ils se déclenchent sur tout exécutable (et consorts) qui définit le code d'intérêt comme nouveau programme. Laissez ensuite le gdb s'exécuter jusqu'à ce qu'il atteigne ce point d'arrêt. À ce stade, pendant l'exécution du programme, le pid du processus exécutant le code d'intérêt peut être extrait et des points d'arrêt peuvent être définis dans gdb qui sont atteints (dans le code du noyau) sur tout appel système de ce processus (y compris fork et execve appels pouvant conduire à des processus supplémentaires à observer).

En théorie, cela devrait être une bonne solution difficile à suivre.

Un problème est que tout dans le système invité devient horriblement lent, et vous pourriez recevoir une énorme quantité d'appels indésirables comme prises accessoires (que vous devez filtrer à l'aide de gdb ...). Il peut être nécessaire d'étendre gdb supplémentaire en utilisant python pour que les points d'arrêt conditionnels fonctionnent avec les conditions requises (en particulier pour une détection automatique de processus enfant).

Guide comment connecter gdb à l'invité: Whamcloud Wiki , ReadHat Helpdesk , Stackoverflow

(Je n'ai pas essayé ces guides. J'ai utilisé gdb il y a quelques années pour déboguer certains détails du noyau pour un projet étudiant. Là, j'ai utilisé une condition simple sur un point d'arrêt pour détecter les appels fork d'un processus spécifique.)

En plus de cela, il existe d'autres techniques pour déboguer un noya .

PS: sachez qu'il existe des moyens d'échapper à une machine virtuelle (un ancien exemple ).

0
msebas