Well this simple task of reproducing a Metasploit exploit is turning out to be a HUGE learning experience.
To quickly recap. We want to brute force an Apache Tomcat 5.5 servers login. Then use those credentials to upload a malicious payload to Tomcat which will then be executed to give us a shell into the system.
I don’t know why I thought this would be simple because it’s certainly not the easiest thing ever. That said, I am making some good progress. This was going to be a two parter but it looks like it will be a three parter. As you may remember from my last post we have credentials. Now we need a way to upload a payload. So this tool that I built tonight does just that.
Before we can upload, we need to see what is actually being sent in the request. To do this, I logged into the Tomcat management console, opened up burp and took a look at what got sent over the wire and where when I uploaded a file.
There’s a lot going on in this photo but here is the gist of it. The row that I have selected is the request that was made when I clicked deploy. The information at the bottom is the actual raw contents of that request. The important things to look at here are the headers. Immediately a few stood out to me.
‘Authorization: Basic dG9tY2F0OnRvbWNhdA==’
‘Content-Type: multipart/form-data: boudary=….’
In the end, this was 99% of what I needed to make this successful. Let’s start with the easy one. The post path is what gets tacked onto our base URL and port. When crafted it will look something like http://192.168.1.65:8180/manager/html/upload. No problems here.
Next we need to look at Authorization. This one’s a little trickier but still pretty easy. The double equal sign is a dead give away that this is a base64 encoding.
A quick online decoder confirms this
As you can see, when decoded we get tomcat:tomcat which is username:password. This is going to come in useful later.
Finally, the biggest pain in the ass ever. The Content-Type of multipart/form-data and its boundary. When I first started trying to make this work I crafted everything by hand. I put the file in the post data payload and sent it off. This failed horribly.
Uploading to the server turned out to be a little more tricky than I expected. Since I am crafting the request in python it needs to be precisely what the server is expecting. Otherwise you get erroneous errors like “Upload Failed – No File” or “Authorization Required”. As fun as these were to mess with, I found it frustrating after about 2 hours of the same error outputs.
So then I started looking at what multipart/form-data actually was and how to craft it in python. Surprisingly the python documentation online is pretty bad ass. I wish MSDN was as clean and easy to read.
I will also say using WireShark to inspect my calls and being able to line them up to burp made this SUPER easy (once I thought to do it) Had I done this from the start I probably would have cut my dev time down to 10% as long as it took me. Hey, that’s the learning process though.
Another thing that hung me up for a REALLY long time is the file name. Notice in the WireShark image below it says name=”file”; this is incorrect and is what held me up the longest. I didn’t catch that it was doing that. The correct value should be ‘deployWar’. You will see how it should be crafted in the next section.
Putting it all together
So let’s put all our info into a request and send it. First we will encode the username and password
Next we grab our file
Then we can build our request, set the headers and send it off.
Finally we just check our response for some keywords to see if we got a valid response or not
Execute the payload and we get profit!!
One final touch I added was including a path that the user can click to activate the payload. (or so we hope) At this point it’s untested with a real payload so that is what’s going to be in the next post.
Okay, that was super educational. I learned a ton there. I am getting better at this python thing and I am excited to try and craft a payload tomorrow. If I get that to work then we will put it all together into one big application and see if it works!