Conférence NDH 2009 sur GoRing0

14 mai 2009 – 0:50

Je me suis récemment lancé sur un nouveau projet perso, nommé GoRing0. Ce projet est parti d’une question existentielle que je me suis posée concernant les processus, ou plutôt les threads. Sous Linux et Windows, ceux-ci s’exécutent normalement en ring 3 (mode processeur userland), alors que les drivers s’exécutent en ring 0 (kernelland).  Ma question était la suivante : est-ce techniquement possible de passer un thread du ring 3 vers le ring 0 ? Attention, je ne parle pas de faire un appel à un code driver depuis un programme ring 3 par le biais d’une interruption ou d’un IOCTL, mais bien de passer une le code du thread lui-même en ring 0. Étant convaincu que la réponse à cette question est affirmative, je me lance dans la conception d’une preuve de concept : GoRing0.

GoRing0

GoRing0 est donc un rootkit qui a pour objectif de faire passer un thread en ring 0, et de le rebasculer accessoirement en ring 3 lorsqu’il le souhaite. Pour cela, celui-ci devra bien évidemment charger un driver, afin de s’élever les droits et de permettre une telle commutation. La partie utilisateur du rootkit pourrait se présenter sous la forme d’une librairie exportant deux fonctions principales : GoRing0() et GoRing3(), permettant le basculement en ring 0 et ring 3 respectivement. N’importe quel programme pourrait alors faire appel à ces fonctions et s’élever les droits à volonté. Je développe pour le moment sous Windows, mais idéalement, GoRing0 devrait être capable de fonctionner aussi bien sous sous Linux, la manipulation qu’il effectue étant surtout liée à l’architecture x86.

Le principe de fonctionnement de GoRing0 repose sur les interruptions. Les fonctions GoRing0() et GoRing3() déclenchent une interruption spécifique qui est hookée par le driver et qui se charge de modifier la valeur de CS empilée automatiquement par le processeur. En effet il se trouve que le ring courant du processeur (le CPL) est encodé dans les 2 premiers bits de CS ainsi que dans le descripteur de segment (dans la GDT) auquel il correspond. Plus intéressant encore, Windows définit deux valeurs spéciales de CS : une en userland (0x1b), et une en kernelland (0×8). Il suffit alors au handler d’interruption de substituer la valeur empilée de CS par la valeur kernelland pour passer le thread en ring 0 au retour d’interruption.

Pour le moment, j’ai un prototype fonctionnel stable : j’arrive à passer un thread en ring 0 et à le rebasculer en ring 3. Pour m’en assurer, je peux afficher la mémoire kernel depuis ce thread (adresses supérieures à 0×80000000 sous Windows). Cependant, lorsqu’un thread est en ring 0, il est impossible d’appeler des API Windows car celles-ci vérifient apparamment si le thread qui les appelle vient bien du ring 3. De même, il n’est pas possible d’appeler des fonctions du kernel depuis le thread même en ring 0, à moins d’en connaître l’adresse ou de la résoudre à l’exécution.

Nouvelle conférence à la Nuit Du Hack

Enfin, j’en viens à la véritable news de ce post… Au départ, je devais présenter une conférence sur XeeK et une autre sur InjecSO. Etant donné qu’InjecSO est sorti depuis un moment maintenant (avec la doc sur ce blog), que je me suis lancé dans ce nouveau projet, et que cette année il n’y a pour l’instant aucune conférence orientée kernel, j’ai pensé intéressant de remplacer la conférence sur InjecSO par une sur GoRing0. Je compte y présenter le projet et par la même occasion de présenter rapidement l’architecture x86 et le développement en mode kernel aux débutants en la matière. Ceux pour qui les concepts d’interruption, segments et autre GDT sont du chinois (autrement dit ceux qui n’ont pas compris le paragraphe technique ci-dessus…) sont les bienvenus, je compte justement expliquer tout cela ! Ca sera de plus l’occasion de releaser officiellement GoRing0 et de faire une petite démo. Sur ce, à la NDH !

  1. 3 réponses à “Conférence NDH 2009 sur GoRing0”

  2. Hello,
    Ton PoC existe déjà, yolejedi a implémente une DLL permettant d’exécuter un code en ring0 dans le même contexte que le thread ring3 original.

    Par sloshy le 14 mai 2009

  3. Salut
    En effet il semblerait qu’il ait eu une idée similaire. Par contre je doute qu’il n’utilise la même technique que moi. Utilise-t-il un driver, ou exploite-t-il une faille du kernel ?
    Quand tu dis que le code ring 0 s’exécute dans le même contexte, qu’entends-tu par « contexte » ? S’il s’agit juste du CR3 (définissant l’espace d’adressage virtuel), n’importe quel appel de driver classique le fera aussi vu que le CR3 n’est pas changé lors d’une interruption ou un IOCTL.
    Je vais jeter un coup d’oeil à sa PoC, ça a l’air intéressant. En tout cas merci de l’avoir signalé, car j’avais déjà cherché des outils du genre et je n’avais pas trouvé.

    Par Emilien Girault le 15 mai 2009

  4. Yolejedi et toi même avez de meilleur connaissance que moi, je suppose que tu pourra repondre a ces questions une fois que tu aura regarde ça de plus près.

    donne tes réponses ici si tu veux bien, ça m’interresse.

    Par sloshy le 16 mai 2009

Désolé, les commentaires sont fermés pour le moment.