======================================================================== Brève présentant les nouveautés de l'authentification dans Oracle 11 ======================================================================== --[ 1. Introduction ]--------------------------------------------------- Oracle est sans nul doute l'une des bases de données les plus complexes. Il suffit de chercher sur son moteur de recherche préféré pour voir le nombre de forums traitant du sujet, et le désarroi de nombreuses personnes voulant tenter l'aventure d'en installer un. SID, Listener, service name, GLobal Name, Instance, ... rien que les différents termes et façons d'atteindre la BDD en perdent plus d'un. Les consultants en sécurité informatique n'échappent pas à la règle et doivent régulièrement reprendre la documentation d'Oracle afin de comprendre les différents accès possibles à une base. Cette brève a pour ambition de défricher un peu les différents processus d'authentification sous Oracle, et ce en se basant sur la dernière version d'Oracle (11g) et notamment ses différentes nouveautés qui ajoutent plusieurs processus de sécurisation. --[ 2. Utilisateurs ] -------------------------------------------------- Tout d'abord, pour pouvoir s'authentifier, il faut évidemment avoir des utilisateurs. Certains sont définis par défaut dans Oracle et quelques uns avec des droits particulièrement élevés. Nous verrons par la suite que ceux-ci disposent d'un mécanisme d'authentification spécifique. Les utilisateurs privilégiés possèdent des droits d'administration ou des droits système, par exemple : - SYS : possède les droits SYSDBA et est propriétaire du dictionnaire ; - SYSTEM : DBA et est propriétaire de quelques vues système et outils ; - SYSMAN : utilisateur de la console OEM ou GRID. Un compte présent et régulièrement activé sur les versions plus anciennes d'Oracle est relativement intéressant du point de vue sécurité, surtout lorsqu'il est associé avec son mot de passe par défaut. Il s'agit de DBSNMP. Cet utilisateur est utile pour Oracle Agent qui remonte des informations sur la base locale et possède notamment par défaut les droits d'accès à tous les dictionnaires. Ce privilège permet entre autre de lister tous les utilisateurs/mots de passe contenus dans dba_users, ce qui en fait un compte dangereux et à désactiver. Puis viennent les utilisateurs lambdas, propriétaires ou non de différents schémas, bases ou tables : - SCOTT et ses tables EMP et DEPT - HR, schéma "ressources Humaine" - OE, schéma "gestion des commandes" - SH, schéma "ventes" etc. La grande nouveauté d'Oracle 11g vis-à-vis de cette liste d'utilisateurs vient du fait que la majorité est désactivée par défaut (incluant surtout DBSNMP). Une installation par défaut d'Oracle, sans processus de minimisation, comportera donc un peu moins de risques qu'avant. La liste exhaustive des USERS prédéfinis est donnée par la requête SQL suivante (principales colonnes seulement) : SQL> SELECT username, account_status, lock_date, default_tablespace, temporary_tablespace, profile FROM DBA_USERS; --[ 3. Authentification des utilisateurs classiques ]------------------- Il existe trois façons de s'authentifier une fois l'utilisateur défini : - authentification locale ; - authentification externe ; - authentification globale. ----[ 3.1 Authentification locale ]------------------------------------- L'authentification locale est celle que l'on retrouve le plus souvent : les utilisateurs et leur mot de passe sont stockés dans une table spécifique de la base de données. Les mots de passe ne sont évidemment pas stockés tels quels, mais sous forme d'empreinte. Jusqu'à Oracle 10g, l'algorithme utilisé pour calculer cette empreinte est DES. Une graine est également utilisée afin de se prémunir contre les attaques par tables pré-calculées (Rainbow Tables). Cette graine utilise, dans le cadre d'Oracle, le nom de l'utilisateur. C'est pourquoi il est tout de même possible de trouver des tables pour les deux utilisateurs principaux que sont SYS et SYSTEM. La taille maximale d'un mot de passe est de 30 caractères, ceux-ci étant passés en majuscules avant chiffrement. Dans 11g, on retrouve toujours cette empreinte, mais celle-ci est uniquement présente pour des raisons de rétro-compatibilité. Un nouveau format est maintenant utilisé, et est stocké dans le champ "spare4" de la table sys.user$. L'algorithme utilisé est maintenant SHA1, les mots de passe peuvent aller jusqu'à 50 caractères, sont sensibles à la casse, et une vraie valeur de sel est utilisée. L'utilisation de tables pré-calculées n'est donc plus possible. Par défaut, les deux empreintes sont donc stockées, mais il est possible de ne garder que le dernier format si tous les clients sont compatibles (la méthode est décrite dans le le-saviez-vous de mars 2011 http://www.hsc-news.com/archives/2011/000080.html). La requête listant les deux formats est la suivante : SQL> select name,password,spare4 from sys.user$ where name='HSC'; ----[ 3.2 Authentification externe ]------------------------------------ L'authentification externe est particulièrement dangereuse du point de vue sécurité. En effet, elle délègue complètement l'authentification au système d'exploitation. Il suffit donc qu'un attaquant soit identifié sur son système d'exploitation avec un nom d'utilisateur défini dans la base de données pour que celle-ci l'accepte sans demander quoi que ce soit. Cette option n'est évidemment pas activée par défaut. Pour l'activer, il faut positionner le paramètre remote_os_authent à la valeur TRUE. Cette valeur est associée à un autre paramètre : os_authent_prefix qui indique le préfixe avec lequel sera déclaré un utilisateur de l'OS dans oracle ex : le compte guest sur un OS sera défini dans oracle si le préfixe est OPS$ : OPS$GUEST Il suffit d'avoir un OS qui contient cet utilisateur, et d'être connecté avec pour pouvoir se connecter sans authentification sur Oracle. En Oracle 11, cette option est notée comme "deprecated", mais elle est encore présente pour des raisons de retro-compatibilité. ----[ 3.3 Authentification globale ]------------------------------------ L'authentification globale permet de gérer de manière centralisée la gestion des utilisateurs par l'intermédiaire d'un serveur LDAP. Dans ces cas là, les utilisateurs sont créés de la manière suivante : SQL> CREATE USER HSCLDAP IDENTIFIED GLOBALLY AS 'CN=hsc, O=hsc, C=fr'; User created. Pour les lister : SQL> SELECT username, external_name, account_status from dba_users where authentication_type='GLOBAL' ; --[ 4. Authentification des utilisateurs SYSDBA ]----------------------- Les accès aux utilisateurs ayant le privilège DBA sont différents. La raison évidente est que ces utilisateurs ont notamment besoin de démarrer une base de données (si le mot de passe est stocké dans la base de données et que celle si est éteinte....) La liste des DBA est récupérée avec la requête suivante : SQL> select grantee from dba_role_privs where granted_role='DBA'; L'authentification peut être effectuée de différentes façons : - par le système d'exploitation ; - par un fichier de mots de passe ; - par authentification forte. ----[ 4.1 Authentification par le système d'exploitation ]-------------- Par le système d'exploitation : Dans ce cas là, pour être SYSDBA, il suffit d'appartenir au groupe utilisateur dba sur unix ou ora_dba sur windows. On peut ensuite s'authentifier avec sqlplus /@service_name as sysdba (sans avoir besoin de préciser de mot de passe). ----[ 4.2 Authentification par fichier de mots de passe ]--------------- Pour pouvoir se connecter depuis un poste distant afin de démarrer les bases de données, les DBA peuvent être déclarés dans un fichier de mots de passe (cas par défaut). Ils peuvent donc ensuite se connecter via la commande : sqlplus user/pass@IP/service_name as sysdba pour lancer la BDD ou l'éteindre. (via la commande startup / shutdown) Par défaut, le fichier de mots de passe est créé avec les mêmes mots de passe que ceux définis dans la BDD, ce qui peut évidemment être intéressant. Le fichier de mots de passe se trouve dans $ORACLE_HOME/dbs/orapw pour les Unix et le fichier $ORACLE_HOME/database/PWDsid.ora sous windows. Les droits en lecture sont relativement restreints : -rw-r----- 1 oracle oracle 1536 May 11 2010 orapwXE (ces droits sont fixés par l'application qui créée le fichier). La commande suivante permet de le créer : $ orapwd FILE=monfic PASSWORD=monpasse ENTRIES=100 avec PASSWORD : le mot de passe de SYS ENTRIES : le nb max d'utilisateurs référençables dans le fichier. Pour être active, le paramètre suivant doit être positionné : SQL> show parameter remote_login_passwordfile NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ remote_login_passwordfile string EXCLUSIVE Le paramètre peut prendre 3 valeurs : - NONE ; - EXCLUSIVE : le fichier est propre à une instance (par défaut) ; - SHARED : le fichier est partagé par plusieurs instances (Ex: RAC). Via une requête SQL, on peut voir les utilisateurs qui sont présents dans le fichier (les utilisateurs sont automatiquement ajoutés lorsqu'on leur donne les droits DBA) : SQL> select * from v$pwfile_users; USERNAME SYSDB SYSOP SYSAS ------------------------------ ----- ----- ----- SYS TRUE TRUE FALSE HSC TRUE FALSE FALSE Pour récupérer la liste des empreintes et des mots de passe, on peut lancer la commande strings sur le binaire résultant de la commande. Mais ceci a deux conséquences : - du bruit est inséré dans le résultat de la commande, ce qui peut être gênant si beaucoup de mots de passe sont présents. - la commande strings limite les chaînes à celles contenant au moins 4 caractères, éliminant de facto les logins comme SYS, HSC, HR, etc. (en sachant que l'empreinte est "grainée" avec le login, il peut être compliqué de casser l'empreinte). Il est bien entendu possible de paramétrer la commande strings pour obtenir les chaînes de caractères de taille inférieure, mais cela augmente encore plus le bruit. Un rapide reverse de orapwd permet d'en extraire la structure. Le fichier est composé de blocs de 512 octets. Le premier contient des informations sur le nombre de blocs total. Le deuxième contient les premières empreintes : ===================== extrait du désassemblage de orapwd =========== push ebp mov ebp, esp sub esp, 18h mov [ebp+var_14], edi mov [ebp+var_10], esi mov esi, [ebp+arg_0] mov edx, 1Bh mov eax, [ebp+arg_4] mov [ebp+var_8], eax mov [ebp+var_18], ebx mov [esi+1Eh], dx call $+5 pop ebx add ebx, 1E1Ah lea edi, (aOracleRemotePa - 804B794h)[ebx];"ORACLE Remote Password file" mov ecx, [edi] mov eax, [edi+4] mov [esi], ecx mov [esi+4], eax mov eax, [edi+8] mov [esi+8], eax mov eax, [edi+0Ch] mov [esi+0Ch], eax mov eax, [edi+10h] mov [esi+10h], eax mov eax, [edi+14h] mov [esi+14h], eax movzx eax, word ptr [edi+18h] mov [esi+18h], ax movzx eax, byte ptr [edi+1Ah] mov [esi+1Ah], al movzx eax, word ptr [esi+40h] mov dword ptr [esi+80h], 8 and eax, 0FFFEh lea ecx, (aInternal - 804B794h)[ebx] ; "INTERNAL" mov [esi+40h], ax mov edx, [ecx] mov edi, [ecx+4] lea eax, [esi+60h] // le login "INTERNAL" sera positionné à l'octet 0x60 mov [eax], edx mov [eax+4], edi mov edi, [ebp+var_8] push 1 mov ecx, [edi+3B4h] mov ecx, [ecx] lea edx, [edi+82Ah] mov [ebp+var_C], edx lea edx, [esi+84h] // le mot de passe sera écrit à l'octet 0x84 mov [ebp+var_4], edx movzx edx, word ptr [edi+848h] movzx edi, word ptr [edi+1BCh] push dword ptr [ecx+edi*4] push dword ptr [esi+80h] // la taille du login "INTERNAL" sera à 0x80 push eax mov eax, [ebp+var_C] push edx push eax mov eax, [ebp+var_4] push 1Eh push eax call _lncupw // appel de la fonction positionnant le mot de passe et renverra sa taille mov dword ptr [esi+0E8h], 3 lea ecx, (aSys - 804B794h)[ebx] ; "SYS" mov [esi+0A4h], eax // la taille du mot de passe sera à 0xA4 movzx eax, byte ptr [esi+0A8h] or eax, 0FFFFFF0Fh mov [esi+0A8h], al movzx edx, word ptr [ecx] movzx eax, byte ptr [ecx+2] lea edi, [esi+0C8h] // login de SYS mov [edi], dx mov [edi+2], al push 1 lea eax, [esi+0ECh] // mot de passe de SYS mov [ebp+var_4], eax mov eax, [ebp+var_8] movzx edx, word ptr [eax+848h] mov ecx, [eax+3B4h] movzx eax, word ptr [eax+1BCh] mov ecx, [ecx] push dword ptr [ecx+eax*4] push dword ptr [esi+0E8h] // taille de SYS mov eax, [ebp+var_4] push edi mov edi, [ebp+var_C] push edx push edi push 1Eh push eax call _lncupw // récupération du mot de passe add esp, 40h mov edi, [ebp+var_14] mov [esi+10Ch], eax // taille du mot de passe de SYS movzx eax, byte ptr [esi+110h] or eax, 0FFFFFF0Fh mov [esi+110h], al mov ebx, [ebp+var_18] mov esi, [ebp+var_10] mov esp, ebp pop ebp retn ===================================================================== Après les différents en-têtes (Oracle password etc.) viennent les différents mots de passe par "défaut" : Internal et SYS. Ceux-ci sont positionnés aux octets du fichier : - 0x60 (96) pour le début de la chaîne du login - 0x80 (128) pour la taille du login - 0x84 (132) pour le début de la chaîne du mot de passe - 0xa4 (164) pour la taille du mot de passe Les 2 mots de passe sont espacés de 104 octets. Ce qui sera la norme pour tous les mots de passe hormis entre SYS et le suivant (116 octets). La liste intégrale des mots de passe est donc extractible facilement via un script ou un petit programme comme delphes écrit pour l'occasion. (http://www.hsc.fr/ressources/outils/delphes). ----[ 4.3 Authentification forte ]-------------------------------------- En cas de forte contrainte de sécurité, il est possible de configurer une authentification forte pour les SYSDBA et SYSOPER. Trois méthodes sont possibles : - en utilisant un Oracle Internet Directory ; - en utilisant Kerberos ; - en utilisant une authentification SSL mutuelle. --[ 5. Politique de mots de passe ]------------------------------------- Une dernière partie liée à l'authentification concerne la politique de mots de passe. Celle-ci est contenue dans un profil Oracle (qui ne se limite pas à cette seule politique). Il est possible d'obtenir la liste des profils via la requête SQL suivante : SQL> select distinct profile from dba_profiles; PROFILE ------------------------------ MONITORING_PROFILE DEFAULT Par défaut, deux profils sont présents : - Monitoring_profile pour dbsnmp - default pour les utilisateurs standards. La liste des différents attributs d'un profil est ensuite obtenue par la commande suivante : SQL> select * from dba_profiles where profile='DEFAULT'; Les attributs liés à la politique de mots de passe : CONNECT_TIME UNLIMITED FAILED_LOGIN_ATTEMPTS 10 PASSWORD_LIFE_TIME 180 PASSWORD_REUSE_TIME UNLIMITED PASSWORD_REUSE_MAX UNLIMITED PASSWORD_VERIFY_FUNCTION VERIFY_FUNCTION_11G PASSWORD_LOCK_TIME 1 PASSWORD_GRACE_TIME 7 avec : - GRACETIME : durée de vie du mot de passe après expiration du mot de passe - PASSWORD_LOCK_TIME : verrouillage après plusieurs essais de pass Deux grands changements ont eu lieu avec l'arrivée de la version 11g d'Oracle : - les mots de passe sont maintenant sensibles à la casse, ce qui augmente considérablement l'entropie. - une fonction de vérification de la solidité des mots de passe est définie par défaut (attribut PASSWORD_VERIFY_FUNCTION). Cette fonction vérifie notamment les points suivants : - 8 caractères minimum ; - au moins 1 caractère numérique et 1 caractère alphanumérique ; - différents du nom d'utilisateur ; - taille différente de la taille du nom d'utilisateur ; - différents du nom de l'utilisateur inversé ; - différents du nom du serveur ou du nom du serveur avec des chiffres. La solidité des mots de passe Oracle est donc considérablement renforcée, et évite qu'un utilisateur lambda "pêche" dans le choix de son mot de passe. --[ 6. Conclusion ]----------------------------------------------------- Oracle, avec sa version 11g, s'est donc donc beaucoup axé sur la sécurité de l'accès des différents utilisateurs par rapport aux versions précédentes. Là où il était assez courant, et aisé, de découvrir un login existant avec un mot de passe faible, permettant dans un premier temps de se connecter pour ensuite pouvoir découvrir des informations et ensuite élever ses privilèges, la sécurité a été renforcée. La version 11g permet donc de limiter, par défaut, un grand nombre d'accès, tel que l'on pouvait le trouver sur les versions jusqu'à la 10g. --[ 5. Références ]----------------------------------------------------- - Site Web d'Oracle : http://www.oracle.com/pls/db111/homepage - Site Web de Red database security : http://www.red-database-security.com/whitepaper/oracle_security_whitepaper.html ======================================================================== Yves Le Provost - Hervé Schauer Consultants ========================================================================