So first of all, we have to ssh a web page, here is what we got:
beginning screen (from https://f00l.de/blog/) |
So, let's start!
file command gives us "setuid setgid ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x5446b9058fdd04404a8b84827d5873028204ee90, not stripped"
Ok fine, so a 64bit executable, setuid (as we already know), not stripped lucky us!
run the program, nothing happen, exit 0.
Run the program with an argument display the following string:
Mmm.. me lika string! let's open it with IDA and look for the string!
A quick look on the binary let us find the function in charge of displaying our string:
Function display the string "Zombie detected" |
Ok, as presumed, if this function is called it will display the string and then exit.
Looking a bit more in the binary we find where this function is called and what the binary is doing:
Series of actions for the main |
Then it writes on this page all strings we give as input as a double-word converted with strtoul function, appending 0xc3 as 4th byte and then call it! After calling all our "inputs", if no signal were received in the mean time it pops up a shell.
We begin to have an idea about what we have to do, we basically have to inject a shellcode so that the program will acquire the privileges of safehouse (without going in segfault), then the program itself is going to pop up a shell for us! the only limitation is given by that 0xC3 injection as the fourth byte on every double word, we need a clever way to write our shell code.
We know that setuid is a a system call, therefore we can call it by mean of a int 0x80h instruction.
Looking here we have a nice table of all system call, with relative parameters.
Gotcha! an int 0x80h with a 0x17 in eax will call sys_setuid, what we need! uid_t should be in ebx register, and we know safehouse is uid=1006 (in hex 0x3ee).
Now we need to divide our input in several pieces, all of them smaller than 4 bytes:
mov bh, 0x3 -> b7 03 //highest part of 1006
mov bl, 0xee -> b3 ee //lowest part of 1006
int 0x80 -> 80 cd
Wow! we just need to split the setting of the bx register in two parts, and all our input is nicely divided in block 2 bytes-long!
Obviously we still need to fill up 1 byte without letting the process crash, what's better than a nice old 0x90!?
we just built 4 arguments then (remember LITTLE ENDIAN!):
'0x9017b0', '0x9003b7', '0x90eeb3', '0x9080cd'
Now it's just a matter of converting them to integer and we should be cool!
[9443248, 9438135, 9498291, 9470157]
Trying to call the program with these arguments give us
And a nice little shell for us!
that's it, I found this easy exploitation very didactic for building up a custom shellcode, a very nice piece of work!
There was also another version of this challenge a bit more complex, it will be for next time!
This is a link (from LeetMore writeup) for downloading the binary.
Enjoy!
No comments:
Post a Comment