web-dev-qa-db-fra.com

L'exploitation du débordement de tampon conduit à un défaut de segmentation

J'essaie d'exploiter une vulnérabilité de débordement de pile simple. J'ai un code de base en c:

#include <cstring>
int main( int argc, char** argv )
{
        char buffer[500];
        strcpy(buffer, argv[1]);
        return 0;
}

compilé à l'aide de -fno-stack-protector. J'ai déjà compris la longueur du tampon et j'ai réussi à écraser les registres EBP et EIP. J'ai injecté un grand nombre de NOP, suivi de ce code Shell et finalement inséré une adresse où se trouvent les NOP injectés pour que le code soit exécuté.

Maintenant, le problème. Sur l'image ci-jointe, vous pouvez voir la sortie gdb. Si j'exécute mon programme avec une entrée malveillante, il obtient un SIGSEGV. Dump de l'adresse 0xbffff880 vous pouvez voir qu'il y a beaucoup de NOP suivis du code Shell (case rose) et enfin de l'adresse (case bleue).

J'ai pensé que cela fonctionnerait comme suit: Au début, le 0x90909090s et le shellcode sont considérés comme de simples données. Après ceux-ci (après la case rose), il y a une adresse 0xbffff880. Je dis au cpu "hé là, maintenant veuillez exécuter ce qui est sur 0xbffff880 ". Le processeur prend ce qui est sur l'adresse et exécute tous les NOP et le shellcode lui-même. Cependant, cela ne se produit pas et SIGSEGV se produit.

Où je me trompe?

gdb output

J'essaye de réaliser ceci sur l'instance Virtualbox d'Ubuntu 14.04 Linux 3.13.0-39-i686 générique 32 bits avec ASLR désactivé.

22
tsusanka

Votre adresse mémoire 0xbffff880 Est très probablement non exécutable, mais uniquement en lecture/écriture. Il existe plusieurs façons de surmonter ce problème.

  1. S'il s'agit d'une adresse de pile, vous pouvez utiliser -z execstack Lors de la compilation. Cela rendra essentiellement toute la mémoire de la pile exécutable.
  2. Pour une solution plus robuste, vous pouvez écrire le shellcode pour appeler mprotect sur l'adresse à laquelle vous écrivez.

Par exemple, la ligne suivante marquera l'adresse 0xbffff880 En lecture/écriture/exécutable.

mprotect((void*) 0xbffff880, buffer_len, PROT_READ | PROT_WRITE | PROT_EXEC);

-fno-stack-protector ne signifie pas que la pile sera exécutable. Il désactive uniquement d'autres fonctionnalités de sécurité telles que les canaris ou empiler les cookies . Si ces valeurs sont écrasées (avec un débordement de tampon) lors de leur vérification, le programme échouera. Cela ne permettrait pas d'activer l'exécution de votre tampon.

24
RoraΖ

Comme l'a dit RoraZ, votre pile n'est pas exécutable. Pour développer cela, un exploit de débordement de tampon comme celui-ci ne fonctionnera pas sur une boîte Linux moderne à moins que le binaire ne soit compilé pour autoriser de tels manigances. Vous devrez désactiver un certain nombre de fonctions de sécurité; RELRO, STACK CANARIES, NX, TARTE.

Il existe un script Nice bash appelé checksec.sh ( http://www.trapkit.de/tools/checksec.html ) qui peut vous aider à vérifier le binaire, par exemple:

enter image description here

La façon dont je compile un binaire pour le test de débordement de tampon x86:

gcc -m32 -g -mpreferred-stack-boundary=2 -no-pie -fno-stack-protector -Wl,-z,norelro -z execstack ./program.c
  1. -no-pie: désactiver PIE (exécutable indépendant de la position)
  2. -z execstack: pour désactiver NX (rendre la pile exécutable)
  3. -Wl, -z, norelro: désactiver RELRO (relocations en lecture seule)
  4. -fno-stack-protector: supprime la protection de la pile (vérifications de sécurité de débordement de pile)

Et pour plus de commodité:

-g: ajouter le débogage

-mpreferred-stack-bounary = 2: aligner la pile sur la limite de 4 octets

1
sf_admin