Ptrace() En «six» mots : Ptrace() permet de suivre un processus.



Documents pareils
Playing with ptrace() for fun and profit

Cours Programmation Système

Dans le chapitre 1, nous associions aux fichiers ouverts des descripteurs de fichiers par lesquels nous accédions aux fichiers.

Livre blanc Mesure des performances sous Windows Embedded Standard 7

Sauvegarde et restauration d'un système d'exploitation Clonezilla

Les avantages de la virtualisation sont multiples. On peut citer:

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

ERESI : une plate-forme d'analyse binaire au niveau noyau. The ERESI team

Acronis Backup & Recovery 10 Advanced Server Virtual Edition. Guide de démarrage rapide

Mise en œuvre d un poste virtuel

Protocoles DHCP et DNS

SYSTÈME DE GESTION DE FICHIERS

Programmation système en C/C++

I. Introduction aux fonctions : les fonctions standards

Stockage du fichier dans une table mysql:

"! "#$ $ $ ""! %#& """! '& ( ")! )*+

Installation et Réinstallation de Windows XP

Symantec Backup Exec Remote Media Agent for Linux Servers

Guide de fonctions du téléphone du système SCI Norstar

Symantec Backup Exec 12.5 for Windows Servers. Guide d'installation rapide

MODE D'EMPLOI DE LA CALCULATRICE POUR LES COURTS SÉJOURS DANS L'ESPACE SCHENGEN

Guide rapide d'installation SUSE Linux Enterprise Server 11 SP1

1. Introduction Création d'une macro autonome Exécuter la macro pas à pas Modifier une macro... 5

Introduction aux Systèmes et aux Réseaux

Le Network File System de Sun (NFS)

Maintenir Debian GNU/Linux à jour

Protéger ses données dans le cloud

gestion des processus La gestion des processus

Systemes d'exploitation des ordinateurs

Guide pour la réalisation d'un document avec Open Office Writer 2.2

Documentation utilisateur, manuel utilisateur MagicSafe Linux. Vous pouvez télécharger la dernière version de ce document à l adresse suivante :

POUR MAC Guide de démarrage rapide. Cliquez ici pour télécharger la version la plus récente de ce document

SYSTÈME DE GESTION DE FICHIERS SGF - DISQUE

CONDITIONS PARTICULIERES SOLUTIONS CLOUD. API : Interface de programmation pouvant être utilisé par le Client pour interagir avec ses Services.

Synchronisation Mysql (Replication)

PFE Télécommunications. Pré-rapport à l'issue des 6 premières semaines de stage. Page 1 sur 5 1 %

HelpAndManual_unregistered_evaluation_copy GESTIONNAIRE D'ALARMES CENTRALISE OPTIM'ALARM. Manuel d'utilisation

Guide de l'administrateur Citrix Personal vdisk 5.6.5

Messages d'erreurs. Redémarrez votre PC en cliquant sur Démarrer, en sélectionnant ensuite Arrêter puis en cochant Redémarrer

Supervision des applications et services réseaux

Service client LSC 1

Virtualisation de Windows dans Ubuntu Linux

OPTENET DCAgent Manuel d'utilisateur

1 Mesure de la performance d un système temps réel : la gigue

Guide de configuration de SQL Server pour BusinessObjects Planning

Concept de machine virtuelle

Stratégie de sécurité grâce au logiciel libre. Frédéric Raynal Cédric Blancher

Généralités sur le Langage Java et éléments syntaxiques.

Titre: Version: Dernière modification: Auteur: Statut: Licence:

Sommaire Introduction... 3 Le but du projet... 3 Les moyens utilisés... 3 Informations sur le client FTP... 4 Pourquoi une version Linux et

Présentation du SC101

PRINCIPES DE BASE DE LA SAUVEGARDE POUR LA PROTECTION DE VOS DONNÉES ET DE VOTRE ACTIVITÉ

DIASER Pôle Assistance Rectorat

Faille dans Internet Explorer 7

CA Desktop Migration Manager

Mise en place d'un Réseau Privé Virtuel

Institut Supérieure Aux Etudes Technologiques De Nabeul. Département Informatique

INFORM :: DEMARRAGE RAPIDE A service by KIS

GUIDE DE L UTILISATEUR

Exécutif temps réel Pierre-Yves Duval (cppm)

Premiers pas sur e-lyco

Firewall Net Integrator Vue d ensemble

HP Data Protector Express Software - Tutoriel 3. Réalisation de votre première sauvegarde et restauration de disque

Systèmes d exploitation

Serveur d application WebDev

56K Performance Pro Modem

REALISATION d'un. ORDONNANCEUR à ECHEANCES

FOIRE AUX QUESTIONS PAIEMENT PAR INTERNET. Nom de fichier : Monetico_Paiement_Foire_aux_Questions_v1.7 Numéro de version : 1.7 Date :

Chapitre 5 : Les procédures stockées PL/SQL

Les rootkits navigateurs

Glossaire. Acces Denied

Réseau : Interconnexion de réseaux, routage et application de règles de filtrage.

Prise en main. Norton Ghost Pour trouver des informations supplémentaires. A propos de Norton Ghost

À propos de Parallels Desktop 10 pour Mac

Les vulnérabilités du noyau. LECORNET Olivier LEGROS Bruno VIGIER Nicolas Promo 2005

Programmation assembleur : aperçu

Chapitre 1 : Introduction aux bases de données

Manuel Utilisateur de l'installation du connecteur Pronote à l'ent

Bind, le serveur de noms sous Linux

MANUEL. de l application «CdC Online» pour Windows. Table des matières

Pour valider les pré-requis nécessaires, avant d'aborder le TP, répondez aux questions ciaprès

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

TP Service HTTP Serveur Apache Linux Debian

PARAGON SYSTEM BACKUP 2010

CARPE. Documentation Informatique S E T R A. Version Août CARPE (Documentation Informatique) 1

NAS 224 Accès distant - Configuration manuelle

Ajouter de la mémoire à son ordinateur

1 Repérer les paramètres d installation (.exe ou.msi).

TeamViewer 9 Manuel Management Console

Processus! programme. DIMA, Systèmes Centralisés (Ph. Mauran) " Processus = suite d'actions = suite d'états obtenus = trace

Accès Gratuit - Conditions Générales d'utilisation

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Installation d'un serveur DHCP sous Windows 2000 Serveur

Conditions d utilisation

Créer un publipostage avec Word 2007.

Transcription:

Ptrace() Avertissement : tout d'abord, nous allons vous faire part de nos sources, car pour l'élaboration de ce document, nous avons dû nous documenter mais également nous inspirer de quelques ouvrages publics ainsi que du fameux man. Concernant les documents publics nous nous sommes surtout inspiré de «Playing with Ptrace() for fun and profit» de Nicolas Bareil. En «six» mots : Ptrace() permet de suivre un processus. Profil fonction : #include <sys/ptrace.h> long ptrace(enum ptrace_request requête, int pid, void * addr, int data); Présentation générale : Globalement, la fonction ptrace() donne l'opportunité à un processus de contrôler l'exécution pas à pas d'un autre processus en se substituant à son père. Il devient ainsi un «faux père» et acquiert les privilèges qui en découlent. L'un de ces privilèges lui permet de recevoir les notifications d'évènements du processus suivi, et de le contrôler par l'intermédiaire de signaux. «Brièvement, ptrace() permet d'accéder en lecture/écriture à tout l'espace d'adressage d'un processus». Ce contrôle, total, peut être établit par n'importe quel processus, il lui suffit pour cela d'avoir les droits nécessaires : les même que requiert un simple envoi de signal à un autre processus. En au moins «deux mille huit cents quatre vingt dix» mots : A/ Fonctionnement détaillé : Nous avons vu précédemment les aspects globaux de la fonction ptrace(). Dans cette partie nous allons nous attarder plus en détail sur les arguments et les diverses fonctionnalités de ptrace(). D'après le man, l'argument requête peut prendre pour valeurs : 1. - PTRACE_TRACEME : cet argument est utilisé si c'est le fils qui fait appel à ptrace(). Cela permet, si le père est en attente d'un suivi du fils, que le vrai père prenne en charge le «destin» du fils. Dans ce cas, n'importe quel signal, excepté SIGKILL, arrêtera le processus et notifiera le père par un wait. De plus, les appels ultérieurs à exec() par ce processus lui enverront SIGTRAP, ce qui donne au père la possibilité de reprendre le contrôle avant que le nouveau programme continue son exécution. Dans cette requête, les autres arguments sont ignorés. 2. - PTRACE_ATTACH : c'est cet argument qui permet la substitution du père par le processus appelant. De ce fait, le fils se comportera de la même manière que s'il avait appelé ptrace() avec PTRACE_TRACEME. Cependant un appel à getppid() renverra le pid du vrai père. L'arrêt du fils n'est peut être pas immédiat et, par

précaution, il faut utiliser wait dans le père pour attendre son arrêt effectif. Les arguments addr et data sont ignorés. 3. - PTRACE_CONT : permet de redémarrer le processus fils stoppé. Data est reconnu comme un numéro de signal à transmettre au fils, s'il est non-nul et différent de SIGSTOP aucun signal n'est transmit. L'argument addr est ignoré. 4. - PTRACE_DETACH : relance le processus fils comme avec PTRACE_CONT en lui redonnant sa parenté initiale et sa «liberté» (il n est plus suivi par le processus appelant). L'argument addr est ignoré. 5. - PTRACE_SYSCALL & PTRACE_SINGLESTEP : permet de redémarrer le processus fils stoppé comme PTRACE_CONT à la différence qu'il s'arrêtera à la prochaine entrée/sortie d'un appel système ou de la prochaine instruction. Cela n'empêche pas le fils d'être arrêté par un signal entre temps. Le père sera informé de cet arrêt par SIGTRAP. L'argument addr est ignoré. 6. - PTRACE_PEEKTEXT & PTRACE_PEEKDATA : permet de lire un mot à l'adresse addr dans l'espace mémoire du fils. Ptrace() renvoi en résultat la valeur lu. Ces deux requêtes sont équivalentes sous linux car il ne sépare pas les espace d'adressage de code et de donnée. L'argument data est ignoré 7. - PTRACE_PEEKUSR : de même que PTRACE_PEEKTEXT cet argument lit un mot à l'adresse addr mais dans l'espace USER du fils. Cet espace contient les registres et diverses informations sur le processus. L'argument data est ignoré. 8. - PTRACE_POKETEXT & PTRACE_POKEDATA : copie un mot depuis l'adresse data de la mémoire du père vers l'adresse addr de la mémoire du fils. Pour les même raisons que PTRACE_PEEKTEXT, les deux requête sont équivalentes. 9. - PTRACE_POKEUSR : copie un mot depuis l'emplacement data du père vers l'emplacement addr dans l'espace USER du processus fils. Cependant, certaines modification de la zone USER sont interdites afin de «maintenir l'intégrité du noyau». 10. - PTRACE_GETREGS & PTRACE_GETFPREGS : copie les registres généraux ou du processeur, en float, vers l'adresse data du père. 11. - PTRACE_SETREGS & PTRACE_SETFPREGS : remplie les registres généraux ou du processeur, en float, vers l'adresse data du père. 12. - PTRACE_KILL : envoie un signal SIGKILL au fils pour le terminer. Les argument addr et data sont ignorés. 13. - PTRACE_GETSIGINFO : obtient l information sur le signal qui a provoqué l arrêt, récupère les signaux du processus fils. 14. - PTRACE_SETSIGINFO : modifie les signaux du processus fils. Configure l information du signal. Copie une structure siginfo_t de l emplacement data du père vers le fils. Cela n affectera que les signaux qui auraient été normalement délivrés au fils et étaient capturés par le traceur. Il peut être difficile de dire ces signaux normaux à partir de signaux synthétiques générés par ptrace() lui-même.

L'argument addr est ignoré. 15. - PTRACE_GETEVENTMSG : copie la variable noyau child->ptrace_message en espace utilisateur. 16.- PTRACE_SYSEMU : redémarre le processus fils stoppé jusqu'au prochain syscall, qui ne sera pas exécuté. 17.- PTRACE_SYSEMU_SINGLESTEP : pareil que précédemment mais en pas à pas s'il n'y pas de syscall. 18.- PTRACE_SETOPTIONS : permet l'ajout ou la modification des options de suivi de processus. Les options peuvent être les suivantes : - PTRACE_O_TRACEFORK : permet d'activer le traçage «en cascade» (de tous les fils qui seraient créés par le fils via fork()). L équivalent pour la fonction vfork() est PTRACE_O_TRACEVFORK. - PTRACE_O_TRACESYSGOOD : informe le père par la transmission du signal SIGTRAP lors du déroutement par syscall, ce qui permet de faire la différence entre les déroutements normaux et les déroutements syscall. -PTRACE_O_TRACEEXIT : arrête le fils à la sortie avec SIGTRAP. L état de sortie du fils peut être obtenu avec PTRACE_GETEVENTMSG. Cet arrêt sera effectué plutôt pendant le processus de sortie lorsque les registres sont encore disponibles, permettant de voir où survient la sortie. La notification de sortie normale est effectuée après que le processus ait achevé sa sortie. -PTRACE_O_TRACECLONE : arrête le fils au prochain appel clone() avec SIGTRAP et démarrer automatiquement le suivi du nouveau processus «cloné» qui démarrera avec un SIGSTOP. Le PID du nouveau processus peut être obtenu avec PTRACE_GETEVENTMSG. NB : L'argument requête est le seul à être fixé. Ceci signifie que que les arguments finaux inutiles peuvent être omis. si un processus est attaché avec PTRACE_ATTACH, son père original ne peut plus recevoir les notifications avec wait(). Ptrace() peut varier sensiblement sur d autres types d Unix. Valeur de retour : Pour les requêtes PTRACE_PEEK, ptrace() renvoie la valeur réclamée, sinon elle renvoi 0 pour toutes les autres requêtes. Ou 1 en cas d échec en remplissant errno avec un des codes d erreurs se trouvant dans le paragraphe ci-après.

Utilisation des options : L'utilisation des optons pour ptrace() se fait de la manière suivante : int options = PTRACE_O_TRACEFORK PTRACE_O_TRACESYSGOOD... ; ptrace(ptrace_setoptions, pid, null, options); Les erreurs produites par Ptrace() : EBUSY : erreur lors de l'allocation ou de la libération d'un registre de débogage. EFAULT : tentative de lecture/écriture dans une zone mémoire invalide. EINVAL : tentative d'utilisation d'une option invalide. EIO : requête invalide, ou envoie de signal invalide. EPERM : le processus ne peut être suivi à cause d'un manque de privilège du processus appelant, ou alors le processus est déjà suivi. ESRCH : le processus n'existe pas, n'est pas suivi par l'appelant, ou n'est pas arrêté (si besoin est). B/ Utilisation pratique : Nous avons vu les caractéristique détaillé des arguments de Ptrace() ainsi que ses erreurs. Maintenant nous allons nous focaliser sur la partie utilisation de ptrace(), son utilité, ses avantages et ses inconvénients. Aux vues des documents que nous avons consulté pour cette description de ptrace() nous nous sommes confrontés à quelques difficultés de rédactions. C'est pourquoi dans cette partie, à la place de "tricher" en copiant/collant, nous allons être honnête et faire des paragraphes des informations que nous avons réussi à assimiler et retranscrire. Les autres parties vous seront retransmises sous forme de citations. Portabilité : La fonction ptrace() présente un désavantage majeure, dû à sa conception, étant intimement liée au noyau, elle ne peut être portable. En effet, les registres ou les informations manipulés changent d'un noyau à l'autre, ainsi que la taille des mots, les alignements imposés par l'utilisation des options de ptrace(), peuvent différés d'une distribution à l'autre, voire d'une version plus élaborée d'une même distribution. Il en va de même pour les différentes architectures. Nous ne pouvons donc garantir la compatibilité du code écrit/injecté que sur notre propre machine.

Injection de code : Si le but de l'insertion de code est d'être le plus furtif possible, la pile semble l'endroit le plus adapté. En effet, nous utiliserons un double appel de la fonction ptrace(), qui permettra d'injecter le code dans la pile, tout en modifiant les deux pointeurs eip (emplacement courant) et esp (haut de la pile) pour rendre invisible ladite injection. Le premier appel écrira le code à l'adresse pointé par eip, alors que le deuxième modifiera les deux pointeurs, mettant esp à la place du "nouveau" haut de pile, et eip pointant sur une copie de l'ancien eip à sa nouvelle place. Après avoir exécuté notre code en continuant le processus et avant la fin du code, il faut restaurer la pile dans son état initial. Cette phase est celle qui pose le plus de problème : il faut en effet repérer la dernière ligne de code injectée dans la pile avant de supprimer toute trace de notre passage. Pour cela, deux solutions s'offre à nous, soit faire du pas à pas dans l'injecteur et repérer la dernière instruction, soit faire continuer le code et attendre qu'il réveille l'injecteur via le signal SIGTRAP, qui redonne la main au père, qui peut ainsi nettoyer derrière lui. Ce qui rend cette méthode furtive est le fait que le fils n'a pas la main durant l'injection de code. De ce fait, il ne se rend pas compte de la modification de la pile et ne peut pas détecter l'intrusion. Interruption appel système : Si l'on injecte du code durant un appel système (read, write, open, etc...), il se peut que le fils ait besoin de reprendre la main. «Sur architecture x86, à l'entrée d'un appel système, le noyau pousse eax sur la pile (eax contenant le n de syscall demandé). Ensuite, l'appel système est exécuté et à sa fin, met sa valeur de retour dans ce même registre eax. Les appels systèmes considéré lents sont interruptibles, à la réception d'un signal, le noyau va arrêt l'appel système pour exécuter le handler. Puis, après traitement du signal, deux cas possibles : - l'appel système et automatiquement redémarré, - le redémarrage doit être manuel (le code de retour de l'appel système échoue avec errno égale à EINT); pour le redémarrage automatique, le noyau rétabli eax en utilisant sa copie locale contenue dans la pile, notre fameux orig_eax, puis décrémente eip de deux octets, soit la taille de l'instruction int 0x80. Pour détecter l'interruption d'un appel système, nous allons mimer le noyau linux et regarder nos registre : eax doit valoir -1 et orig_eax doit contenir un numéro d'appel système correct. Une deuxième méthode, qui à le mérite d'être portable sur toutes les architectures, et d'utiliser l'option PTRACE_O_SYSGOOD qui va ajouter 0x80 à si_code accessible via une requête PTRACE_GETSIGINFO.» Exemple d'utilisation de ptrace() Un exemple d'utilisation de ptrace() peut être la Virtualisation de système (UserModeLinux) : son implémentation repose sur l'utilisation de ptrace(), le but étant de

faire tourner un maximum d'instruction et passer par une couche d'abstraction lorsque les appels système sont utilisés. En fait, la machine virtuelle crée un thread, qui va permettre de tracer ses processus. Une fois les processus attachés, ils sont continués avec PTRACE_SYSCALL, qui permettra de stopper les processus de la même façon que Fakebust. «Fakebust est un logiciel développé par Michal Zalewski afin de pouvoir lancer des binaires inconnus (hostiles) sans avoir à utiliser une machine virtuelle ou à avoir à effectuer une longue analyse statique. Fakebust est basé uniquement sur ptrace() en suivant un processus à l'aide de PTRACE_SYSCALL. Cela signifie que le processus tracé est uniquement interrompu à l'entrée et à la sortie d'un appel système, ainsi qu'à la réception d'un signal. A l'entrée d'un des syscall, considérés comme dangereux (par exemple open, socket, unlink, etc.), Fakebust va autoriser les appels système au cas par cas en interrogeant l'utilisateur s'il doit exécuter l'appel système, le refuser ou le simuler.» Ptrace() nous permet également de réagir face à certains incidents. En effet, nous devenons «omniscient», il nous est possible d'analyser chaque processus. Si le noyau n'a pas été modifié ou qu'il ne s'intéresse pas à ptrace(), nous allons pouvoir analyser les processus suspect du style backdoors, redirecteurs de ports, client IRC, etc. L'intérêt de cette propriété de ptrace() est que si vous faites «l'autopsie» d'une machine piratée, votre but sera d'accéder au root, et ainsi accéder à tous les processus. Vous pourrez, à partir de là, modifier les binaires recherchés et y insérer le «hash» du mot de passe pour effectuer votre identification. «Nous pouvons également détourner et retourner des rootkits noyau comme le populaire Suckit. Pour ce dernier, l'accès au seul pirate est limité par un mot de passe qui autorise ou non l'utilisation du module noyau. Comme cela a été montré par Frédéric Raynal a EusecWest, le binaire de contrôle est chiffré en RC4 avec une graine de 64 octets placée en fin de fichier avec la configuration (contenant le mot de passe hashé). A l'exécution, le binaire est complètement déchiffré en mémoire puis tente d'authentifier l'utilisateur avec la demande du mot de passe. Celui-ci est hashé et comparé à celui stocké en mémoire.» Conclusion : Ainsi, ptrace() est un outil puissant de debugging, avec de nombreuses fonctionnalités, mais qui permet également une utilisation moins attendue, comme le hacking de compte root par exemple. De plus, cette faille touche toutes les architectures utilisant ptrace(), ce qui fournit les outils nécessaire aux pirates de tous horizons. Cependant, comme toutes failles, il existe des solutions : par exemple un patch est en vigueur pour les distribution supérieur à la version 2.4.20 de Linux, qui résout les problèmes de sécurité liés à ptrace().