SYSENTER, stepping into da ring0

février 4th, 2007 at 08:46 admin

Vous avez sans doute déjà rencontré cette instruction en tracant sous Olly sans vraiment trop vous y intéressé et pourtant c’est une des plus importante de votre OS. Que peut-elle bien faire pour être si importante et pourquoi elle semble ne rien faire. Ivanlef0u votre détective préféré s’est penché sur cette affaire.

Dans un call à une API native comme par exemple ZwCreateFile on peut voir :

7C91D682 >  B8 25000000     MOV EAX,25
7C91D687    BA 0003FE7F     MOV EDX,7FFE0300
7C91D68C    FF12            CALL NEAR DWORD PTR DS:[EDX] //EDX pointe sur 0x7C91EB8B
7C91D68E    C2 2C00         RET 2C

On arrive ici avec le call
7C91EB8B >  8BD4            MOV EDX,ESP
7C91EB8D    0F34            SYSENTER
7C91EB8F    90              NOP
7C91EB90    90              NOP
7C91EB91    90              NOP
7C91EB92    90              NOP
7C91EB93    90              NOP
7C91EB94 >  C3              RET

En fait l’instruction SYSINTER à pour rôle de de faire un appel système. Dans notre exemple le code qui sera lancé sera celui de NtCreateFile de ntoskrnl.exe. Bon c’est cool tout ca mais comment on sait qu’on appel NtCreateFile, hé bien vous voyez le « mov eax, 0×25″, 0×25 correspond à l’indice de la fonction dans la SSDT (System Service Descriptor Table), une sorte de table d’exportation pour les fonctions systèmes.

Par contre l’appel à la SSDT n’est pas fait directement par SYSENTER, une routine du noyau (KiSystemService) se charge de retrouver l’adresse de la fonction dans la SSDT. Alors comment fait donc SYSENTER pour jumper sur KiSystemService ? En fait elle utilise les MSR (Model Specific Register), ceux-ci servent à des opérations spéciales sur le processeur. L’intruction SYSENTER utilise les 3 suivants :
- MSR_SYSENTER_CS 0×00000174
- MSR_SYSENTER_ESP 0×00000175
- MSR_SYSENTER_EIP 0×00000176
Voir le manuel « Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 2B Instruction Set Reference, N-Z »
Le MSR_SYSENTER_EIP contient l’adresse de la fonction KiSystemService (0x0804de6f0 chez moi), on trouve dans le MSR_SYSENTER_ESP l’adresse de notre nouvelle Kernel stack (0x0f88ab000 chez moi) enfin le nouveau segment de code MSR_SYSENTER_CS celui-ci n’a pas vraiment d’utilité.

Avant les appels systèmes étaient effectué avec l’interruption int 0x2E, SYSENTER la remplacé pour des raisons de rapididé.

Alors imaginons qu’on puisse modifier ces fameux MSR :), on pourrait donc faire exécuter notre code en ring0 !
He bien cela est possible ! Avec l’API natice NtSystemDebugControl on peut lire et écrire les MSR.
On lui donne une petite structure :

typedef struct _MSR_STRUCT {
DWORD MsrNum;            // MSR number
DWORD NotUsed;            // Never accessed by the kernel
DWORD MsrLo;            // IN (write) or OUT (read): Low 32 bits of MSR
DWORD MsrHi;            // IN (write) or OUT (read): High 32 bits of MSR
} MSR_STRUCT, *PMSR_STRUCT;

Structure formée par Reversing du ntoskrnl evidemment …

Apràs il suffit de sauvegarder le MSR_SYSENTER_EIP courant puis on lui dit de pointer sur le morceaux de code que l’on veut lancer en ring0, on appel SYSENTER et hop ! Pour quitter on n’oublie pas de le restaurer bien sur !!!!

Bon clairement il faut codé un shellcode ring0, le mien ne fait que retrouver l’adresse de la structure ETHREAD courante mais au final on peut faire ce qu’on veut dans notre noyau, suffit de s’y mettre :}

Voici le code avec pas mal d’infos dedans et le binaire.
http://ivanlef0u.fr/repo/MSR.rar
Have fun.

Entry Filed under: Non classé

4 Comments

  • 1. Touronster  |  février 27th, 2007 at 17:24

    salut, petite rectification :
    en ce qui concerne les syscalls windows, avec un sysenter, on ne jump pas directement dans KiSystemService, MSR_EIP pointe en réalité sur KiFastCallEntry, qui par la suite pushera des données sur la pile et appelera KiSystemService qui lui appelera le service en question.

    Sinon c’est cool.. salut !


  • 2. admin  |  février 27th, 2007 at 23:22

    Exact on peut le voir sous le kd avec :
    kd> ln 0804de6f0
    (804de6f0) nt!KiFastCallEntry
    merci :)


  • 3. Ivanlef0u’s Blog &r&hellip  |  novembre 2nd, 2007 at 16:46

    [...] cette opération est de faire appel à l’instruction SYSENTER, je vous laisser lire le post SYSENTER, stepping into da ring0. Il existe d’autres façons de passer en ring0, une méthode que je trouve assez peu connu [...]


  • 4. Null  |  octobre 19th, 2011 at 15:52

    Iop, en fait, je crois que la suite d’appels est :

    - SYSENTER
    - KiFastCallEntry
    - ZwFonction
    - KiSystemService
    - NtFonction


Trackback this post


Calendar

décembre 2017
L Ma Me J V S D
« fév    
 123
45678910
11121314151617
18192021222324
25262728293031

Most Recent Posts