Call: +44 (0)1904 557620 Call

Pete Finnigan's Oracle Security Weblog

This is the weblog for Pete Finnigan. Pete works in the area of Oracle security and he specialises in auditing Oracle databases for security issues. This weblog is aimed squarely at those interested in the security of their Oracle databases.

[Previous entry: "Oracle 11g Security - part 5 {Playing for time}"] [Next entry: "September 2007 - 3 years of Oracle security blogging"]

Oracle 11g Password algorithm revealed

I have posted a few entries in this blog about the new Oracle 11g features and I have concentrated on the new SHA1 11g password algorithm. I made a post titled "Oracle 11g Security - part 5 {Playing for time}" on wednesday - a comment was added on Thursday the 20th by Niels to reveal the algorithm which i already knew. Niels example is in PHP.

The algorithm is very simple and easy to guess. Once you realise that the SHA1 hash stored in SYS.USER$.SPARE4 is too long. I mentioned this before here in this blog. The SHA1 verifier should be 160 bits but the spare4 column holds S: and a further 240 bits of hash. It was clear from some investigations that the password function used a salt and also it was obvious that the salt is stored also in SPARE4. the data is even prepended by S:. It then becomes a simple guess as to whether the algorithm is SHA1(userpwdsalt), SHA1(saltuserpwd), SHA1(pwdsalt) or SHA1(saltpwd) a few experiements with PL/SQL and DBMS_CRYPTO reveals the result.

The algorithm is simple. This can be described as:

sys.user$spare4 = SHA1(pwd concat with salt) contat with salt

or to test

substr(spare4,3,40) = SHA1(pwd concat with substr(spare4,43,10)

Here is a simple test case to show how to verify the Oracle 11gR1 password algorithm:

Connected to:
Oracle Database 11g Enterprise Edition Release - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> connect sys@ora11g as sysdba
Enter password: ******
SQL> create user g identified by g;

User created.

SQL> @c:\11g_notes\sha1.sql
PWD to test [manager]: g
PWD found

PL/SQL procedure successfully completed.


Then try an invalid password:

SQL> @c:\11g_notes\sha1.sql
PWD to test [manager]: G
PWD not found

PL/SQL procedure successfully completed.


OK, the simple algorithm works. the code in sha1.sql is:

SQL> get c:\11g_notes\sha1.sql
1 set feed on
2 set head on
3 set arraysize 1
4 set space 1
5 set verify off
6 set pages 25
7 set lines 80
8 set termout on
9 set serveroutput on size 1000000
10 undefine user_to_find
11 undefine pwd_guess
12 accept user_to_find char prompt 'NAME OF USER TO CHECK [system]: ' default system
13 accept pwd_guess char prompt 'PWD to test [manager]: ' default manager
15 lv_pwd_raw RAW(128);
16 lv_enc_raw RAW(2048);
17 lv_hash_found varchar2(300);
18 cursor c_main(cp_user in varchar2) is
19 select substr(spare4,3,40) hash,
20 substr(spare4,43,20) salt,
21 spare4
22 from sys.user$
23 where name=cp_user;
24 lv_user c_main%rowtype;
26 open c_main(upper('&&user_to_find'));
27 fetch c_main into lv_user;
28 close c_main;
29 lv_pwd_raw:= utl_raw.cast_to_raw('&&pwd_guess')||hextoraw(lv_user.salt);
30 lv_enc_raw := sys.dbms_crypto.hash(lv_pwd_raw, 3);
31 lv_hash_found:=utl_raw.cast_to_varchar2(lv_enc_raw);
32 if lv_enc_raw = lv_user.hash then
33 dbms_output.put_line('PWD found');
34 else
35 dbms_output.put_line('PWD not found');
36 end if;
37* END;

11g brings case sensitivity but a major flaw exists in that the older 10gR2 and lower algorithm is also still used and the SYS.USER$.PASSWORD column still contains the lower version case insensitive password. As I have discussed here recently there have been improvements to protect the hashes but if the SHA1 hash is available then the older one is also and this makes cracking the passwords via a dictionary or brute force attack easier.

FX has also added a blog entry to his blog titled "Oracle 0xDEADF00D" which details Recurity Labs efforts to crack the Oracle 11g SHA1 Password algorithm using rather more technical methods than I used. its well worth reading how he used IDA Pro, GDB and FindCrypt to locate the function responsible for creating the hash in the Oracle 11g binary on Linux.

There has been 2 Comments posted on this article

September 29th, 2007 at 01:11 pm

Pete Finnigan says:

Check for a recently released cracker.

September 30th, 2007 at 10:37 am

Pete Finnigan says:

Thanks for the link, I actually already found your tool on Friday and tested it. I was planning to do a blog entry later about it.