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:\sulleyYou 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 888Now 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://hinow 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:888What 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.
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