lundi, janvier 22, 2007

Au-delà de l'écran bleu


L'examen de la mémoire physique reste, à l'heure actuelle, une pratique marginale du forensique numérique. Pourtant, nous pouvons constater chaque jour que les codes malveillants utilisent de plus en plus de techniques, dites anti-forensiques, afin de ne laisser aucune trace sur les disques durs... Au grand malheur des investigateurs forensiques !

Les équipes de réponse aux incidents ont récemment intégré le recueil de la mémoire physique des systèmes Microsoft Windows dans leur procédure de réponse immédiate. Mais les informations obtenues par ce recueil semblent bien dérisoires, face à la somme de données que détient cette mémoire.

Nous sommes actuellement dans une situation similaire à celle des premiers égyptologues qui essayèrent de déchiffrer des milliers d'idéogrammes dont la logique leur échappait. La seule différence est, peut être, que leur auteurs (les développeurs Microsoft) sont bien vivants, mais tenus par des clauses de non divulgation draconiennes. Pour obtenir des brides de savoir, il nous reste à écouter les petits malins qui ont, par exemple, la chance d'avoir sous la main un développeur millionnaire retraité (non, ce n'est pas vrai ! Je ne parle pas de David Cutler) qui adore s'épancher le soir autour d'un verre...

Gestion de la mémoire virtuelle sous Windows

L'une des raisons pour lesquelles il est actuellement extrêmement difficile d'analyser la mémoire physique de tout système d'exploitation moderne est l'incroyable complexité de l'abstraction utilisée pour gérer cette mémoire. La plupart du temps, les données appartenant à un processus sont distribuées de manière complètement aléatoire sur la totalité de la mémoire physique, et également sur le disque dur. Ce qui rend extrêmement difficile la restauration des informations utiles.

En fait, il faut savoir que la gestion de la mémoire est un problème aussi vieux que l'informatique. Depuis plus de quarante ans, les systèmes d'exploitation s'escriment à résoudre le problème de l'allocation de la mémoire physique. Nous allons donc nous concentrer sur les meilleures usines à gaz du moment : les systèmes Microsoft Windows.

Outre leur effroyable complexité interne, les systèmes MS Windows ont l'avantage de constituer l'écrasante majorité des systèmes étudiés durant une investigation forensique. Le véritable challenge dans leur étude réside dans la volonté évidente de leurs développeurs de ne rien documenter sur leur fonctionnement interne. Est-ce d'ailleurs vraiment un bon calcul au niveau sécurité ? Vous n'êtes pas sans savoir que les véritables hackers adorent s'acharner sur ce qui leur résiste !

L'objet \Device\PhysicalMemory a été révélé pour la première fois à la face du monde par Mark Russinovich de Sysinternals (un type qui adore écouter les vieux développeurs autour d'un verre :-)) dans le code source de Physmem. La solution de Microsoft consiste à diviser cette mémoire en un série de pages à taille constante. Cette taille est fixée à 4KB sur les architectures x86 de moins de 4GB de mémoire physique (variable PAGE_SIZE).

La meilleure analogie que je connaisse pour la gestion de la mémoire sous Windows consiste à la comparer à un livre dans lequel chaque page contient un nombre limité de caractères. Dans ce livre, chaque processus possède sa propre table des matières (appelée registre CR3) qui lui permet de consulter les pages qui le concerne. De plus, deux processus possèdent une lecture du livre entièrement différente, chacun d'entre eux croyant être son unique lecteur. Enfin, si un processus peut lire l'adresse mémoire 0x00422211 et y lire le mot "eric", un autre processus y lira le mot "alex".

Chaque processus possède ainsi donc sa propre lecture de l'espace mémoire. Il s'agit du processus de translation de la mémoire virtuelle dans la mémoire physique et le fichier de pagination. Cette translation est possible grâce à la tenue d'une multitude de tables et de registres. Pour simplifier, on peut affirmer que toute l'habileté d'un cheval de Troie réside dans sa capacité à modifier ces tables sans provoquer un écran bleu de la mort (un BSoD pour les anglophiles) !

Premier élément d'analyse de la mémoire : les objets _EPROCESS

Chaque programme tournant sur un système MS Windows se voit assigner un "processus" qui maintient l'état de ses données en mémoire. MS Windows stocke dans la mémoire virtuelle les informations relatives à chacun de ses processus dans une structure du noyau appelée _EPROCESS.

Le gestionnaire de la mémoire des systèmes Microsoft prédéfinit un intervalle de l'espace d'adressage de la mémoire virtuelle au profit des objets du noyau (adresses supérieures à 0x80000000 pour les architectures Intel x86 de moins de 4GB de RAM et supérieures à 0xC0000000 si l'option /3GB a été utilisée lors de l'installation du système).

Nous savons que tous les blocs _EPROCESS de l'ensemble des processus tournant sur un système MS Windows sont liés entre eux dans une double-liste dans laquelle le champ ActiveProcessLinks contient l'adresse virtuelle du prochain _EPROCESS à l'offset +0x088 et le précédent _EPROCESS à l'offset +0x08C.

Malheureusement, trouver l'adresse virtuelle d'un _EPROCESS constitue l'une des difficultés de l'analyse de la mémoire physique. En s'appuyant sur de la recherche de motifs (patterns matching), les outils mem_parser et KnTList réussissent à retrouver l'adresse du _EPROCESS System, bien que celle-ci soit modifiée à chaque redémarrage de la machine. A partir de cette adresse, et grâce à la double liste, nous sommes alors en mesure de retrouver tous les processus qui tournaient sur une machine MS Windows dont on a recueilli une image de la mémoire physique. A l'exception des codes malveillants qui manipulent leurs voisins dans la double liste pour rester invisibles (technique de camouflage DKOM, pour Direct Kernel Object Manipulation).

Deuxième élément d'analyse de la mémoire :la BPD et le PEB d'un _EPROCESS


Une fois tous les processus, qui étaient en fonctionnement lorsque l'image de la mémoire physique a été prise, sont retrouvés par l'adresse de leur _EPROCESS respectif, nous pouvons nous intéresser à chacun d'entre eux en particulier.

La BPD (pour Basic Process Details) fournit un certain nombre d'information sur le processus, dont les plus intéressantes sont les suivantes, classées par Offset :
- +0x018 : DirectoryTableBase qui constitue l'adresse physique de la table des matières de ce processus (Page Directory)
- +0x084 : le PID (l'identifiant) du processus
- +0x088 et +0x08C : les adresses des processus voisins dans la double-liste
- +0x14C : le PPID (PID du processus parent). C'est là que l'on recherche en particulier les processus ayant comme parent cmd.exe
- +0x174 : le nom du fichier binaire (.EXE, .DLL, ...)

Le _PEB (pour Process Environment Block) fait partie des principaux éléments de description d'un processus. Il stocke les données d'environnement du processus en mémoire. Pour accéder au _PEB, une translation doit être réalisée en utilisant son adresse virtuelle stockée dans son objet parent : _EPROCESS. Les informations intéressantes à recueillir dans cet objet sont les suivantes, classées également par Offset :
- +0x008 : adresse virtuelle de l'image de l'exécutable. Une fois sauvegardée, cette image peut être lancée et étudiée à loisir. (il existe des offsets permettant de calculer la taille de cet exécutable)
- +0x00c : adresse virtuelle de la liste des DLL (modules) utilisées par le processus
- +0x018 : adresse virtuelle du tas (Heap) du processus. (une bonne excuse pour se replonger dans les affres de l'assembleur et du reverse engineering...)

La guerre sombre et cruelle du Kernelland

Les rootkits les plus difficiles à détecter sont ceux résidant uniquement dans la partie de la mémoire physique réservée au noyau. Il s'agit d'un terrain de jeu extrêmement dangereux où le moindre faux pas provoque le terrible BSoD.

Afin de rester invisibles aux yeux des logiciels de détection qui scrutent les accès en écriture sur le disque dur, les codes malveillants de dernière génération font en sorte de se faire passer pour un pilote de matériel ou un thread appartenant à un processus noyau qui nécessite de la mémoire virtuelle non-paginable. Pour la dernière solution, il lui faut appeler la fonction ExAllocatePool avec le paramètre NonPagedPool, mais ceci est une autre histoire..

La principale faiblesse des rootkits est qu'ils doivent restés vivants ! S'ils ont été développés pour ne rien écrire sur le disque dur, ils sont donc inévitablement présents en mémoire physique.

Les méthodes d'analyse les plus simples que j'utilise actuellement pour détecter un rootkit dans l'image de la mémoire physique d'une machine suspecte sont les suivantes :
- repérer les processus ayant comme PPID cmd.exe ou explorer.exe
- référencer les adresses inhabituelles de module dans l'Offset +0x00c du PEB. En particulier, les librairies Kernel32.dll et NTDLL.dll. (rootkit utilisant les IAT Hooks)
- faire du reverse sur l'image de l'exécutable et examiner les données du tas du processus (bon là j'avoue que j'ai du mal. Mais je me documente à fond :-)).

vendredi, janvier 19, 2007

L'éthique kantienne contre la fascination du côté obscure

Toujours dans le thème du social, nous allons traiter ce soir des problèmes éthiques auxquels une équipe IR peut être un jour confrontée.

Si l'aphorisme du XVIIe siècle : savoir, c'est pouvoir est aujourd'hui évident pour notre société de l'information, l'adage du XIXe siècle : le pouvoir corrompt est une constatation quotidienne des équipes IR.

Quelle équipe IR n'a jamais traité une compromission liée à un problème de moralité ?

Bien entendu, ceci ne signifie pas que le pouvoir est un synonyme de corruption, mais simplement que tout individu investi d'une autorité ou d'une responsabilité peut être tenté de l'utiliser afin d'en tirer un quelconque avantage personnel.

Une déduction immédiate peut être tirée de ces deux affirmations :

Si savoir, c'est pouvoir et si le pouvoir corrompt, alors le savoir corrompt !

Ainsi, la connaissance accroit le risque de corruption. Et c'est là le noeud du problème.

Un membre d'une équipe IR possède les connaissances et le savoir-faire pour devenir un agent extrêmement dangereux, en particulier pour l'organisation qu'il est sensé protéger ! Sa reconversion en blackhat semble très facile :
la même connaissance des vulnérabilités des systèmes d'exploitations et de la plupart des applications, la même utilisation quoditienne d'outils d'analyse et de débogage, et enfin le suivi quotidien des mêmes pages relatives aux derniers rootkits et autres malwares.
En fait, il n'en est rien. Le passage à l'acte est souvent lié chez un individu à une absence de connaissance sur les moyens à la disposition des enquêteurs. Or, peu de personnes sont plus au fait des dernières techniques de forensique numérique qu'un membre d'une équipe IR. Il est également connu que le crime parfait ne résiste jamais à l'amélioration des techniques d'investigation...

Les sommes folles offertes actuellement pour une simple vulnérabilité dans Vista étaient ce matin dans tous les esprits de mon équipe. De tels montants, comparés aux salaires de techniciens, font rêver. Je ne sais plus qui d'entre nous a lancé l'idée d'unir nos efforts afin de rechercher une telle vulnérabilité, puis de monter une société écran dans un quelconque paradis fiscal, afin d'en faire profit...

La conversation a gentiment dérapé vers toutes les actions que l'équipe pourrait entreprendre à son propre profit : détournement de centres de calcul entiers afin de réaliser des rainbow tables, collecte d'informations personnels pour la revente à des spammers ou des list-brokers, renseignement économique... Bref, l'arsenal complet du parfait criminel en col blanc.

Au delà de cette simple conversation, une équipe IR - dont la mission est essentiellement défensive - utilise les mêmes outils que ses adversaires. Ajouté à cela le côté sulfureux de la sécurité informatique, il est alors inévitable que la plupart des responsables soient méfiants vis à vis de toute initiative entreprise par son équipe IR ou son staff chargé de la sécurité informatique. Toujours est-il que notre profession souffre suffisamment de l'ignorance ambiante, pour que nous puissions nous permettre d'avoir une attitude équivoque vis à vis de notre moralité.

En fait, j'ai souvent des pics de violence lorsque j'entends l'un de ces pseudo-hackers/professionnel-INFOSEC laisser supposer qu'il pratique toujours la compromission système à distance, comme un simple passe-temps.

Pour revenir à notre sujet principal, mon autre question d'ordre éthique est la suivante :

Jusqu'où peut-on aller pour stopper ou coincer un assaillant ?

Un coordinateur IR doit constamment s'interroger sur le bien-fondé moral des contre-mesures qu'il fait mettre en place par son équipe : sniffer, pot de goudron, pot de miel (j'adore les termes français pour ces deux là), keylogger... Sur quoi un tel jugement peut-il reposer ?

L'approche la plus simpliste consiste à se convaincre que tout ce qui tient du mensonge, du chantage ou de la tromperie est immoral. Au delà des considérations religieuses (qui ne sont pas ma tasse de thé en cette période de politiquement-correct), je préfère, pour ma part, pratiquer la règle de Kant qui stipule qu'un acte est moral s'il est universel. En d'autres termes, il est légitime de tromper l'assaillant dans des situations où nous admettons que quiconque à notre place serait en droit de le tromper.

Ainsi, l'acte moral s'apprécie en fonction des intentions qui le sous-tendent. Etant donné le caractère confidentielle des affaires qu'elle traite habituellement, une équipe IR ne peut pas s'appuyer sur un quelconque débat public pour justifier du bien fondé d'une de ces actions. Mon expérience fait que je me tiens à la règle suivante : ne déployer que le strict nécessaire de moyens pour stopper ou découvrir les acteurs d'une compromission. Tout en respectant la législation des pays concernés, cela va de soi...

C'est promis, le prochain article sera technique. ;-)

mercredi, janvier 17, 2007

La sociologie des équipes IR ou la libre société

Bon, j'ai cinq articles sur le forensique en préparation, et toujours rien de suffisamment abouti pour être présentable en l'état (perfectionniste, me direz-vous ?). Il faut savoir que c'est très long de faire des copies d'écran d'expériences réalisées à la vas-vite...

Faisons donc un peu de social, cela peut se faire sans aucune préparation :

Les méthodologies pratiquées par les équipes IR reposent toutes sur des hypothèses visant à expliquer les informations et les données recueillies. Or, il est souvent possible d'émettre plusieurs hypothèses à partir d'un recueil donné. La première question est la suivante :

Faut-il toujours choisir le scénario le plus simple ?

Un ancien précepte philosophique, connu sous le nom de rasoir d'Ockham, du nom d'un philosophe anglais du Moyen Âge stipule que : Parmi toutes les hypothèses, choisissez la plus restreinte. S'il est possible de ne retenir qu'un élément pour expliquer tel ou tel évènement, écartez le second.

Mais, la pratique de l'IR montre que, fréquemment, le scénario le plus évident n'est pas toujours le plus proche de la réalité. Un bon binôme IR doit donc savoir abandonner ce qu'il avait présumé au préalable et être capable de prendre du recul par rapport au scénario qu'il privilégie. Toute l'expérience du responsable de l'équipe IR (appelé par la suite coordinateur IR) réside dans la décision de se détacher d'un scénario qui ne colle pas aux données recueillies.

Quelle doit donc être l'état d'esprit de l'équipe IR lorsqu'un de ses binômes présente un scénario ?

Après plusieurs tâtonnements, j'en suis venu à considérer que la meilleure attitude consistait à écouter la ou les hypothèses, puis à chercher à les démolir à l'aide de toute les objections possibles et imaginables. Le coordinateur IR et le reste de l'équipe IR se doivent donc de critiquer le scénario construit par le binôme IR. Ceci va à l'encontre de toute règle sociale et peut mettre en danger la cohésion d'une équipe IR non entrainée à cette pratique !

Le processus de réfutation doit pour cela être facilité par le binôme IR qui doit faire en sorte de présenter son scénario de manière à permettre justement son démenti. Ceci demande beaucoup d'entrainement et ressemble, pour une oreille non avertie, à de la langue de bois !

Mais cela ne suffit pas. Mon opinion est la suivante :

La formulation d'une critique n'est possible que dans une équipe IR ouverte, dans laquelle l'information circule librement.

L'un des meilleurs moyens que je connaisse consiste à faire tourner le rôle de coordinateur IR, facilitant à la longue une libre expression, là où une hiérarchie trop stricte ne ferait que la museler.

On est là à des années lumières de l'image convenue de la cellule de crise : le sombre capitaine, seul maitre à bord au milieu de la tempête, qui dicte ses ordres à une équipe disciplinée, au fil de son intuition... Les plus gros désastres, que j'ai d'ailleurs pu observer au cours de ma carrière, provenaient souvent de ce genre de configuration, si prisée dans les films d'actions. Mais, je m'égare encore...

Personne n'aime faire l'objet de critique, surtout après une vingtaine d'heures de travail acharné. Enfin, notre éducation fait que l'on hésite toujours à critiquer la travail d'un proche. Le rôle du coordinateur IR est donc d'encourager ce genre d'aptitude. Le plus dur à vaincre reste la peur du ridicule devant ses pairs, si une réfutation parait complètement farfelue.

Finalement, les meilleures équipes IR que j'ai pu rencontrer ressemblaient d'avantage à un cercle de joueurs de poker, plutôt qu'à une section d'infanterie de la Grande Armée ! Quant à l'image que peut avoir une telle équipe au sein d'une organisation, ceci est une autre histoire. :-)