Showing posts with label CVE. Show all posts
Showing posts with label CVE. Show all posts

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!

Thursday, October 18, 2012

My First Experiences Bug Hunting, Part 2

So in Part 1 I disclosed the specifics of CVE-2012-3819, and I ended with the concept of loading a debugger (OllyDbg in this case) in order to analyze the program while it crashes from the stack overflow exception. During this process it is easy to note that no control of the EIP register is obtained - and thus the bug is relegated to a generic DoS type bug.


As you can see the registers remain largely intact. EAX is a pointer on the stack (which is very low at the point of crashing, due to the stack consumption). So it is shown that the impact of this bug is likely very small. But since we have the debugger open anyway, we go ahead and do a search for strings. This is so we can see what else might be of interest just while we're in town.

To do this we first want to be analyzing the actual executable, in this case: "Campaign11.exe" which is the primary executable for Campaign Enterprise 11, my installation is a previous version (11.0.538). This software, of which I found another five vulnerabilities within, is used to send e-mails to large lists of individuals. It is an excellent marketing tool. Including the recent fixes for these bugs (version 11.0.551), I believe it will be that much better now. We click View in the menu and select "Executable Modules" which loads a list of the images presently mapped to memory. We then double click the entry which lists Campaign11.exe and this loads that module into the CPU window.

Right clicking in the instruction pane of the CPU window we choose "Search for -> All referenced text strings." This loads a list of things that look like strings in the Campaign11.exe application. This will provide us a great deal of insight into the inner-workings of the application. First I note at the top of this list are several tell-tale signs that it was programmed in Visual Basic. Including typical VB style nomenclature for control names, etc.

Knowing one of the key failures in many web based applications is SQL Injection (SQLi) I begin looking for SQL strings of interest. I right click in the list of strings and select "Search for text," running this command I seek out instances of "select * from" which is ubiquitous. I repeat this search, seeking things that look interesting. I find several entries that could be fun:
004C6143   PUSH Campaign.00426428                    UNICODE "select * from tblUsers where "UID"=" 
004C624D   PUSH Campaign.004264AC                    UNICODE "select * from tblUsers where UID="
There are many of these, but they all seem invaluable - they appear to be the first start of a string concatenation which may lead to SQL injection - and this is the sort of code you would associate with the login screen. I find all instances of "select * from tblUsers" and set break points on each. I use Ctrl+L to go to the next, then use F2 to speed the process of "red-pointing."

Then I try to login (plus a little SQL Injection since I'm expecting the possibility) to see if I won anything....


Damn. I see my SQLi is thwarted likely by a call to replace("'", "''"). Scrolling up some you can see this call does in fact happen. I see down in the current operands area that the string we're specifically dealing with is  "select * from tblUsers where username=". So back in the strings window I limit my breakpoints down to just the ones that have an instance of the string we landed on first. There are only two, and I notice something interesting nearby the second instance. A string "User-Edit.asp" - I try to load this URL "http://localhost:82/User-Edit.asp"

Bingo! I see a screen with *USERNAMEINPUT* as the username - I presume this is some sort of place holder. I combine this with the test for UID in the strings above and take a stab in the dark - I use UID as a Query String parameter and set it to 1. "http://localhost/User-Edit.asp?UID=1"

No dice, but I did land on a break point which may show me what's happening a bit. I step forward a little bit and wait for a string to appear in the top right pane of the CPU window - eventually it does, right around: 
005FD39A   . 8B85 60FFFFFF  MOV EAX,DWORD PTR SS:[EBP-A0]
The string is in EDX, and I see it's carrying my "UID=1". I wonder... what about SQLi here? I try it. "http://localhost:82/User-Edit.asp?UID=1%20OR%201=1"

I see my SQLi seems to be unhindered, so I let the program run through (F9).



I'm greeted with the user-edit page - and I have the admin user (the only user in my case). Reviewing the source of the page, I see it populates the username as well as the password boxes. In my example it appears random - but that's just the password I punched in. Its  in plaintext!

I go ahead and enumerate all of the available .asp pages and continue similar testing on these. Then I contact the vendor as well as cve-assign@mitre.com and these are what was assigned:
CVE-2012-3820: Multiple SQL Injection: activate.asp – SerialNumber field, User-Edit.asp – UID field 
CVE-2012-3821: Unauthorized access to the activate.asp page, allows modification of stored database field SerialNumber without authentication or authorization.
CVE-2012-3822: Unauthorized access to the User-Edit.asp page, allows attacker to enumerate users and their credentials by supplying their UID in the querystring. 
CVE-2012-3823: The product has stores passwords in clear text and these may be retrieved  using the User-Edit.asp page. 
CVE-2012-3824: Multiple pages accessible without authentication or authorization which may lead to the unintended disclosure of information or functionality but was not assessed. Register.asp, Group-Edit.asp, Subscriber-Edit.asp, SMTP-Edit.asp, Email-Edit.asp, Admin-GlobalConfig.asp, Admin-Users.asp, Campaign-Datasource.asp 
And that sums up my first experiences bug hunting.

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

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!