This time there's no binary or libc.so provided, only an image looks like this:
So apparently the program has two vulnerabilities: stack overflow & format string. Since we can't actually exploit the stack overflow vulnerability (the program likely won't return because of the infinite loop), we'll have to focus on the format string vulnerability and exploit the service without having the binary file.
So how are we gonna do this? Fortunately, pwntools is here to rescue! By using the amazing DynELF module, we're able to resolve & leak some address without the need for binary!
First we'll need a leak function to let pwntools able to leak data at an arbitrary address. Here we exploit the format string vulnerability to leak an arbitrary address:
Then we need a pointer into the binary. I got the pointer by entering %30$p, which returned 0x40060d. Now we can use the DynELF module to help us resolve some function addresses.
First we'll need to resolve the address of printf and system:
It took a while because of sleep(1), and pwntools will need a lot of addresses to resolve those functions.
OK so now we know the offset between printf and system. Next time we'll just have to leak email@example.com, calculate system's address and use it to overwrite printf's GOT entry, finally we'll be able to hijack printf's GOT and call system("sh") by entering "sh".
But first we'll have to know the address of firstname.lastname@example.org. Luckily, not only can DynELF resolve function addresses, it can also resolve some useful addresses such as the pointer to the .dynamic section:
Once we got the .dynamic section's address, we can use it to locate the .got.plt area:
Now we can find where email@example.com is, by leaking all the GOT entry and compare the low 12 bits of the function address (see if it ends with 550):