Published on December 6th, 2013 | by NJ Ouchn0
Revisiting Oracle Privilege Escalation Attacks in SQLi Lab
Submitted by :
SQLi Lab is a unique platform which lets people master the Art of Exploiting SQL Injection. When you sign up for the lab you get access to the VPN through which you can access 27 challenges which have over 90+ objectives. The lab has 4 databases MS-SQL, Oracle, Postgres and Mysql. The challenges are split into three difficulty levels (basic, intermediate and advanced). Subscription to the lab includes full solution of each challenge (both PDF and video walk-through). From SQLi 101 to mind bending issues such as 2nd order injection, privilege escalation attacks, code execution etc; there is something for everyone.
In this article, we are going to look at some of the recent additions to the SQLi lab. Challenge 21-27 of SQLi Lab relates to Oracle Database privilege escalation attacks. For these, you don’t need a browser, but you require a database client to connect to the database and issue queries.
Login to the oracle database based on the following information [Level: Intermediate]
- List the permissions/privileges of current user. (create any trigger)
- Escalate privileges and become DBA
Login to the database as user4. We will use a client called Razor SQL to connect to the database. You can use any other database client.
List the current privileges by issuing the query “select * from session_privs”:
Note: that we have a high privilege CREATE ANY TRIGGER.
Before we go any further, lets revisit the privilege model on which objects (such as procedures, functions, trigger etc) get executed in Oracle. By default, the objects in Oracle are executed with privileges of the definer. Think of it like suid files in linux. Just as you have the ‘passwd’ executable in linux, which always run as owner (root) irrespective of which user executes it and updates the /etc/shadow file based on user’s new password. Similarly, by default all objects in Oracle by default executes with the permission of the owner/definer. The reason for this is as following:
Let’s assume a privileged user (say SYS) created a stored procedure and gave an unprivileged user (say SCOTT) execute permission on this stored procedure. Typically this SYS created stored procedure will interact with other objects in SYS schema (e.g. it may query a particular table). If the stored procedure were to execute with privileges of SCOTT, then in-order for stored procedure to work, SYS will need to explicitly identify all objects the stored procedure interacts with and then grant SCOTT access to interact with these objects. To save all that hassle, it’s easier to have the stored procedure execute with SYS privilege. So, who-ever has permissions to execute this SYS created stored procedure, will always execute this procedure as SYS.
Note: if SYS wants this stored procedure to be executed with privileges of invoker, then he can specify the keyword AUTHID CURRENT_USER within the procedure and now the privileges are dropped and the procedure is executed with the permission of user invoking it.
Also note that the concept of “Owner/definer”. Typically, an owner/definer is NOT the user which created that object, but it’s the schema in which the object belongs. The difference between CREATE TRIGGER and CREATE ANY Trigger is, with CREATE ANY TRIGGER privilege, a user can not only create a trigger in his own schema but in any other user’s schema. Note: when we say any other user’s schema, it excludes SYS schema.
Thus, if we can create a trigger into a high privileged user’s schema and then execute an event which will invoke our crafted trigger than the trigger will get executed with privileges of DBA user and then we can execute or SQL code defined in trigger as DBA.
Note: the table SYSTEM.OL$ is a special table and PUBLIC have insert privileges on this table. So, we can create a trigger in SYSTEM schema based on insert done on table SYSTEM.OL$
create or replace trigger "SYSTEM".the_trigger
before insert on system.OL$ for each row
declare pragma autonomous_transaction; begin
execute immediate 'grant dba to user4';
As per the trigger above, every-time an insert is made on table SYSTEM.OL$ the trigger will execute the statement ‘GRANT DBA TO USER4’ (with permissions of SYSTEM user).
Now if we do an insert into SYSTEM.OL$ the trigger will be invoked.
This should give us DBA role. If we logout and log back in, we can verify this:
The indirect privilege escalation attacks have been very well described by David Litchfield in his book, Oracle hacker’s handbook. To practices a variety of privilege escalation attacks as well as to master SQL Injection, please visit the SQLi Lab.