Oracle RCE & more
RCE: Java Store Procedure
So, imagine that you have the administrator account information. In this case, a very popular way to execute your command on the server is to write a âjava storedâ procedure. This is done in three stages. First, create a Java class called âoraexecâ. To do this, connect via âsqlplusâ terminal and write:
Next, write a PL/SQL wrapper for this class:
Thatâs it. Now, to execute a command, all you need is just to send the following query:
Note that when using the above procedure, we cannot see the results of executed command, however, you can redirect the output to a file and read it. You can find the full code of the shell that allows to read and write files:
However, there is a [more sophisticated script] (goo.gl/EuwPRU) that handles the command output, but it has a larger size here.
RCE: Scheduler
The next method, which will help us if there is no Java virtual machine, is to use âdbmsschedulerâ, the built-in task scheduler of Oracle. To use it, you must have the privilege âCREATE EXTERNAL JOBâ. Hereâs a code sample that implements the entry of â0wnedâ string into a text file in the root of the C: drive:
This will create and run a job for executing your command. And hereâs an option for calling the Scheduler from another procedure â âSYS.KUPP$PROC.CREATE_MASTER_PROCESSâ, which is of interest to us, primarily, because it allows you to embed multi-statement queries, that is, those consisting of multiple sub-queries. Theoretically, you can run such query even in case of injection into a web application.
Note that, when you use the Scheduler, you can run this job more than once and do it with some frequency. As a result, this will help you get a foothold in the tested system, because, even if the administrator deletes the user from OS, this job, which is regularly running in the system, will bring him or her back to life.
RCE: External Tables
As the last method for achieving the execution of OS commands, I would like to mention the use of External Tables. This method will help you later download files from the server. You will need the following privileges:
UTL_FILE;
CREATE TABLE;
a directory reserved for the user.
Letâs remember that the access to âUTL_FILEâ package is by default provided to all accounts with âCONNECTâ role. Step one: Check the issued directories with the following query:
Step two: Create an executable batch file with desired command:
Step three: Prepare the external table âEXTTâ, you will need it to run the file:
Now, just call your batch file with the following command:
The terminal will start to display error messages that the system cannot match the table and invoked file but, in this case, it is not important, as the main objective was to open the executable file, which you have achieved.
âODAT.pyâ utility also can implement this attack. However, it requires the privilege âCREATE ANY DIRECTORYâ, which, by default, is granted only to DBA role, since it attempts to execute the file from any and not only âyourâ directory.
Read/Write files
Now, letâs proceed to the task of reading and writing the files. If you simply need to read or write a file to the server, you can do it without any Java procedures, which, however, can also handle such tasks. Letâs have a look into âUTL_FILEâ package that has the functionality required for working with the file system. The good news is that, by default, it can be accessed by all users with âPUBLICâ role. The bad news is that, by default, this procedure has no access to the entire file system, but only to a directory pre-defined by the administrator. However, it is not uncommon to find a directory parameter specified as â*â, which literally means âaccess to everything.â You can find this out by using the following command:
I found that the shortest procedure for using âUTL_FILEâ package is proposed by Alexander Polyakov:
If you need more functionality with the ability to write, I recommend to google a script called âraptor_oraexec.sqlâ. And according to tradition, hereâs an option for using âODATâ utility, which, as always, is the shortest:
âUTL_FILEâ package is also very interesting because if youâre lucky, you can reach the logs, configuration files and obtain passwords from privileged accounts, such as âSYSâ.
The second method that I would like to mention is to use again the âExternal Tablesâ. Remember that, when using âExternal Tablesâ, the database can access in read mode the data from external tables. For a hacker, this means yet another opportunity to download files from the server, but this method requires âCREATE ANY DIRECTORYâ privilege. I suggest immediately using âODATâ, as it is stable and fast:
Elevating Privileges
You can use various methods to elevate privileges, ranging from classic buffer overflows and DLL patching to specialized attacks against databases, such as PL/SQL injections. The topic is very extensive and, in this article, I will not dwell on it, as this is discussed in large research papers, such as those found in the blogs of [Lichfield] (goo.gl/IebQN4) and [Finnigan] (goo.gl/vXhttf). I will just demonstrate some of them, so that you have a general idea. During the testing, I recommend simply paying attention to current privileges and, based on this, search for desired loopholes in the Internet.
Unlike MS SQL, where an attacker can inject âxp_cmdshellâ almost immediately after âSELECTâ by simply closing it with a quotation mark, Oracle DB flatly rejects such tricks. For this reason, we cannot every time resort to classical SQL injections although, in this case, too, it is possible to find a way out. We will consider PL/SQL injections, which are modifying the process of executing a procedure (function, trigger, and other objects) by embedding random commands into available input parameters. (Ń) Sh2kerr
In order to embed the payload, find a function where the input parameters are not filtered. Remember that Oracle SQL does not allow multi-statement (multiple) queries, therefore, most likely, you will need to use some âspecialâ procedures that have this feature. The main idea behind the attack is as follows: By default, unless specified otherwise, the procedure is executed on behalf of the owner and not on behalf of the user who started it. In other words, if a procedure owned by âSYSâ account is available for execution and you can embed your code into it, your payload will also be executed in the context of âSYSâ account. As I already mentioned, this is not what happens always, as there are procedures with âauthid current_userâ parameter, which means that this procedure will be executed with privileges of the current user. However, usually in each version, you can find some functions that are vulnerable to PL/ SQL injection. A general view of this process is shown in Fig. 2.
In short, instead of expected legitimate argument, we pass some malicious code that becomes a part of procedure. A good example is provided by âCTXSYS.DRILOADâ function. It is executed on behalf of âCTXSYSâ and does not filter the input parameter, which allows you to easily rise up to DBA:
However, by now, this is probably history, since the vulnerability was found in 2004, and it affects only the old versions 8â9. Usually, the process of escalating the privileges is divided into two parts: writing the procedure that increases the rights and performing the injection itself. A typical procedure is as follows:
Now we can inject a procedure as an argument of vulnerable function (example for versions 10x):
In the not too recent versions 10 and 11, there is one âniceâ exception, or rather a vulnerability, that allows you to execute commands on the server without having DBA rights: âDBMS_JVM_EXP_PERMSâ procedure allows a user with âCREATE SESSIONâ privilege to get âJAVA IOâ rights. The attack can be mounted as follows:
Now that you have the privileges to call up Java procedures, you can evoke a response from the Windows interpreter and execute something:
Last updated