I came across an interesting application recently, that seemed to break every single rule in the book where it came to security.
I first noticed something was up, when I was waiting for the app to run a basic database search (which could take several minutes, during which time the app froze and became unresponsive with the window not redrawing). I was idly clicking explorer windows on the client PC and came to the C:\ directory. There was something interesting there; a file called 'usercache.txt'.
I loaded it up. It was a CSV file that was fairly obviously a cached copy of the 'users' database table for the business app. It included everything, user role, admin privileges, login name, real name, password ("encrypted"), entire password history, etc.
Examining the passwords, it was painfully obvious that the encryption was crude. Just eyeballing the file, and my own password history, it was fairly obviously some type of polyalphabetic substitution cipher (aka Vigenere cipher, but extended to include numerals). As a lot of people had their first password as the 'default' first password (password) in the history, it soon became apparent that the encryption 'key' was the username + a fixed offset.
Why this was cached instead of just running an SQL query on the oracle server against it, I don't know. Maybe it was for performance reasons.
Anyway, I tinkered around further. This time I just browsed the network explorer window and found the app server. Clicked on it, and opened the shared drive (Initially, I was somewhat surprised to find that I could log on freely as guest and see lots of apparently interesting files. But then, the app ran fine when run under the windows guest account, so I guess this was deliberate).
The files on the totally open app server share were quite interesting:
Text files containing conversations from the integrated private-messgaing function in the app, and .wav files containing everyone's voice messages and voice memos.
However, much more interesting than this was the [applicationname].ini file on the root of the file share.
This contained the very interesting segment:
Hmm. I wonder what that could possibly do.
Anyway, my interest was piqued at this point, so I thought I'd try a more directed approach. I popped in a USB stick and copied the app .exe file to it. Took it home and threw it at some decompilers.
The findings here were just as interesting:
1. All the database queries where strings in the application source. There were no views, and no stored procedures.
2. The query strings were built programmatically. Although prepared statements for user-supplied fields were used appropriately, many of the parameters in the .ini file were used to construct the query strings without any escaping.
3. There was no 'runtime' checking of user credentials/rights/etc. except after the login procedure.
4. The password encryption was confirmed to be a polyalphabetic substitution cipher using the usename as key.
5. The examination of the code confirmed the reason for some peculiar data corruption and database inconsistencies that I'd noticed following client crashes. There were no transactions used anywhere in the app. Command batches that updated multiple tables relied purely on seredipity to ensure consistent data.
And you know the best thing about this system:
It's an electronic patient record system at a major hospital - and it was installed just a few weeks ago!
N.B. Passwords have been changed to protect the guilty.
I first noticed something was up, when I was waiting for the app to run a basic database search (which could take several minutes, during which time the app froze and became unresponsive with the window not redrawing). I was idly clicking explorer windows on the client PC and came to the C:\ directory. There was something interesting there; a file called 'usercache.txt'.
I loaded it up. It was a CSV file that was fairly obviously a cached copy of the 'users' database table for the business app. It included everything, user role, admin privileges, login name, real name, password ("encrypted"), entire password history, etc.
Examining the passwords, it was painfully obvious that the encryption was crude. Just eyeballing the file, and my own password history, it was fairly obviously some type of polyalphabetic substitution cipher (aka Vigenere cipher, but extended to include numerals). As a lot of people had their first password as the 'default' first password (password) in the history, it soon became apparent that the encryption 'key' was the username + a fixed offset.
Why this was cached instead of just running an SQL query on the oracle server against it, I don't know. Maybe it was for performance reasons.
Anyway, I tinkered around further. This time I just browsed the network explorer window and found the app server. Clicked on it, and opened the shared drive (Initially, I was somewhat surprised to find that I could log on freely as guest and see lots of apparently interesting files. But then, the app ran fine when run under the windows guest account, so I guess this was deliberate).
The files on the totally open app server share were quite interesting:
Text files containing conversations from the integrated private-messgaing function in the app, and .wav files containing everyone's voice messages and voice memos.
However, much more interesting than this was the [applicationname].ini file on the root of the file share.
This contained the very interesting segment:
Code:
[ClientDatabaseConnectionString]
Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=EPRORA)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)));User Id=SYSTEM;Password=D7g8Yj2-+f;
Hmm. I wonder what that could possibly do.
Anyway, my interest was piqued at this point, so I thought I'd try a more directed approach. I popped in a USB stick and copied the app .exe file to it. Took it home and threw it at some decompilers.
The findings here were just as interesting:
1. All the database queries where strings in the application source. There were no views, and no stored procedures.
2. The query strings were built programmatically. Although prepared statements for user-supplied fields were used appropriately, many of the parameters in the .ini file were used to construct the query strings without any escaping.
3. There was no 'runtime' checking of user credentials/rights/etc. except after the login procedure.
4. The password encryption was confirmed to be a polyalphabetic substitution cipher using the usename as key.
5. The examination of the code confirmed the reason for some peculiar data corruption and database inconsistencies that I'd noticed following client crashes. There were no transactions used anywhere in the app. Command batches that updated multiple tables relied purely on seredipity to ensure consistent data.
And you know the best thing about this system:
It's an electronic patient record system at a major hospital - and it was installed just a few weeks ago!
N.B. Passwords have been changed to protect the guilty.
Last edited: