For those who are ultra-conscious about security within the Oracle RDBMS, particularly when the topic involves the weaknesses of Oracles password mechanism or algorithm, older versions of Oracle (especially 10g and below) are always going to be viewed as a hackers target of opportunity. Almost nothing you can do, so it seems, will ever give you 100% protection against hackers. There are many areas you can shore up, but some constants remain, and those include the fact that some people are always going to have access to sensitive data and that the vast majority of client connections will involve transmitting data across a network.
The word hacker needs to be qualified a bit for the purposes of this article. The hacker of interest used in the following demonstrations is you, the DBA. How can a DBA be a hacker, given that you have the keys to everything within the database in the first place? Just because you have access to all data doesnt mean you can view all data. In particular, you can view the hashed value of passwords, but not the passwords themselves.
Why would you want to see actual password values? To be a bit more restrictive, why would you want to know what a particular plaintext password is? You can war game lots of scenarios where this may be necessary, but one that may be more common than not is due to the use of legacy applications, relatively high personnel turnover, and poor password management/documentation in the first place. Changing SYS and SYSTEM passwords is typically not an issue, but what about the password for the OLD_APP schema?
Before testing the identified by values temporary changing of the password routine, you may need the plaintext value. I dont know, something about .NET developers always wanting to store unencrypted passwords in a configuration file and then the file gets trashed during a server crash and no one knows how to 1) rebuild the application, or 2) reconnect the application comes to mind.
An Internet search for Oracle password crackers turns up a good bit of information and even points you towards homegrown hacker-like applications. For our (benevolent) purposes, I selected Laszlo Toths woraauthbf tool, which you can read about and download from here (http://www.soonerorlater.hu/index.khtml?article_id=513). The program is very much as-is (Elpased instead of Elapsed), but it serves our purposes quite well.
To provide a bit more information about whats documented, you can use woraauthbf against older versions of Oracle by creating a text file with the username, hashed password, the SID and the server name. The only parts which have to be real are the username and hashed password value. Why is that? Upon further research into how Oracle constructs the hashed value, youll learn that the username and password are concatenated. The SID and server name have nothing whatsoever to do with constructing the hashed value. Other cracker programs rely on network information such as the client and server IP addresses and ports and a third party sniffer tool to snoop the data being transmitted between the client and server.
Using the tool
Lets move on to a quick example. Create a password file by copying the output from the following (or spooling) to a simple txt file:
select username||':'||password||':'||name||':'||host_name||':' from sys.dba_users, sys.V_$DATABASE, sys.v_$instance;
Again, the name and host_name can be whatever you want, or just use the real values. My example is:
Scotts password is tigers (which is eventually reported as TIGERS, another knock on Oracle for ignoring case), taking the length up to six characters from five. After unzipping the downloaded file, open a CMD prompt/DOS window and invoke the command from that location. Using a password file named password_file.txt, the command line text is:
woraauthbf.exe -p c:\password_file.txt
The output from this session (using all of the defaults) is shown below.
C:\[my path]>woraauthbf.exe -p c:\password_file.txt Usernames will be permuted! The number of processors: 2 Number of pwds to check: 321272406 Number of pwds to check by thread: 160636203 Password file: c:\password_file.txt, charset: alpha, maximum length: 6, type: hash Start: 0 End: 160636203 Start array thread with 489 number of passwords! Start: 160636203 End: 321272406 Writing session files... Writing session files... Password found: SCOTT:TIGERS:ORCL:MYPC Elpased time: 164s Checked passwords: 153976754 Password / Second: 938882
The program calculated that slightly more than 321 million passwords needed to be checked (but 26 to the 6th power is a bit more than 308 million), and with two processors, the workload was evenly divided. The default character set was alpha (A-Z) and it took a whopping 164 seconds to determine that Scotts password is TIGERS. Also of interest is the passwords checked per second rate of 938,882. We hit on the password before exhausting all possible values, which you would expect to hit around the halfway point anyway.
Excluding physical limitations (the number of CPUs and processor speed, which when running this expect to see the performance meter peg around 99% for this program), two key factors come into play in the run time. If, and that is a big IF, you know the length and the character set (purely alphabetical versus alphanumeric versus alphanumeric plus special characters), you can greatly reduce the number of passwords to be checked. This is a case where it is better to start off with a small guess and let that run as opposed to opening up the criteria to everything. The run time ramps up extremely fast after a certain point.
As an example, I changed the character set to alphanum, and the run time to get Scotts unchanged password went up to over six minutes. With another users password info added to the same password file, knowing ahead of time that is also length 6 and alphanumeric, the run time took over 29 minutes. (The second user name and password shown below have been edited for privacy reasons.)
woraauthbf.exe -p c:\password_file.txt -m 6 -c alphanum Usernames will be permuted! The number of processors: 2 Number of pwds to check: 2238976116 Number of pwds to check by thread: 1119488058 Password file: c:\password_file.txt, charset: alphanum, maximum length: 6, type: hash Start: 0 End: 1119488058 Start: 1119488058 End: 2238976116 Start array thread with 490 number of passwords! Writing session files... Writing session files... Writing session files... Writing session files... Writing session files... Writing session files... Password found: SCOTT:TIGERS:ORCL:MYPC Writing session files... Writing session files... Writing session files... ... Writing session files... Writing session files... Password found: SOMENAMES:X1M72Y:ORCL:MYPC Elpased time: 2152s Checked passwords: 1917149967 Password / Second: 890868
The second entry in the password file came from an 8i database, while Scotts hashed value came from a 10g version. I didnt use the o option to specify the oran10.dll either. The implications of this should be very clear: protect access to anything showing usernames and their hashed password values, particularly the SYS.USER$ fixed table (not relying on DBA_USERS view as that can be spoofed).
The run time to get the second users plaintext password was quite reasonable. You could easily spend hours and hours scouring files looking for the password being embedded in a script. My test was run on an ancient IBM ThinkCentre with 3GHz and 2GB RAM, certainly nothing fancy. In the second run, the rate dropped slightly, but Im happy being able to check about 900,000 passwords a second. If you need to determine a hidden (more like forgotten) password, this tool, and several others just like it, especially given the free cost, will do the trick. Spending several hours (or even a few days) on CPU time may be a cheaper route than having to socialize changing a forgotten password with users who are quite against any downtime because their application no longer works.