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?