explication du code "Red Pill" / instruction SIDT

explication du code "Red Pill" / instruction SIDT - C - Programmation

Marsh Posté le 08-07-2006 à 23:04:32    

Sur ce blog très intéressant (http://invisiblethings.org/papers/redpill.html) consacré aux roots-kits il y a un morceau de code dont je ne comprends pas le fonctionnement :
 

Code :
  1. int swallow_redpill () {
  2.        unsigned char m[2+4], rpill[] = "\x0f\x01\x0d\x00\x00\x00\x00\xc3";
  3.        *((unsigned*)&rpill[3]) = (unsigned)m;
  4.        ((void(*)())&rpill)();
  5.        return (m[5]>0xd0) ? 1 : 0;
  6.      }

 
 

The heart of this code is actually the SIDT instruction (encoded as 0F010D[addr]), which stores the contents of the interrupt descriptor table register (IDTR) in the destination operand, which is actually a memory location. What is special and interesting about SIDT instruction is that, it can be executed in non privileged mode (ring3) but it returns the contents of the sensitive register, used internally by operating system.


 
 
L'idée est de déclencher une instruction SIDT mais je ne comprends pas comment cette fonction y parvient. Quelqu'un pourrait-il me décomposer le contenu de la fonction ? (ou au moins me donner un indice). Merci !


---------------
rule #1 : trust the python
Reply

Marsh Posté le 08-07-2006 à 23:04:32   

Reply

Marsh Posté le 08-07-2006 à 23:46:52    

Bon, je vais essayer de répondre, mais je ne garantis rien, si quelqu'un de plus expérimenté veut confirmer/infirmer...
 

Code :
  1. int swallow_redpill () {
  2.        unsigned char m[2+4], rpill[] = "\x0f\x01\x0d\x00\x00\x00\x00\xc3";  /* les 3 premiers char de rpill corrsponde à 0X0F010D, code de l'instruction SIDT */
  3.        *((unsigned*)&rpill[3]) = (unsigned)m;   /* là, c'est tricky: on écrese les 0 de queue de rpill par l'adresse de m, qui va contenir la valeur du registre IDTR */
  4.        ((void(*)())&rpill)();   /* appel effectif de l'instruction IDTR en spécifiant l'adresse utilisée pour le mémoriser la valeur du registre en question */
  5.        return (m[5]>0xd0) ? 1 : 0;  /* on compare la valeur renvoyée reflétant le contenu du registre en question */
  6. /* s'il est supérieure à une certaine valeur, c'est que c'est l'adresse a été fournie par une machine virtuelle, donc qu'on tourne sur un OS virtuel. Apparemment, ce code dépend de la machine virtuelle, d'où sa conclusion qu'on peut l'utiliser pour faire du fingerprinting (un peu comme nmap) */
  7.      }

 
 
Conclusion: en fait, elle bidouille du code en C en pour appeller l'instruction en question en passant par son code hexa (elle concatène l'instruction avec son paramètre, et marque la fin avec '\xc3' dans rpill), sans passer par de l'assembleur : rpill représente l'instruction qui va être appellée, ensuite elle compare la valeur retournée par l'instrcution à une valeur limite pour vérifier si on tourne sur une VMM
Je ne sais pas pourquoi elle n'utilise pas de l'assembleur.


Message édité par simple_stupid le 08-07-2006 à 23:48:39
Reply

Marsh Posté le 08-07-2006 à 23:48:32    

Reply

Marsh Posté le 08-07-2006 à 23:53:05    

0x90 a écrit :

pour que ca reste portable.


Ouais, j'y ai pensé, mais de toute façon ça ne tourne que sous Intel, et ça dépend de la VMM utilisée.
 
SInon, je tiens à préciser que cette Johanna a récemment trouvé un "proof of concept" permettant de faire des root-kits invisibles, dans certaines conditions:
 
http://linuxfr.org/2006/07/04/21062.html
 
Ses travaux n'ont pas encore été vérifiés.

Reply

Marsh Posté le 09-07-2006 à 10:16:17    

> simple_stupid : merci pour tes explications, elles sont très claires.


---------------
rule #1 : trust the python
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed