OK previously I have shown you a few ways you can exploit LFI vulnerabilities. We covered how to gain shell access through
/proc/self/environ, how to read source through
php://filters , and also how to gain command execution through
log poisoning technique. Now today I am going to show you one last method which is much less known about and even less documented. I am going to show you how we can exploit LFI vulnerabilities by abusing the
php://input filter this time. The
php://input filter is designed to handle the data from POST request as its argument. If you follow the link above you will find it described as: (php://input) “
is a read-only stream that allows you to read raw data from the request body. In the case of POST requests, it is preferable to use php://input instead of $HTTP_RAW_POST_DATA as it does not depend on special php.ini directives”. We will abuse this feature to execute PHP code thanks to the include() vulnerability we are exploiting (in similar fashion to how the /proc/self/environ method works). I have seen this method included in a few tools and I will admit I had to tear FIMAP apart to truly figure out how it was getting this technique to actually work which is why I want to share this with everyone, as I assume I am not the only one who is unaware of this technique and how it can be implemented to successfully turn Local File Inclusion (LFI) into Remote Code Execution (RCE), most notable but certainly not limited to - Windows targets.
I will show you how it works using Burp Suite so you can more clearly see how the requests are formed and code injected manually, here goes…
Pre-requisites:
· LFI Vulnerability
· Burp Suite, cURL, Tamper Data, Live HTTP Headers, or some other means to easily make POST requests and control the data sent with it – I will be using Burp Suite for this write up and curl in the bonus video. If you need help in coming up to speed with Burp Suite you might want to check out some of my other tutorials I have done:
· Updated HR’s Burp Pack Download, available here: http://www.megaupload.com/?d=LP7Z7E2K
· A Brain J
OK, so today I will be using this method against a Windows target to show you that LFI vulnerabilities can be abused on Windows just as badly as they can on a *nix machine – just because we can’t find /etc/passwd doesn’t mean we can get things going, watch and learn my friends. I will assume after all my previous LFI coverage that you can spot a potential LFI now and know what to look for. We will start from the initial find and work our way to command execution:
OK our initial request for /etc/passwd fails but gives us a few clues that we are up against a Windows machine. This means that /proc/self/environ method is out. You can use “C:\boot.ini” or “C:\WINDOWS\win.ini” as the Windows universal equivalent to /etc/passwd for a simple LFI base file check:
We can then try to find juicy Windows files using my new LFI-WinblowsFileCheck.txt file I added to my Burp Suite download pack (link available at the top and bottom of this tutorial). My new list is especially helpful when the target is also known to be running under XAMPP setup as I personally set things up locally and tested things until I had every possible file I could think of to potentially gain juicy info from.
In this scenario I was able to find several juicy files which held helpful information, but alas I was not able to successfully gain access to any of the log files. The apache log files caused errors to be thrown which made them unusable and the FTP & Mail log files appear to be on another drive which I can’t successfully access through the LFI. I can use php://filters method to read source code but alas I can only find a few PHP pages even on the site and can’t seem to locate any low hanging fruits by guessing for configuration files L.
Do we give up and move to the next site? Hell no! We never give up and we leave no stone unturned! As we can use php://filters to read source code we will now try one last trick and see if we can abuse another filter which I have yet to introduce you to and that is the php://input filter. This filter is designed to handle data sent via POST request and when we abuse it with our include() vulnerability we can exploit the conditions to turn our LFI into full RCE or Remote Code Execution! In order to get things working we flip our request from a GET request to a POST request. We then replace our file names we have been requesting with php://input and then we place our code below the other header info so it is the data being read by php://input.
Mini-TuT: 101 on GET vs. POST request because you need to understand how to flip the request properly or it wont work correctly, so here is the minimum you need to understand and get started:
HTTP is a request-response protocol, with many built in methods which allow it make all types of requests. The two most common of those methods are GET and POST requests and is all I will focus on for now...
A GET request fetches data from the web server. Here's an example request:
GET /index.html?username=joesomebody&passwd=supersecret HTTP/1.1
Host: www.samplesite.com
User-Agent: Mozilla/4.0
You don’t need to include anything else as everything for the GET request is in the URL itself and header details. This is where the variance becomes notable as POST requests do send additional data to the web server. Here is an example of a POST request:
POST /login.php HTTP/1.1
Host: www. samplesite.com
User-Agent: Mozilla/4.0
Content-Length: 39
Content-Type: application/x-www-form-urlencoded
username=joesomebody&passwd=supersecret
You can clearly see a difference in the structure of the request. We place a POST instead of a GET obviously with the URL pointing to the page we want to send our data to. We then have our Host header to identify the target site so that when paired with the URL page we get a working link. The User-Agent field is fairly self-explanatory, although it is worth mentioning you can spoof this or even use to inject code in some cases (see some of my other LFI tutorials for examples). We then define the Content-Length which is a count of the characters used in our data stream. The default Content-Type should be set to application/x-www-form-urlencoded followed by a blank line and then you can insert your data to send. POST requests typically alter the web server in some way whereas GET requests do not.
Back to the main TuT…
As in many of my other tutorials I like to start small and then work our way up to full shell access so we begin by just checking to see if we can we use injected code to echo some text to the page (Hood3dRob1n in this case), your request should look similar to this:
NOTE: we use the PHP chr() function to send ascii characters one at a time for the echo command
OK, we can clearly see our text being displayed meaning our echo command was successfully injected. Again this is done because php://input takes the data as an argument and since we are inside of the include() vulnerability it causes the code to become executable. We can now modify our code to inject whatever code you like, just remember in this case it is a Windows environment so commands need to be adjusted accordingly. We can quickly check our user status by issuing a quick “whoami” request, like so:
As you can see we are running in this case as the NT AUTHORITY/SYSTEM user, which is the Windows equivalent of root user. Now we can issue a systeminfo command to see what we have gotten into:
And then follow up with DIR commands and take a look around…
Now since it is a Windows machine we may or may not be able to use WGET or CURL to get a shell on the target site. If you can’t do this then we will try to use our RCE ability to add a user and then use RDP to simply login and do our thing. In this scenario I can’t load a shell so we will do it the long way. We first check to see who is in the administrator group already with a quick windows command:
OK, so now we need to get our name on the list. We use some more Windows command line kung-fu and add a user to the machine, like so:
Now we check the cool guy list once more to confirm we are now on the list:
w00t – we made to the cool guy group! Ok we are almost done…now that we have admin level user created we will grant them access to the Remote Desktop Users group so we can use RDP to get full GUI access to the site. In order to do this we again alter our commands slighty and add our new user to the group like so:
Now that we have added a user we need to add them to the administrator group so we can get on the cool guy list, we do this by adjusting our command slightly as so:
OK, now we need to open up a command prompt or terminal on our local machine and issue a quick PING request to the target site so we can confirm the IP address to which we will RDP into, should appear something similar to the following (point is to get the sites IP):
Once we have the IP address for our Windows target we can simply open up our RDP connection manager and connect using our new account credentials we made in the steps outlined above:
At this point you have pretty much got full control thanks to wonderful old Windows. If things fail due to RDP Service not being enabled you can try to inject this command and to enable it:
And if you’re too impatient you can simply restart the machine yourself all though this may cause a few red flags to go off and may also possible lead to data loss on the remote target so use with some caution…
You can use your RDP GUI access to do what you want now or you can do it all from the LFI command execution one by one, whatever floats your boat. This sums up my coverage of the LFI php://input filter technique and how it can be used to exploit Windows systems (It can also be used against *nix but I mainly engage this technique against Windows targets). I hope you have enjoyed this tutorial and as always and until next time – Enjoy!
BONUS VIDEO:
...I should have up in next 24hrs...
Updated HR’s Burp Pack Download, available here: http://www.megaupload.com/?d=LP7Z7E2K