XERXES II – The write up
Now as with every VM once mounted and running we run a arp-scan or whatever to locate the box and once its found we perform a portscan on it resulting in some interesting services, ssh(22),lighttpd(80),unknown(4444),tornado(8888) For those who scan the machine the first time(within 2 minutes after its booted) the tornado service at port 8888 wont show this a little troll added by Bas.
The first thing which got my interest was the unknown service at port 4444 so I connected to it with netcat and was presented with a huge blob of base64 encoded data. I decoded the data and found myself a MPEG file according FILE
I opened the file in a player to see if there were any hints in it, I also hexdumped the file see if the was some obvious stuff in the file but it all seemed useless. The next thing I checked was the default webserver at port 80, this only contained a static page with a logo and wasn’t much useful either so the last thing left was the Tornado server at port 8888.
Once I accessed the Tornado server I ran into the IPython Notebook application, At first I had never heard of it but when I Googled for it I got all warm and fuzzy since it allows you to run system commands. I created a command to set up ssh access and executed it.
Looks good now let’s try to get some shell..
Lovely! Time to explore the box a little bit. I noticed a bf.c file in the home folder and some interesting bash history.
It seems a file called ‘bf’ is executed from the ‘/opt/’ folder and it’s argument appears to be a piece of Brainfuck code. When I checked the ‘/opt/’ folder to see if the binary still existed I also noticed an interesting ‘backup’ folder with an encrypted tar file in it belonging to the ‘korenchkin’ user which at that moment didn’t make much sense to me.
When analyzing the source code(bf.c) we can see it’s a normal implementation of Brainfuck with an extra instruction ‘#’ which sends our current buffer into a ‘printf’ without a format pattern which results into a formatstring vulnerability!
76 case '#': 77 // new feature 78 printf(buf); 79 break;
Now the system seemed to have the most common protections like ASLR and NX enabled.
And also the Binary seemed to be compiled to use non executable memory when being checked with PEDA
So in order to exploit this I needed to find a way to bypass the ASLR. A good way to do this is by leaking some binary or library address, Now a formatstring vulnerability allows us in certain cases to dump stack memory which often contain such addresses. The first thing I had to do was trying to locate my input on the stack like we do with every formatstring attacks. I wrote a little for loop and executed it.
Added some line numbers to it with VIM
My input seemed to be on index 16 and when looking at index 1 and 9 they looked like something which could be a library addresses so I decided to have closer look on the stack using GDB with a breakpoint set on ‘printf’ and some simple Brainfuck code to handle. Once the breakpoint was reached I looked up the current stack
I could see an address which looked allot like I seen before ‘xxxxxFF4’ aka index 9 and when I checked the current process mappings in GDB I could see the address belonged to ‘libc’ it’s range
In order to get the raw offset of the leaked address I subtract the current libc baseaddress so
0xb7707ff4 – 0xb75a8000 = 15FFF4
So I could calculate the Baseaddress by simply doing
leakedaddress – 0x15FFF4 = Baseaddress
When looking up the offset 0x15FFF4 with objdump and IDA I noticed it was the ‘.got.plt’ offset
delacroix@xerxes2:~$ objdump -h /lib/i386-linux-gnu/i686/cmov/libc.so.6 | grep 0015fff4 29 .got.plt 0000002c 0015fff4 0015fff4 0015eff4 2**2
A few test runs checking that index 9 showed that the leaked libc address was always there just its base kept changing as expected due the ASLR
So the general idea of the exploit is to provide the binary some Brainfuck code which does the following
1. read a format string pattern into the buffer and send it to the printf to leak the libc address at index 9. 2. move the buffer pointer back to its begin. 3. read a format string pattern into the buffer and send it to the printf to overwrite the binary's printf GOT with libc's system address. 4. move the buffer pointer back to its begin. 5. Finally read the command into the buffer and send it to the printf which now points to system, resulting into a system(command).
An example of such code could be..
h4x@kali:~/xerxes2$ python -c “print ‘%9\$x\n<–>\n/bin/sh\n'” | ./bf “,>,>,>,>,>#<<<<<,>,>,>,>,>#<<<<<,>,>,>,>,>,>,>,>,>#”
I wrote the exploit in python and used pexpect to interact with the binary which gave me some pain but let’s not get into that!
You can find the exploit source code at http://pastebin.com/gGWMy9gT
Boom! we have a shell owned by ‘polito’! I executed the shell and applied the same ‘authorized_keys’ to the user as I did before so I had another proper ssh shell
What’s next Bas?!
The pdf tells me silly Bas left me an encrypted dump file.. And when it comes to the password needed to decrypt it he tells me that I’m pretty much on my own. I checked the QR code again(those who did xerxes 1 know…) I decided to check a hexdump of the pdf to see if the password maybe was stored in it hoping it was clearly visible.
I didn’t see anything password like, but the first 512 bytes of the file directly got my attention.. I could see that it contained some ‘Warning’ string and beneath it something which at first looked like some scrambled text. I checked if it maybe was ROT13 but didn’t seem to be the case. When I checked the pdf with FILE I got more confused, since it told me the pdf was a x86 bootsector. So after reading a bit up again on bootsectors I decided to dump the mbr.
After trowing the mbr into IDA and dressing its assembly a bit up I could see some interesting code appear..
The code looks rather simpel, if we follow the jumps we can see it pushes a bunch of values onto the stack and jumps into a loop where it pops 2 values from the stack(for each loop) and prints them on the screen until the ‘5A4Dh’ marker is reached. I simply copied all the pushes from ‘seg000:00EA’ till ‘seg000:0117’ and stripped all the addresses, pushes with a simple macro
seg000:00EA push 0A0Ah seg000:00ED push 6C4Eh seg000:00F0 push 5761h seg000:00F3 push 7546h seg000:00F6 push 6D61h seg000:00F9 push 200Ah seg000:00FC push 203Ah seg000:00FF push 7369h seg000:0102 push 2064h seg000:0105 push 726Fh seg000:0108 push 7773h seg000:010B push 7361h seg000:010E push 7020h seg000:0111 push 6568h seg000:0114 push 540Ah
after stripping the stuff I concatenated the data back into a hex string and decoded it with python and printed it in reversed order..
Yeah I have a password! I tested the password on the dump.gpg and it seemed to be the correct one. I quickly looked up the file which seemed to look like a memorydump, I ran some strings on it but it gave me to much rubbish then I suddenly remembered the backup tar seen earlier and took a wild shot grepping for it in the memorydump.
Yeah baby! thats looks interesting! seems the dump contains the commandline used to encrypt the backup file and also contains the password. I copied the file to my ‘tmp’ folder and decrypted it.
Nice! we have the .ssh folder of the ‘korenchkin’ user so I could ssh into the user using the identity file
So what’s the last part? well root the damn box! I quickly looked in the home folder but couldn’t see anything interesting so I checked the user his sudo privileges
It seemed like the user was able to install kernel modules, now this is nice since they run with root privileges so I decided to write a simple kernel module which just copys a root shell into the ‘tmp’ folder.
I used the following code and Makefile..
Then I compiled the module and installed it…
And dropped into the root shell!
Another super cool boot2root vm from Bas finished! I enjoyed this one like I did with XERXES1, Once again it was a nice blend of binary exploiting and crypto.
Also I wanna say thanks to recrudesce and superkojiman for helping test stuff during the development of the bf exploit.