papers

"Share your knowledge. It’s a way to achieve immortality." - Dalai Lama

View on GitHub

De la réalité à la virtualité

Alors pilule rouge ou pilule bleue ?

Non désole cette article ne va pas parler de cette trilogie où ils ont utilisé Nmap. A ce jour on ne sait toujours pas pourquoi d’ailleurs ?

La virtualité, une chose tant convoité par l’humain. Il n’y a qu’à regarder l’essor que connais les MMORPG depuis quelques temps pour comprendre qu’une vie virtuelle est tellement réjouissante pour le moral humain.
« Rêve ta vie en couleur, c’est le secret du bonheur. » Peter Pan connaissait t-il déjà les vies virtuelles ?
Les statisticiens ( pour une fois qu’ils servent … ) de chez Gartner annonce qu’en 2011, 80% des internautes auraient une seconde virtuelle.

Tout ça pour annoncer le sujet de ce petit article. Naviguant sur le Web je tombe sur un article paru dans Phrack #63 qui annonçait les rootkits de 4ème génération. Oui je suis en retard :) mais mieux vaut tard que jamais. La technique proposée par Sherri Sparks et Jamie Butler est intitulée Virtual memory Subversion.

I. Relations entre mémoire physique et mémoire virtuelle

Pour commencer la mémoire physique est découpée en bloc appelés cadres et la mémoire virtuelle découpée par blocs de même tailles appelés pages.
Sous Windows les tailles peuvent être de 4Ko ou 4Mo par blocs. Pour que le processeur sache à quelle cadre fait référence une certaine page, il utilise un système structuré par des PDE et PTE.
( PDE : Page Directory Entry , PTE : Page Table Entry )

Voici les structures de ceux ci :

Structures PDE PTE

Comme vous pouvez le remarquez, elles sont très semblables. Voici les champs les plus importants pour nous :

Vous devez pensez c’est joli mais si on cherche a quel cadre fait référence notre page alors qu’on ne sait toujours pas où est stocker le page directory d’un processus dans la mémoire physique. Mais si on le sait :) l’adresse est stockée dans la structure EPROCESS de notre processus ou tout simplement dans le registre CR3 lorsque que le processeur est dans le contexte de notre processus.
Mais pour nous simple utilisateur de la mémoire virtuelle, les choses sont faites pour que le page directory du processus courant soit mappé en 0xC0300000 et les page tables en 0xC0000000. Les pages tables sont mappées les unes a la suite des autres en respectant l’ordre du page directory.
Donc comment avoir à quelle entrée correspond une certaine adresse virtuelle, cela est simple. Les 10 premiers bits de l’adresse virtuelle est l’index dans le page directory du processus, les 10 suivant sont l’index dans la table page et les 12 suivant l’offset dans la page. Donc le page directory et une page table contiennent tout les deux 1024 entrées.

Récapitulons par un schéma.

Représentation de la mémoire virtuelle

II. But et principe

Le but de la technique est de pouvoir cacher une zone mémoire choisie. Imaginez un scan de la mémoire virtuelle qui voit seulement des NOP alors que l’exécution sur cette partie mémoire produit bel et bien quelque chose.

Le principe est assez simple : modifier un PTE pour faire croire que le cadre concerné est swappé, à ce moment la une interruption 0E est générée et donc le gestionnaire des défauts de page prend le relais. A nous de modifier la routine appelé lors d’un défaut de page pour faire ce que nous voulons.

Il existe plusieurs techniques possibles pour effectuer cela :

La première est celle proposée dans l’article phrack, c’est à dire de désynchroniser les TLB séparés intégré dans les processeurs actuels.

Le TLB ( Translation Lookaside Buffer ) contient les translations d’adresses déjà effectué auparavant. Avant de faire une translation d’adresse virtuelle en adresse physique le processeur cherche dans le TLB si cette translation n’est pas en cache, si ce n’est pas le cas alors celui ci effectue la translation et la met par la suite dans le TLB.

Le TLB est séparé en un Data TLB et un Instruction TLB, tout les deux en temps normal sous Windows doivent pour une page donnée avoir une translation sur le même cadre.

Comment influer sur le TLB :

Donc voila comment les auteurs de l’article procèdent :

La deuxième méthode décrite dans plusieurs articles consiste a jouer avec le mode single step de notre processeur. Avec cette méthode il faudrai faire deux hooks d’interruption au lieu d’un. Par contre au lieu de charger une entrée dans le TLB nous même, une fois la page mise présente au niveau du PTE avec la routine qui gère les défauts de page, il suffit d’activer le mode single step et redonner la main au programme cible. A ce moment la, après l’exécution de l’instruction qui a provoqué le défaut de page une interruption 01 est générée par le mode single step. Maintenant c’est a notre routine, qui remplace soigneusement celle d’origine, de modifier a nouveau le PTE pour que les futures accès à notre page soit filtré.

Encore deux petits schémas ( 1ère méthode et 2ème méthode ) pour mieux comprendre :

Technique 1 Technique 2

III. Préparation

Première chose à penser, comment faire un hook d’une interruption logiciel. Pour cela il va falloir modifier l’IDT ( Interruption Descriptors Table ), l’emplacement de cette table est stocké dans le registre IDTR qui est récupérable a l’aide de l’instruction sidt suivi d’un pointeur sur un emplacement de 6 octets.

Le registre a la constitution suivante :

IDT

Les 32 bits de poids fort contiennent l’adresse linéaire de l’emplacement de l’IDT et les 16 suivant contiennent la taille de la table.

L’IDT est, comme son nom l’indique, constituée de descripteurs d’interruption. Ces descripteurs sont constitué de la manière suivante :

Donc il suffira que nous modifions le premier et le dernier champs pour faire un hook d’une interruption.

Deuxième chose à préparer, quelles informations sont passées lors d’un appel d’un gestionnaire d’interruption.

Jetons encore un coup d’oeil au manuel Intel. Voila les informations que nous pouvons rassemblées.

StackInt

L’information qui nous intéresse le plus est l’EIP qui pointe sur l’instruction provoquant le défaut de page, elle se trouvera donc en ESP + 4.

Source

References:
http://www.phrack.org/archives/63/p63-0×08_Raising_The_Bar_For_Windows_Rootkit_Detection.txt
http://www.i.u-tokyo.ac.jp/edu/training/ss/msprojects/data/05-x86TrapsInterruptsExceptions.pdf 
http://cairo.cs.purdue.edu/pubs/dsn07-codeinj.pdf
http://www.phrack.org/archives/63/p63-0×08_Raising_The_Bar_For_Windows_Rootkit_Detection.txt
http://www.scs.carleton.ca/~paulv/papers/IEEE-extended.7april05.pdf
http://www.acm.uiuc.edu/sigmil/talks/shadowwalker/Shadow+Walker+Talk.pdf