Going from Jue010 to Better isn't a single giant leap; it is a series of small commits.
Don't try to fix everything at once. Commit to improving just one element of your Jue010 today. That is the compound interest of mastery.
Paradoxically, making Jue010 "better" usually involves removing things rather than adding them. jue010+better
If you are the user who typed "jue010+better" or you found it in a document, here is an informative action plan:
Since check_pass expects its argument in rdi, we can also ROP a gadget that loads the address of our forged password buffer into rdi before calling check_pass. The easiest way is to simply return directly to check_pass because the password buffer is already at a known offset from the current RSP after the overflow. When check_pass starts, it will read the password from rdi – which will contain the address we placed in the overflow. Going from Jue010 to Better isn't a single
The simplest approach is:
overflow -> [username(16)] [password(16) = correct secret] [canary] [saved RBP] [RIP = address_of_check_pass]
When main returns, the stack will be:
RIP = check_pass
RDI = ??? ← we need to set RDI = address_of_password_buffer
To set RDI we can use a ROP chain consisting of:
Because after the overflow the saved RBP is no longer meaningful, we can place the ROP chain in the overflow payload after the saved RIP. Don't try to fix everything at once
Send the payload and read the flag.