https://exploit.education/phoenix/stack-zero/
#define BANNER \
"Welcome to " LEVELNAME ", brought to you by https://exploit.education"
char *gets(char *);
int main(int argc, char **argv) {
struct {
char buffer[64];
volatile int changeme;
} locals;
printf("%s\n", BANNER);
locals.changeme = 0;
gets(locals.buffer);
if (locals.changeme != 0) {
puts("Well done, the 'changeme' variable has been changed!");
} else {
puts(
"Uh oh, 'changeme' has not yet been changed. Would you like to try "
"again?");
}
exit(0);
}
Version de 32bits
Utilizamos GDB para debuggearlo, podemos intentar entender como funciona y si es explotable.

Podemos observar varios detalles interesantes.

Los dos ultimos puts tienen cadena de caracteres, y el primero es el que nos interesa, hace un push en la pila (0x80485ac) e invoca un call a puts seguido de un jmp para llegar a exit y terminar el programa.
También podemos obervar que para llegar a esa dirección, gets mete a eax algunos bytes cuando escibimos el mensaje que nos pide, pero justo después mete en eax un 0x0, que anteriormente se guardo en [ebp-0xc],0x0... lo que significa que el primer push mete a la pila bytes, después pone a eax en 0 y al hacer la comparación siempre será negativa la respuesta 1 != 0.


¿Y qué pasa si modificamos a eax antes de que haga la comparación y le ponemos 1?.

Bueno, llevemoslo a la práctica.
Hay que tener en cuenta algo, si observan, en la base (EBP) se encuentra [ebp-0xc], 0x0 y luego se encuentra un lea eax,[ebp-0x4c] que es un espacio para gets, entonces 0x4c - 0xc = 40hex o (64 decimal).

eso significa que con 65 logramos el objetivo, veamos...

Listo.
Version de 64bits
Utilizamos GDB para debuggearlo, podemos intentar entender como funciona y si es explotable.

Podemos observar varios detalles interesantes.

El puts que nos interesa es (0x4006d0) y para poder llegar tenemos que lograr que eax se sobreescriba para que je no salte a (0x400708) y terminar el programa.
Como se puede observar mete 0x0 a rbp-0x10 eso lo compara y si es efectivamente es 0x0, entonces salta, así que hay que cambiarlo.

Se puede observar lo que sucede si le ponemos 1 a rax.
Bueno, llevemoslo a la práctica.
Observa lo que sucede si le ponemos una cadena de 64 letras y otra de 65.
Eso significa que con 65 logramos el objetivo, veamos
Listo.
Version de ARM
Utilizamos GDB para debuggearlo, podemos intentar entender como funciona y si es explotable.

Podemos observar varios detalles interesantes.

El puts que nos interesa es (0x10570) y para poder llegar tenemos que lograr que r3 se sobreescriba para que beq no salte a (0x10574) y terminar el programa.
Como se puede observar mete 0x0 a r1 eso lo compara y si efectivamente es 0x0, entonces salta, así que hay que cambiarlo.

Se puede observar lo que sucede si le ponemos 1 a r3.
Bueno, llevemoslo a la práctica.
Observa lo que sucede si le ponemos una cadena de 65.
Eso significa que con 65 logramos el objetivo, veamos
Listo.
Version de ARM64
Utilizamos GDB para debuggearlo, podemos intentar entender como funciona y si es explotable.

Podemos observar varios detalles interesantes, aquí hay uno muy importante que hay poner atención, antes de que leas el detalle, trata de encontrar la diferencia entre ARM y ARM64 para encontrar el puts.

El puts que nos interesa es (0x7b0) y para poder llegar tenemos que lograr que w0 se sobreescriba para que b.eq no salte a (0x400708) y terminar el programa.
Para poder encontrar los puts, se debe hacer algo interesante, hay unos adrp que coloca 0x400000, y en add coloca #0x760, eso se debe sumar y por eso queda 0x400760.
Como se puede observar mete 0x0 a w0, donde se ve que simplemente usa wzr para asumir que en [x29, #104] tiene de valor 0, sería, llenar de ceros el registro x29, luego meterlo en el registro w0 para usarlo en cmp w0, #0x0, y eso lo compara y si efectivamente es 0x0, entonces salta, así que hay que cambiarlo.
Hay que recordar que estamos usando 64bits, los registros son de x0-x30, y los de 32bits son d w0-w30

Se puede observar lo que sucede si le ponemos 1 a x0.
Bueno, llevemoslo a la práctica.
Observa lo que sucede si le ponemos una cadena de 65.
Eso significa que con 65 logramos el objetivo, veamos
Listo.