ha! mommy told me that 32bit is vulnerable to bruteforcing :).
En esta prueba hay que debuggear bastante para comprender que está pasando.
Al principio parecía que solo era crear un overflow y sobreescribir una variable para lograr el objetivo de la comparativa del if, pero resultó diferente, veamos.
vamos a empezar a analizar la función welcome().


Con esto podemos ver donde empieza todo, que es donde te pide tu nombre en name.
Pero veamos esto, en el código menciona que name utiliza un array de 100 y podemos ver que scanf tiene edx,[ebp-0x70] y 0x70 no son 100, serían 112, pero veamos más arriba.

entonces 0x70 - 0xc = 64 (100 bytes).
Veamos si es cierto, vamos a ver que pasa si agregamos datos.


Efectivamente, se sobreescriben los 100 bytes, pero vemos algo interesante, ebp-0x10 tiene los ultimos datos y veamos en login.

Podemos observa como en login se reutiliza ebp-0x10, lo que significa que se puede sobreescribir 4 bytes (0x45444444), que son 96 + 4 = 100, pero los ultimos 4 bytes podemos sobreescribirlos porque es un entero, veamos.

Efectivamente son 4 bytes porque es un integer.
Vamos a hacerlo directamente con python para empezar a hacer pruebas.


vamos a ver si es posible incluir 13371337.

Esto es por lo que mencionaba que no se podría solo sobreescribir y ya, habría que hacerlo mediante GOT ya que ya le protección de RELO es casi nula.
Vamos a comprobar que realmente se sobreescriba la siguiente variable que sería segun el código "passcode1".
ponemos un break en el siguiente scanf y veamos.

Obsevamos que edx toma lo que hay en ebp-0x10 y si lo mostramos aparece como 0x42424242.
Busquemos que GOT podría funcionar.

El unico que funcionaría sería flush, pero ¿cómo llegamos ahí?.
Pues cuando sobreescribimos passcode1, hacemos que scanf lo guarde en algun bloque de memoria, ya que scanf no esta bien definido, por ejemplo.
Si tu escribes...
int i
scanf("%d", &i)
Le estas diciendo que busque la dirección de int i para guardar en ese bloque de memoria datos en formato integer, pero si colocas esto.
int i
scanf("%d", i)
Le estás diciendo que guarde datos integer en cualquier dirección, así que si vamos a darle una dirección que nos convenga y datos integer.
Vamos a decirle que queremos que guarde datos en la dirección de flush y lo sobreescriba, para que cuando se ejecute, en vez de ejecutar el verdadero flush, hagamos que se ejecute otra dirección con otros datos, vamos a ver.
Primero veamos la dirección de flush.

Ok, hagamos el intento, primero colocamos la cantidad de overflow que son 96 bytes, después agregamos la dirección que será la de flush, y después los datos que tiene que escribir, recordemos que es un scanf("%d"), así que es un integer, tenemos que ponerle datos en enteros.
from pwn import *
p = process('./passcode')
payload = b'A'*96
payload += b'\x04\xa0\x04\x08'
payload += b'134514277'
p.send(payload)
p.interactive()

Bueno, con esto inyectamos un payload de 96 bytes, después le vamos a decir a scanf que busque la dirección de flush y ahí sobreescriba la dirección con los datos, en este caso hice primero la prueba con main para que se ejecute de manera repetitiva la aplicación, así que (134514277 -> 0x08048665(main)).
Pues si funcionó, ahora digamosle que vaya a system, no queremos que dañe system en ningun sentido, así que colocamos una dirección antes para que la siguiente ejecute system junto con la flag, y una antes sería (0x080485e3 -> 134514147).
Hice una flag que dice "lo lograste".


Ahora con el servidor.

Listo.