|
| |
In this article we will show some examples of what is possible with the combination of Java and Oracle or, if you prefer, how to attack the Oracle database with Java. You cannot protect yourself if you don't know the threat, and experience shows that there are very many intruders, and most of them are insiders.Oracle and Java: the good sideThe gist of the integration of Oracle with Java is that from inside the database (for example, from PL/SQL or SQLPlus) it is possible to call Java classes, which can carry out some useful action.To give only one example, suppose that you manage a database on a remote host H1, but you don't have any operating system account on that host, which is absolutely possible (we currently manage NT databases for an external company, but we don't have any NT account; Oracle username and password are stored in our Enterprise Manager console). Some day you get the warning that one of the tablespaces is running out of space and you know that you should add a database file or make one bigger. Question: how can you know that there is enough space on the disk on H1? One normally has to pick up the phone and ask one of the NT administratos. With Java it is simple to create a class that lists the devices and the free space on them; therefore, it is possible to call this class from Oracle and find out where the additional data file can be created. How do you define Java classes in the Oracle database?The topic has become very popular and the method is explained in several excellent articles; therefore we will simply outline the method and you can fill in the gaps.
Oracle and Java: the hacking startsTo understand the risks in the combination Oracle - Java, let's work with a simple Java class Df.java; here is its source code:
/*
* Df.java
*
* Created on August 20, 2003, 10:18 AM
* @author front row seat
*/
import java.io.*;
public class Df {
/** Creates a new instance of Df */
public Df() {
}
//===========================================================================
public static String uptime() {
String sLs = "";
String s = "";
try
{
sLs = "";
boolean found = false;
Process p = Runtime.getRuntime().exec("/usr/bin/uptime");
InputStream is = p.getInputStream();
DataInputStream dis = new DataInputStream(is);
do{
s = dis.readLine();
if(s != null) {
sLs = sLs + s + "\n";
}
}while (s!= null);
}
catch(IOException io) {
sLs = "There was an error";
}
return sLs;
}
//======================================================================================
}
This class contains a function uptime, which is static and public (Oracle requirements); this function executes the UNIX command uptime, which shows how long the system has been running for.The first step is loading the Java class into the Oracle database: loadjava -user sys/syspwd -oci8 -resolve Df.class As we already know, this Java function can be executed from Oracle, provided a wrapper is defined CREATE OR REPLACE FUNCTION uptime RETURN VARCHAR2 AS LANGUAGE JAVA NAME 'Df.uptime() return java.lang.String'; / Function created.SQL> select uptime from dual; UPTIME -------------------------------------------------------------------------------- 3:11pm up 4 day(s), 3:45, 6 users, load average: 3.22, 2.36, 2.04 Now in the Java source let's change the command /usr/bin/uptime with /usr/bin/hostname without changing anything else. Recompile the class: Reload the java class SQL> select uptime from dual; UPTIME -------------------------------------------------------- daddy1 Of course this time we see the hostname, and not the uptime. Oracle with Java: hacking seriouslyMost of you already understand how the story will end, but let's be explicit.oracle# touch /tmp/a.txt oracle# ls -l /tmp/a.txt -rw-r--r-- 1 oracle dba 0 Jan 14 15:42 /tmp/a.txt oracle# ls -l /tmp/a.txt /tmp/a.txt: No such file or directory Therefore the file has actually been deleted. This means that calling an Oracle PL/SQL function that execute some Java code, we can delete an operating system file. Actually, we can delete ANY operating system file belonging to the UNIX user oracle. Now the same exercise with one of the SYSTEM tablespace files ... (please don't, it will work) In the rest of the article the Java privileges in the database will be discussed, but we can already conclude that Java privileges are at least as potentially dangerous as the DBA ones, and often this is not understood. Who can use Java in the Oracle database?In the above example the account SYS was used; this time we will try to carry out the same actions with the account SCOTT and see how we can go on.localuser@:REP920 loadjava -user scott/tiger -oci8 -resolve Df.class localuser@:REP920 Loading the class is allowed.
SQL> connect scott/tiger
SQL> CREATE OR REPLACE FUNCTION uptime
2 return varchar2
3 as language java
4 NAME 'Df.uptime() return java.lang.String';
5 /
Function created.
SQL> select uptime from dual;
select uptime from dual
*
ERROR at line 1:
ORA-29532: Java call terminated by uncaught Java exception:
java.security.AccessControlException: the Permission (java.io.FilePermission
/usr/bin/uptime execute) has not been granted to SCOTT. The PL/SQL to grant
this is dbms_java.grant_permission( 'SCOTT', 'SYS:java.io.FilePermission',
'/usr/bin/uptime', 'execute' )
Let's grant the privilege to scottSQL> execute dbms_java.grant_permission
SQL> select uptime from dual;
select uptime from dual
*
ERROR at line 1:
ORA-29532: Java call terminated by uncaught Java exception:
java.security.AccessControlException: the Permission
(java.lang.RuntimePermission readFileDescriptor) has not been granted to SCOTT.
The PL/SQL to grant this is dbms_java.grant_permission( 'SCOTT',
'SYS:java.lang.RuntimePermission', 'readFileDescriptor', '' )
SQL> show user
USER is "SYSTEM"
SQL> execute dbms_java.grant_permission(
'SCOTT','SYS:java.lang.RuntimePermission', 'readFileDescriptor', '' );
SQL> connect scott/tiger
Connected.
SQL> select uptime from dual;
UPTIME
--------------------------------------------------------------------------------
9:40am up 87 day(s), 23:21, 2 users, load average: 1.10, 1.21, 1.26
SQL>
Let's now try tu execute a UNIX script using the Korn shell.
Process p = Runtime.getRuntime().exec("/bin/ksh /tmp/dummy"); After compiling and loading the class we'll try to execute the function uptime, that in fact will run the UNIX script /tmp/dummy SQL> connect scott/tiger Connected. SQL> select uptime from dual; select uptime from dual * ERROR at line 1: ORA-29532: Java call terminated by uncaught Java exception: java.security.AccessControlException: the Permission (java.io.FilePermission /tmp/dummy execute) has not been granted to SCOTT. The PL/SQL to grant this is dbms_java.grant_permission( 'SCOTT', 'SYS:java.io.FilePermission', '/tmp/dummy', 'execute' ) SQL> select uptime from dual; UPTIME ------------------------------------------------------------------------ There was an errorThe cause of the error is that the user SCOTT does not have the java permission on /bin/ksh SQL> connect / as sysdba SQL> execute dbms_java.grant_permission( 'SCOTT',This means that if you have convinced your DBA to give you the java grants on "/bin/ksh", you can execute any UNIX command from inside the script /tmp/dummy, with the rights of the UNIX oracle account, such as an "rm -rf" This would open the doors to badly hacking Oracle with Java. An article about the Java permissions with Oracle can be found on http://otn.oracle.com/oramag/oracle/03-jul/o43devjvm.html |
|
| [Home] [Web Design] [HTML tutorials] [Javascript] [PSP] [About us] [Links] [Anonymous email] [Best hosting] [Daily Oracle Life] [IT jobs in Switzerland] [Web Submission] [Web traffic] | |