sally sells seashells by the seashore sally sells seashells by the seashore sally sells seashells by the seashore sally sells seashells by the seashore sally sells seashells by the seashore sally sells seashells by the seashore sally sells seashells by the seashore sally sells seashells by the seashore
nc tjc.tf 31365
Solution
As the name of the challenge suggest and checksec suggest, its going to be a shellcode injection type of attack. However there's a bit of a twist
Clearly there's some overflow while buffer only hold 256 bytes, the fgets() takes the twice of it. We can calculate the offset to overwrite the RIP by adding the stack buffer with 8 bytes of RBP which equals to 264. But how do we where and how do we redirect the return to our shellcode?
Notice before it asks us for input, it prints out the address of buffer, which enables us to overwrite the RIP to that buffer where our shellcode resides. Debugging with gdb will proves this as shown below
One complication is that our assembly opcodes is prohibited to contain other than of\x0f and\x05 which corresponds to syscall. Where in this case is needed in order to spawn shell. Initially I tried different assembly opcodes that exist in shell storm that doesn't contains said prohibition. But soon I realised that the check only applies to the first 510 of our input, since the prohibited opcodes are located at the last 2 byte of our shellcode, we can fill the buffer with just enough so that the last two byte are at the 511th and 512th byte of our buffer respectively.
I initially calculated the amount of padding required to do this by ( - - ) to perfectly allocate the prohibited bytes at the last two bytes so it will go unchecked. However it doesn't seem to work, after some tweaking It works by providing 500 instead of 512 as our maximum input. I don't quite understand why, does anyone know why?
To build our payload firstly we need to overwrite the RIP with the address of buffer + 0x110 (or 272 (264 offset + 8 RIP) in decimal). This is because if we jump straight to Initial address of buffer, there will be the address of our desire between the asm('nop') and our shellcode which is not a valid instruction so we have to skip over that. Here's a diagram I create to better visualise