Why are we looking at the password algorithm? - two reasons , we would like to be able to test for weak passwords and also we would like to see if the new algorithm is weaker than the old.
Yesterday we fixed CTIME by using the fixed_date parameter but PTIME is not fixed. One way to check if PTIME is used in the authentication (we cannot easily prove if its used in the salt) is to update SYS.USER$ and see if we can still log in:
SQL> connect system@ora11g Enter password: ****** Connected. SQL> set serveroutput on size 1000000 SQL> exec print_table('select * from sys.user$ where name=''Z'''); USER# : 110 NAME : Z TYPE# : 1 PASSWORD : 319B5E833E3291F7 DATATS# : 4 TEMPTS# : 3 CTIME : 18-sep-2007 17:05:12 PTIME : 18-sep-2007 17:05:12 EXPTIME : LTIME : RESOURCE$ : 0 AUDIT$ : DEFROLE : 1 DEFGRP# : DEFGRP_SEQ# : ASTATUS : 0 LCOUNT : 0 DEFSCHCLASS : DEFAULT_CONSUMER_GROUP EXT_USERNAME : SPARE1 : 0 SPARE2 : SPARE3 : SPARE4 : S5FE25BF206BEFF6BB589C830E111C363A906C191704E35978F32A1F6164 SPARE5 : SPARE6 : ----------------- PL/SQL procedure successfully completed. SQL> update sys.user$ set ptime=to_date('18-sep-2007 18:00:00','DD-MON-YYYY HH24:MI:SS') 2 where name='Z'; update sys.user$ set ptime=to_date('18-sep-2007 18:00:00','DD-MON-YYYY HH24:MI:SS') * ERROR at line 1: ORA-01031: insufficient privileges SQL> connect sys@ora11g as sysdba Enter password: ****** Connected. SQL> / 1 row updated. SQL> commit; Commit complete. SQL> grant create session to z; Grant succeeded. SQL> connect z/z@ora11g Connected. SQL> |
Ok, so changing the PTIME for user proves that the salt is not read from data in SYS.USER$ as part of the authentication process, it doesn't prove whether PTIME is part of the salt. A second test that used to be useful for pre 11gR1 was to show that a password for a user XX/X and a user X/XX were the same. For 11g we already know that this is not the case but if the salt were based on ptime then the hashes would be the same if user/pwd for X/XX and XX/X produced the same hash. This is a newton raphson issue as we have two or more unknowns, we dont know if PTIME affects the salt/hash and whether XX/X and X/XX should produce the same hash. lets test anyway. How can we get the same PTIME and CTIME for two users?
Run this script:
-- create a number users fast to see if we can get the same PTIME for each drop user yyyy; drop user yyy; drop user yy; drop user y; create user yyyy identified by y; create user yyy identified by yy; create user yy identified by yyy; create user y identified by yyyy; set serveroutput on size 1000000 exec print_table('select name,password,ctime,ptime,spare4 from sys.user$ where name like ''Y%'''); |
Running gives:
SQL> connect system@ora11g Enter password: ****** Connected. SQL> @fast_cr User dropped. User dropped. User dropped. User dropped. User created. User created. User created. User created. NAME : Y PASSWORD : 25712A8BFC65A418 CTIME : 18-sep-2007 18:50:24 PTIME : 18-sep-2007 18:50:24 SPARE4 : S:AC003C8C1DB8A7A097C4DE69059ACD3E0FB2F7654C893239029D5359B9BC ----------------- NAME : YY PASSWORD : 25712A8BFC65A418 CTIME : 18-sep-2007 18:50:24 PTIME : 18-sep-2007 18:50:24 SPARE4 : S:FC48CEC1B9204C770E6782AE69BD80F2FC5727BC370B64FEAC5928140091 ----------------- NAME : YYY PASSWORD : 25712A8BFC65A418 CTIME : 18-sep-2007 18:50:24 PTIME : 18-sep-2007 18:50:24 SPARE4 : S:C92FBDBAA3B255F2C8F68AD4DCFB575E06EA2F003378AAC91B1F2303F06A ----------------- NAME : YYYY PASSWORD : 25712A8BFC65A418 CTIME : 18-sep-2007 18:50:24 PTIME : 18-sep-2007 18:50:24 SPARE4 : S:3756488C7B6AE75FF4AF4A05047CAE903ABAE8A969A4F2A6A2370A4185A3 ----------------- PL/SQL procedure successfully completed. SQL> |
So all the old passwords are the same, also the CTIME and PTIME are the same for each user but the new hashes are not. Does this mean neither date are involved in the hash or that XX/X does not produce the same password as X/XX. I am sure the latter is true, that XX/X doesn't produce the same password as XX/X as this was a weakness in earlier versions, hashes could in rare circumstances be the same, I am sure Oracle fixed this in 11gR1. Is PTIME involved in the salt? - dont know.
OK, now I will start to look and blog about something different in 11g Oracle Security next..
September 20th, 2007 at 11:18 am
Pete Finnigan says:
Hi Pete,
The oracle password hash seems to be calculated like this:
sha1(password . 10 character salt)
the salt is then appended to the sha1 hash in hexadecimal format.
The following PHP code verifies Oracle 11g hashes:
echo verifyOraclePass('AC003C8C1DB8A7A097C4DE69059ACD3E0FB2F7654C893239029D5359B9BC', 'yyyy') ? "YES\n" : "NO\n";
function verifyOraclePass($saltyhash, $plain)(
if(strlen($saltyhash) != 60)(
trigger_error("Invalid password hash length", E_USER_NOTICE);
return false;
)
$saltyhash = strtolower($saltyhash);
$salt = substr($saltyhash, 40);
$hash = substr($saltyhash,0,40);
return sha1($plain . pack("H*", $salt)) . $salt == $saltyhash;
)