intmain() { setvbuf(stdout, NULL, _IONBF, 0); printf("Welcome to the Baby Pwn challenge!\n"); printf("Address of secret: %p\n", secret); vulnerable_function(); printf("Goodbye!\n"); return0; }
No need to even look at the binary’s protections here – this is a simple, easy ret2win.
We have a buffer overflow on buffer, allowing us to overwrite the saved RIP, as 128 bytes are read into a 64 byte buffer. Also, he program leaks the address of secret(), so we can just write that to saved RIP!
The first (commented-out) line, when we run the binary with GDB attached, will give us the offset in our input where the saved RIP is. The next two lines use that information to overwrite the saved RIP with the address of secret() (turns out you don’t even need the program’s leak because the binary doesn’t have the PIE protection enabled!)