Passwörter wiederherstellen in Oracle 11g

,

In der Datenbank Version 11gR1 hat Oracle bekanntlich case-sensitive Passwörter und einen neuen Passwort-Algorithmus eingeführt. In der Datenbank werden nicht die Klartext-Passwörter, sondern nur deren Hashes abgelegt, und der Algorithmus, mit dem diese Hashes berechnet werden, war bei 10g 3DES, und ist seit 11g SHA1. Im 10g-Hashverfahren fliesst der Username als Salt in den Hash mit ein, während ab 11g ein zufälliges Salt verwendet wird. Ab 11g können die Hashes also zwischen verschiedenen Benutzern geteilt werden.

Will man das Passwort eines Benutzers sichern, um es beispielsweise in einer anderen Datenbank wieder einzuspielen, kann man sich den Hash im Data Dictionary suchen (der 10g Hash steht in SYS.USER$.PASSWORD, der 11g Hash in SYS.USER$.SPARE4), und dessen Wert mit Hilfe der “BY VALUES” Klausel beim Anlegen eines neuen Users angeben:

CREATE USER AKIRA IDENTIFIED BY VALUES ‘DA3A39221404DD55’; –10g hash

ALTER USER AKIRA IDENTIFIED BY VALUES ‘S:3CAFD1F43D6958FD4F67C2EDD91B3FF54913344723750F6AE48C802D37E4’ –11g hash

Oracle erkennt hier selbstständig aus dem verwendeten Wert, ob es sich im einen 10g oder um einen 11g Hash handelt. Wird ein 11g Hash angegeben, löscht die Datenbank allerdings den 10g Hash aus dem Dictionary – und umgekehrt. Normalerweise kann man mit dieser Syntax also nur entweder einen alten oder einen neuen Hash setzen, aber nicht beide, wie man es zur vollständigen Wiederherstellung eines bisherigen Zustandes in einigen Fällen bräuchte.

In der MOS Note (Doc ID 1051962.101) hat Oracle beschrieben, wie man beide Hashes mit der “BY VALUES” Syntax eintragen kann:

alter user TEST identified by values
‘7A0F2B316C212D67;S:F3F4BA77C0E960A5973095AF787988CBE52410CB2EA53F6AF008AD99179B’;

Indem man beide Hashes mit einem Semikolon getrennt zusammen angibt.

Bei der Authentifikation ab 11g existiert eine erschreckende Sicherheitslücke im O5LOGON Protokoll, das es einem Angreifer ermöglicht, den Session Key und das Salt auszulesen, ohne Spuren zu hinterlassen. Um sie zu schließen, haben einige Datenbankadminstratoren die 11g-Authentifizierung ganz ausgeschaltet, indem sie den Parameter “SEC_CASE_SENSITIVE_LOGON=FALSE” gesetzt oder alle 11g-Hashes aus dem Dictionary gelöscht haben.

In dieser Kombination kann es zu dem Effekt kommen, dass Passwörter zum Beispiel beim Aufbau einer Testumgebung mittels der BY VALUE Methode mit einem gespeicherten 11g-Hash zurückgesetzt werden, sich aber danach kein Anwender anmelden kann, weil in der Quell-Datenbank noch der 10g-Hash verwendet wurde, dieser aber durch das Neu-Setzen des 11g-Hashes überschrieben wurde, und die Anmeldung nur mit einem 11g-Hash nicht funktioniert. Hier hilft dann die oben beschriebene Methode, beide Hashes anzugeben, so man sie denn gesichert hatte.

Siehe auch zum Thema:
  • Marcels Blog Post zum Thema Hashes in 11g. Hier wird auch der verwendete Algorithmus vollständig beschrieben.
  • “Cryptographic flaws in Oracle Database authentication protocol”, Esteban Martínez Fayó

DB Link Passwörter Metadaten in 11.2.0.4

, ,

Seit der Datenbank Version 11.2.0.4 funktioniert das Auslesen der Beschreibungen für Datenbank-Links über DBMS_METADATA.GET_DDL nicht mehr. Statt des Passwort Hashes wird nun eine Bind Variable angezeigt.

Die Passwörter von Datenbank-Links wurden früher in der PASSWORD-Spalte der Tabelle SYS.LINK$ im Klartext abgelegt und waren einfach lesbar. In Version 10gR1 wurde der Zugriff auf diese Tabelle aus der Rolle SELECT ANY DICTIONARY entfernt, mit 10gR2 wurde die Spalte PASSWORDX eingeführt, die nun nur noch den Hash speichert.  Mit der Sicherheit dieses Hashes steht es allerdings auch nicht zum Besten.

Während es in älteren Versionen möglich war, die komplette Link-Beschreibung inklusive der Passwort-Hashes in einer “BY VALUES”-Klausel auszulesen, sieht das Ergebnis in 11.2.0.4 so aus:

SQL> SELECT OWNER, DB_LINK, DBMS_METADATA.GET_DDL('DB_LINK',DB_LINK,OWNER) as DDL FROM DBA_DB_LINKS;
OWNER          DB_LINK      DDL
-------------- ------------ ----------------------------------------------------------
SYS            TEST_LINK    CREATE DATABASE LINK "TEST_LINK"
                            CONNECT TO "DBLINK_ACCOUNT" IDENTIFIED BY VALUES ':1'
                            USING 'TNSALIAS'

Der für den Link notwendige Hash steht allerdings immer noch in der PASSWORDX-Spalte der SYS.LINK$-Tabelle, und kann mit Hilfe von DBMS_CRYPTO recht einfach ausgelesen werden:

SQL> select 
 name, 
 userid, 
 utl_raw.cast_to_varchar2(dbms_crypto.decrypt((substr(passwordx,19)), 
  4353, (substr(passwordx,3,16)))) 
from sys.link$;

NAME       USERID         UTL_RAW.CAST_TO_VARCHAR2(DBMS_CRYPTO.DECRYPT
                          ((SUBSTR(PASSWORDX,19)),4353,(SUBSTR(PASSWORDX,3,16))))
---------- ---------      -------------------------------------------------------
TEST_LINK  DBLINK_ACCOUNT GEHEIMESPASSWORT

Oft wird eine solche Möglichkeit benötigt, um Skripte zu erstellen, die Objekte wie Links zusammensuchen, um sie zu paketieren und für Deployment bereitzustellen.

Dieser Bug in der Datenbank Version 11.2.0.4 ist bei Oracle klassifiziert unter: Bug 18461318. Der Status dieses Bus steht allerdings auf “44 – Not Feasible to fix, to Filer“, was nicht sehr vielversprechend klingt.


Update 23.11.2017: Es findet eine Verschlüsselung, keine Hash-Wert-Berechnung, des Link-Passwortes statt, und diese lässt sich brechen.