It's time to harden and patch

Natalka Roshak's picture

There have been two high-profile Oracle security flaws in the last few months. The first, which everyone reading this article has probably heard of, is the Voyager worm. The second, which is slightly less well-known, is a very severe security hole that lets anyone with a valid logon to an Oracle database -- including an unprivileged account with nothing but CONNECT privs -- execute arbitrary code as SYS. In this article, I'll look at the two security flaws and outline the steps you need to take to protect your databases from them.

The Voyager "Worm"

Oracle has twice emailed its customers about the Voyager worm. Well, "worm" is actually a bit of a misnomer. A worm spreads itself from machine to machine, like the similarly-named Voyager Alpha Force worm that spread through Microsoft SQL Server installations in 2001. In contrast, the published Oracle exploits called the Voyager Worm don't actually have any code to spread from machine to machine. It's being called a worm because the anonymous coder who posted the original exploit added the off-hand comment, "Voyager Beta worm - not complete - maybe someone else has time to look at it".

What it is

The original Voyager "worm" was posted anonymously to the Full-Disclosure mailing list on October 31st, 2005, under the subject "Trick or treat Larry". The worm code is simply an anonymous PL/SQL block. It searches through your subnet for Oracle listeners listening on port 1521, and if it finds one, retrieves the SID it's listening for. It then tries to create private database links to these databases using default passwords, and if successful, creates an empty table called 'X'. The second version of Voyager moves a little closer to being able to spread from machine to machine, but isn't there yet.

How it works

The interesting thing about Voyager is that it doesn't need to exploit any Oracle bugs, buffer overruns, or other security holes. Instead, it operates on DBA laziness. It simply takes advantage of Oracle's default settings to guess its way into your databases.

By default, the Listener operates on port 1521, and OS authentication is enabled, which lets Voyager make a STATUS request to get SID information. Voyager gets its list of IPs and talks to the listener using the utl_inaddr and utl_tcp packages, which are granted to PUBLIC by default. Once it gets the list of SIDs, it uses the CREATE DATABASE LINK privilege, which is granted by default to the CONNECT role until version 10g. And to authenticate on the remote instances, it tries a handful of default usernames and passwords such as DBSNMP/DBSNMP.

As I said, the original version of Voyager doesn't include any code to spread itself. As it stands, it has to be executed by an authenticated user on your database. However, it's easy to see how it could be made into a worm. Instead of creating a table over the dblink it creates, it could push itself down the database link and run on the remote server.

The second version of Voyager, published anonymously on 31 December on Full-Disclosure, comes a little closer to that nefarious goal. It still does not include code to spread, but it's clearly taken steps in that direction. It does several things in addition to running the code in the first version.

Unlike the first version of Voyager, the second version takes advantage of a known vulnerability in the DRILOAD package to attempt to grant DBA rights to PUBLIC. Whether or not the former succeeds, the code then creates an AFTER LOGON trigger that, about 1 time out of every 100 it is executed, Googles for its own code, extracts it from the Google response and executes it. ( is taking this very seriously, and has blocked access to the search string that Voyager issues.)

Next, Voyager tries to mail your user and password hashes to , using Oracle's own SMTP server, and to oracle@[random-ip-in-your-subnet] using the random IP as a SMTP server.

Finally, the new Voyager code takes further advantage of unsecured listeners, by changing the listener's logfile to the local glogin.sql. Failed listener commands are logged to the listener logfile, so the worm sends a SQL string, "alter user mdsys identified by mdsys." This is an invalid command, so is logged to glogin.sql. The next time a DBA logs in from that machine, the password of MDSYS will be reset to default -- increasing the chances that the worm will be able to create a successful database link.

How to protect your databases

The original version of Voyager could affect even the most punctiliously patched Oracle installation, because it exploits badly set-up installations. Most of the new version's payload also doesn't depend on Oracle vulnerabilities. The Voyager worm really highlights the need to harden our databases -- even our test and development databases.

The first, most obvious point is to NEVER leave default accounts open, unlocked, and with default passwords. The 10g installer locks and expires most default accounts; but earlier versions, and databases that were manually created, can still have a long list of default accounts, with default passwords, unlocked and unexpired. You're at risk from more than just Voyager if you've still got DBSNMP/DBSNMP or SCOTT/TIGER running on any of your instances. Many DBAs don't bother locking and expiring default accounts on test systems; however, the payload in the second version of Voyager, which uses access to one database in your system to change the password for MDSYS on any other databases you log into, shows that this is a dangerous practice.

Oracle provides a utility to check for some default accounts and passwords; if you have support, search for Patch 4926128 on Metalink. The "utility" is basically just a SQL script. If you don't have support, there is a password checking utility available for free on You should check all your accounts for accounts whose password matches their username. You should also download Oracle's security checklist it contains a list of all the default accounts and their default passwords. Lock and expire all of these accounts except for the ones you actually need to log in as, such as SYS and SYSTEM. And change the passwords for the accounts you don't lock and expire.

You should follow the rest of the recommendations in Oracle's security checklist. Here are the specific areas that you need to harden to protect yourself from Voyager:

  • Change default passwords, and lock and expire default accounts, for all your databases, not just your production systems.
  • Do not put your listener on port 1521.
  • Password protect your listener. Disable local authentication for the listener by setting LOCAL_OS_AUTHENTICATION_ = OFF in the listener.ora, and restarting the listener.
  • Revoke PUBLIC privileges to the UTL_TCP, UTL_SMTP, and UTL_INADDR packages.
  • Revoke CREATE DATABASE LINK from the CONNECT role, and grant it only to users who need to link to remote databases


Curiously, Oracle has twice emailed all its customers about the Voyager worm, but has been more low-key about a much greater security risk: the DB18 security hole. This vulnerability lets anyone with a valid database login execute arbitrary commands as SYS on that database. And it's incredibly simple to use.

January's Critical Patch Update (CPU) risk matrix for the RDBMS contains a very unusual entry. Scroll down to "DB18" and you'll see that this vulnerability is rated as "easy" and "wide" in every category. It affects every supported Oracle release. And all that's required is a database login -- no special privileges required.

What it does

DB18 lets anyone with a login execute arbitrary commands as SYS.

How it works

Imperva, the security firm that discovered this hole in October 2005, explains the vulnerability on their website. The vulnerability is in how Oracle's TNS protocol handles authentication. Imperva discovered that when you carry out standard authentication, your client makes two separate requests and gets two separate server responses. The first request just contains the username. The second request contains the username-password pair, and also a list of other key-value pairs that hold various client attributes.

The vulnerability is in the second request. One of the key-value pairs is for a key named AUTH_ALTER_SESSION. Imperva says that the intended purpose of this key is to set up NLS-type session attributes such as NLS_DATE_FORMAT, etc. by passing an ALTER SESSION SET... statement as the value for this key. However, Imperva discovered that any SQL statement passed as the value to AUTH_ALTER_SESSION gets executed... and it gets executed as SYS.

Thus, any user with no more than CONNECT privileges can execute arbitrary statements as SYS. For example, any user could create a new account and grant DBA privileges to that account. (If the user tries to grant DBA privileges to their current account, the session hangs.)

How to protect your databases

The only way to protect against this vulnerability is to apply Oracle's January CPU. And it's essential that you apply it as soon as possible. To quote, "Exploits for this vulnerability are already available!!!"

As always, the best practice is to apply the CPU to a test instance, test your production applications, then apply the CPU to your production instances.

The problem with CPUs

Imperva also points out that this issue highlights a meta-vulnerability -- a flaw in Oracle's way of dealing with security holes. Imperva says they notified Oracle of this vulnerability in October 2005, but that Oracle decided not to release a patch until their January CPU. Oracle only releases CPUs quarterly. Of course, this may not be dawdling on Oracle's part; it may simply have taken Oracle this long to patch the vulnerabilitty. Oracle is notorious in the security community for taking a long time to issue patches; some lower-priority vulnerabilities have taken upwards of two years to get patched.

PCs with unpatched vulnerabilities are protected by anti-virus software, which aims to detect viruses that exploit unpatched vulnerabilities. By volume, most unpatched vulnerabilities are due to user laziness, but there are always a significant number of known vulnerabilities the software vendor hasn't yet been able to patch. Imperva, unsurprisingly, calls for solutions like the one Imperva itself manufactures, a 'database security gateway,' essentially a packet-inspecting firewall, which scans all incoming traffic for virus signatures. However, such products can only scan for published vulnerabilities; the majority of Oracle vulnerabilities aren't published by their discoverers until they've been patched, at which point you might as well apply the patch. Imperva scans for any unpublished vulnerabilities that it discovers, but any one firm is unlikely to discover all the open vulnerabilities at any given time.


Historically, Oracle databases were likely to be located deep in the organization, and there were relatively few exploits out there. Those days are gone. Many DBAs are still complacent about patching -- for instance, only patching production instances, or not patching at all. And I've read one estimate that 60% of Oracle customers have at least one database running that still has unlocked, unexpired default accounts with default passwords.

These two high-profile vulnerabilities are a wake-up call to all of us. The Voyager "worm" reminds us to harden all our databases, even test and development databases. And the DB18 vulnerability is a reality check for those who still think that applying Oracle's CPUs is not important, or can be delayed. Similarly, Voyager shows that patching alone is not enough; and DB18 shows that even hardened databases need to be patched.

About the author

Natalka Roshak is a senior Oracle and Sybase database administrator, analyst, and architect. She is based in Kingston, Ontario. More of her scripts and tips can be found in her online DBA toolkit at


Thanks for this wakeup! I'll start checking today.

Of the last 5 CPU's I have had to deal with for Oracle Application Server, 2 had bugs - not a good percentage. The CPU bug for Windows for 2nd or 3rd quarter last year caused Oracle to withdraw the CPU (Windows only - maybe just midtier?) for about a month until they fixed it. For the other one, I had to open a TAR, and we figured out that one dll had to be reverted to the one it was replacing - no idea what security impact that had since Oracle "protects" us by not divulging details at that level.

So, I have had to take the stance of letting others find the bugs for a few weeks at least before I jump on a fresh CPU, and then I apply it to a plain test system (thank VMware for making it easy to start with a fresh image each time for Intel based OS's ;-), and hope I can spot anything that looks suspect before applying it to customer systems.