Cómo explotar un desbordamiento de pila sin configurar -mpreferred-stack-boundary = 2

3

He estado jugando con algunos juegos de guerra y también porté algunos de ellos en mi máquina Linux. Noté que cuando no se usa -mpreferred-stack-boundary = 2, gcc podría compilar "main" con un interesante prólogo / epílogo: efectivamente "confiando en $ ecx (que se basa en $ ebp-4) para el valor de $ esp antes de ret". ¿Alguien más ha encontrado esta observación?

Esto significa que no puede sobrescribir la dirección ret normal que se mantiene en $ ebp + 4, sino que debe sobrescribir $ ebp-4 (es decir, ecx) y volver a colocar el puntero de pila y su dirección de devolución (utilizando efectivamente un pivote de pila) para promover la explotación.

Encuentre un código de ejemplo y un ensamblaje relacionado a continuación:

$ cat stack4.c
/* stack4-stdin.c                               *
 * specially crafted to feed your brain by gera */

#include <stdio.h>

int main() {
    int cookie;
    char buf[80];

    printf("buf: %08x cookie: %08x\n", &buf, &cookie);
    gets(buf);

    if (cookie == 0x000d0a00)
        printf("you win!\n");
}

$ objdump -D ./stack4_normal | grep -A31 main.:
0804845b <main>:
 804845b:   8d 4c 24 04             lea    0x4(%esp),%ecx
 804845f:   83 e4 f0                and    $0xfffffff0,%esp
 8048462:   ff 71 fc                pushl  -0x4(%ecx)
 8048465:   55                      push   %ebp
 8048466:   89 e5                   mov    %esp,%ebp
 8048468:   51                      push   %ecx
 8048469:   83 ec 64                sub    $0x64,%esp
 804846c:   83 ec 04                sub    $0x4,%esp
 804846f:   8d 45 f4                lea    -0xc(%ebp),%eax
 8048472:   50                      push   %eax
 8048473:   8d 45 a4                lea    -0x5c(%ebp),%eax
 8048476:   50                      push   %eax
 8048477:   68 50 85 04 08          push   $0x8048550
 804847c:   e8 8f fe ff ff          call   8048310 <printf@plt>
 8048481:   83 c4 10                add    $0x10,%esp
 8048484:   83 ec 0c                sub    $0xc,%esp
 8048487:   8d 45 a4                lea    -0x5c(%ebp),%eax
 804848a:   50                      push   %eax
 804848b:   e8 90 fe ff ff          call   8048320 <gets@plt>
 8048490:   83 c4 10                add    $0x10,%esp
 8048493:   8b 45 f4                mov    -0xc(%ebp),%eax
 8048496:   3d 00 0a 0d 00          cmp    $0xd0a00,%eax
 804849b:   75 10                   jne    80484ad <main+0x52>
 804849d:   83 ec 0c                sub    $0xc,%esp
 80484a0:   68 68 85 04 08          push   $0x8048568
 80484a5:   e8 86 fe ff ff          call   8048330 <puts@plt>
 80484aa:   83 c4 10                add    $0x10,%esp
 80484ad:   8b 4d fc                mov    -0x4(%ebp),%ecx
 80484b0:   c9                      leave
 80484b1:   8d 61 fc                lea    -0x4(%ecx),%esp
 80484b4:   c3                      ret

He encontrado varios temas de StackExchange y explicaciones sobre por qué sucede esto. Sin embargo, estoy buscando una guía / tutorial que trate específicamente con la parte de explotación. Quizás alguien más inteligente que yo haya estandarizado esta explotación de una manera mucho mejor que yo.

Parece que la mayoría de las personas, en los tutoriales, solo usan -mpreferred-stack-boundary = 2 para evitar este problema y continúan normalmente con el tutorial de explotación.

Me cuesta creer que nadie haya mencionado esto en un tutorial ya que las nuevas versiones de gcc se compilan de forma predeterminada (al menos en mi máquina).

En cualquier caso, la pregunta es:

  • ¿Es esta la forma óptima de explotar esto (usando un pivote de pila)?

  • Si no, ¿Alguien puede dirigirme a un tutorial o explicación de una mejor? manera?

pregunta nilminus 09.01.2016 - 21:04
fuente

0 respuestas

Lea otras preguntas en las etiquetas