Modificar código C con vulnerabilidad de desbordamiento de búfer para omitir código

7

Estoy tratando de encontrar una manera de explotar la vulnerabilidad de desbordamiento del búfer en el siguiente código fuente para que la línea, printf ("x es 1") se omita:

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

void func(char *str) {
     char buffer[24];
     int *ret;
     strcpy(buffer,str);
}

int main(int argc, char **argv) {
    int x;
    x = 0;
    func(argv[1]);
    x = 1;
    printf("x is 1");
    printf("x is 0");
    getchar();
}

Para hacer esto, quiero modificar la función "func". Sé que necesitaré usar la variable ret para modificar la dirección de retorno y pasar la línea que quiero omitir, pero no estoy seguro de cómo hacerlo.

Al usar gdb, pude encontrar las siguientes llamadas en la función principal:

Temporary breakpoint 1, 0x00000000004005ec in main ()
(gdb) x/20i $pc
=> 0x4005ec <main+4>:   sub    $0x20,%rsp
   0x4005f0 <main+8>:   mov    %edi,-0x14(%rbp)
   0x4005f3 <main+11>:  mov    %rsi,-0x20(%rbp)
   0x4005f7 <main+15>:  movl   $0x0,-0x4(%rbp)
   0x4005fe <main+22>:  mov    -0x20(%rbp),%rax
   0x400602 <main+26>:  add    $0x8,%rax
   0x400606 <main+30>:  mov    (%rax),%rax
   0x400609 <main+33>:  mov    %rax,%rdi
   0x40060c <main+36>:  callq  0x4005ac <func>
   0x400611 <main+41>:  movl   $0x1,-0x4(%rbp)
   0x400618 <main+48>:  mov    $0x4006ec,%edi
   0x40061d <main+53>:  mov    $0x0,%eax
   0x400622 <main+58>:  callq  0x400470 <printf@plt>
   0x400627 <main+63>:  mov    $0x4006f3,%edi
   0x40062c <main+68>:  mov    $0x0,%eax
   0x400631 <main+73>:  callq  0x400470 <printf@plt>
   0x400636 <main+78>:  callq  0x400490 <getchar@plt>
   0x40063b <main+83>:  leaveq
   0x40063c <main+84>:  retq
   0x40063d:    nop

Aunque, estoy confundido en cuanto a dónde ir desde aquí. Sé que la función regresará a la línea de 0x400611 y que necesito hacer que salte a 0x400631, pero no estoy seguro de cómo determinar cuántos bits saltar. He estado tratando de seguir el ejemplo 3 de insecure.org/stf/smashstack.html pero me he perdido cuando se trata de averiguar cuántos bits debo ajustar mi variable. ¿Alguna ayuda?

    
pregunta user2276280 16.04.2015 - 03:36
fuente

2 respuestas

4

Como ya se ha identificado, deberá volver a la dirección 0x400631. Cuando rompes la pila con tu argumento debes controlar EIP. Es decir:

./a.out AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Debería ver el EIP de 0x41414141. Ahora necesita determinar dónde se ubican los 4 bytes que se convierten en EIP en su pila de A's. Puede usar herramientas como metasploit's pattern_create.rb / pattern_offset.rb o ya que es un búfer tan pequeño que puede hacerlo manualmente:

./a.out AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTT

Y en función de la dirección de EIP, ahora puede determinar si es A (x41), B (x42), C (x43), etc. Esto le dirá cuántos bytes debe colocar antes de \ x31 \ x06 \ x40 \ x00. Por supuesto, esto no es un exploit confiable ya que la dirección de retorno está codificada, pero será suficiente para su ejemplo de aprendizaje.

    
respondido por el wireghoul 16.04.2015 - 06:07
fuente
-2

mientras no esté de acuerdo con su plan,

la forma de omitir una instrucción es modificar el valor de registro de PC de las personas que llaman, que se guarda en la pila de funciones llamadas

Por lo tanto, saltarse una instrucción es bastante simple, porque el tamaño de la instrucción (en las CPU modernas) es relativamente consistente.

Sin embargo, omitir una línea de código C es un problema completamente diferente porque la línea podría contener cualquier número de instrucciones.

Una serie de instrucciones que pueden cambiar según los parámetros del compilador, como el nivel de optimización.

    
respondido por el user3629249 16.04.2015 - 05:21
fuente

Lea otras preguntas en las etiquetas