GNU/Linux >> Tutoriels Linux >  >> Linux

ROP du noyau Linux - Retour au mode utilisateur à partir du contexte du noyau ?

J'ai fini par écrire mon shellcode d'une manière différente. Comme je ne savais pas comment revenir, j'ai laissé le noyau faire le gros du travail pour moi, en retournant en mode utilisateur. L'idée était d'exécuter mon bit d'escalade de privilèges et de revenir à l'endroit où la fonction vulnérable était censée revenir, avec les registres et la pile réparés.

Dès que le noyau est revenu de la fonction vulnérable (quand il n'était pas débordé), j'ai remarqué quelque chose via gdb . (Les adresses sont imaginaires, mais expliquent le concept de toute façon.)

(gdb) x/i $eip
0xadd1: ret
(gdb) x/xw $esp
0xadd1: 0xadd2
(gdb) x/6i 0xadd2
0xadd2: add esp,0x40
0xadd3: pop ...
0xadd4: pop ...
0xadd5: pop ...
0xadd6: pop ...
0xadd7: ret

Ainsi, immédiatement après le retour, 0x40 octets de pile sont inutilisés et disparaîtrait simplement avec le add esp instruction. Ainsi, profitant de ce fait, j'ai construit une chaîne ROP (je l'avais déjà construite en écrivant cette question, son travail consistait à désactiver SMEP et à passer à mon shellcode userland), qui faisait 24 octets de long. 4 octets écraseraient l'EIP au moment du retour, et les 20 octets restants (0x14 ) le suivrait directement dans la pile inutilisée. Cela nous laisse avec 0x2c octets de pile inutilisés encore.

Mais si nous retournions à 0xadd2 , nous risquerions de perdre encore 0x14 octets d'informations précieuses sur les registres de la pile et en remplissant les registres avec des données invalides. Nous pourrions add 0x2c à esp dans notre shellcode userland, et passez directement à 0xadd3 , en sautant le add réel instruction.

Notant également à partir de la session de débogage, tout sauf eax et ebx étaient restaurés correctement. Comme mon débordement les avait détruits tous les deux, j'ai dû les restaurer avec des valeurs similaires aux cas où la fonction effectuait un retour propre. (C'était simple :j'ai défini un point d'arrêt à 0xadd2 , et extrait les valeurs de info reg )

Donc, mon dernier shellcode userland était celui-ci :

Execute privesc payload -> add esp,0x2c -> register fixup -> jump to 0xadd3

Ce faisant, le chemin du code est revenu parfaitement propre et le noyau s'est chargé de revenir en mode utilisateur pour moi.


Linux
  1. Pilote de périphérique du noyau Linux vers DMA à partir d'un périphérique dans la mémoire de l'espace utilisateur

  2. Comment charger les modules du noyau Linux à partir du code C ?

  3. Appeler une fonction de l'espace utilisateur à partir d'un module du noyau Linux

  4. Déréférencement du pointeur NULL du noyau Linux dans memset à partir de kzalloc

  5. Comment puis-je réserver un bloc de mémoire à partir du noyau Linux ?

Comment construire le noyau Linux à partir de zéro {Guide étape par étape}

Le noyau Linux contre. Mac noyau

Du rêve à la réalité :comment Linux a changé ma vie

Travailler avec Microsoft Exchange à partir de votre bureau Linux

Comment construire le noyau Linux à partir de zéro

Comment compiler le noyau Linux à partir de la source pour créer un noyau personnalisé