The Ultimate Security Hole in Microsoft Access

nIGHTmAYOR

Registered User.
Local time
Today, 01:18
Joined
Sep 2, 2008
Messages
240
Ok so here goes:
In my hunt of securing my access application I was confrunted only 1 challenge. And hopefully nobody would even try and think of System.mdw Security permissions to solve it ;)
Now the one and only hole that cant seem to be solved by any conventional mean is (Drum Rolls):

MSysObjects (Connect field to be specific)

Well I wouldnt expect a differance realy if they had it encrypted to cover up back end db/user password because for a mysterious reason Microsoft Encription Algorythms are marked the fastest to decode by internet underground community.

Listed are part of how geeks thought to secure it (knowingly that microsoft believes that all to it is setting up a security permission - yes right and give the exploiter the hassel of another 5 minutes to download and install another System.mdw passwords recovery pack):

1-Linking Tables Dynamicaly upon firing of front end

- Buzz Sound -

** Exploiter can still use "Link Table Manager" to connect to table from external database and retrieve connection string


2-Linking Tables Dynamicaly upon firing of front end and then locking the table access via DAO call

- Buzz Sound -

** Exploiter can still use "Link Table Manager" to connect to table from external database running a timer loop retrieve connection string upon first lock release for utilization


3-Linking Tables Dynamicaly on each and every call and deleting it post call execution

- Buzz Sound -

** Ok I'll try not to think of you as crazy , have you tried this before ? ok not commenting the rediculious time it takes a table to link programatically for a misterious reason , all it takes is to End Task application while in the middle of a call causeing the delete procedure to fail then you know the drill..

Now through my experimentations the issue could only be resolved through hex editing the database , which I am not realy sure if it would be fine with microsoft as ownership of database file vary to ownership of database structure (Now if someone could elaborate on this I'd be glad the line is thin here).

Waiting for your thoughts in anticipation.

Best regards,
nIGHTmAyor
 
Last edited:
Or not storing the password at all.

In my case, I prompt for a username and password which my user enters, then code hashes it just in time and use it as the connection string. The saved objects themselves do not store the user/password (there's an option to disable that... think in registry or something like that). This way, you only use password once for the initial connection which is stored in an area that is inaccessible from VBA or Access interface and all other connections, having same parameters (e.g. database, server, etc) is assumed to use the same authorization as the initial connection.

Hashing the password is a good extra step as this makes keyboard logger ineffective because what user typed is not same as what was being passed in the paraameter. Of course, this won't stop the packet sniffer, but that's why I use SSH connection. Doing everything just in time also guarantees that I do not have any password lying around to be picked up.
 
Banana arent you the cutest :)
Giving the users database password and all.
This reminds me of the time when microsoft realized that most attacks and crashes of microsoft isa 2000 are generated by internal users of the network because they were annoyed by bandwidth limititing rules so for a fix microsoft decided to remove bandwidth limititing option in isa 2004 and announced that isa 2004 uptime has increased by 70 %
 
Just to be clear, they only have a password to access the database (and the key file for SSH); they do not actually know the password (which has been salted & hashed) passed in the connection string so that if they tried to connect by other means, they would be summarily refused.

Since the database is distributed in MDE, it's quite difficult to debug for the hashs as they're created. Now, theoretically, someone could use an utility to look at the heap stack and map the variable, but since it's passed several places, it will be quite an effort.

A perfect security is impossible; all I can hope is to make it so hard that social engineering is the easiest way to break my security model. That way, the blame is on the users, not me.


I'm afraid I'm not following the point about users & bandwidth limiting for ISA...


EDIT: I forgot to mention I use DNS-less connection to avoid storing the confidentials in DSN, whether it be a file or in system registry. Once again, just in time for the win.
 
Last edited:
Just to be clear, they only have a password to access the database (and the key file for SSH); they do not actually know the password passed in the connection string so that if they tried to connect by other means, they would be summarily refused.
sounds like there might be a smart thought here hidden somwhere , please elaborate :D
 
My method:

Pop up a login form. User enters username and password. Of course, the password textbox is masked.

I then pass both to a function that:

1) Immediately hash the password with SHA-256.
2) Clear the textbox.
3) Hash the username, then pseudo-randomly select a salt using one method
4) Hash the username with MD5, then pseudo-randomly select an operator.
5) Perform a mathematical operation on the hashed password with the selected salt using the selected operator. (Note: The result is always the same for same input but can be very different for different inputs, even if one letter's case is changed)
6) Pass the final hash with plaintext username to another function which then executes a connection
7) Regenerate the links in similar manner to Doug Steele's DNS-less connection code posted in his website.

Did that help?
 
ok steps 1-5 for the non technicals are an attempt to encript user name an password using both conventional and inventional methodes to give exploiters hard time to decode them.
6-needs elaboration as to "how ?"
7-is vague!
 
6- Take a look in VBA help file at OpenDatabase method.
7- Google "Doug Steele DNS-less connection"; the code is posted there. The underlying principle is basically same, though I've heavily modified it for my needs and for MySQL backend rather than SQL Server backend.
 
Oh, wow. That is too bad.

Thankfully, someone posted the full code in this thread. It seems to be altered just for the driver for MySQL, rather than SQL Server, but is quite identical, if my memory serves, unlike my butchered copy.
 
Hush, don't make a dumb fool of me, will ya, George?!? ;)

(I thought it was at the now-defunct address, but you can infer from my pointing to Google that I've failed to memorize his address.) :D

Nonetheless, I'm glad Mr. Steele didn't do a Fermat's last theorem on us!
 
Since this is about security holes, I guess this is a good place to post this.

Note: This applies only if you are paranoid. *raises hand*

Prompted by another user's concerns about security; specifically the fact that there are password recovery tools even for ULS/.mdw files. The fact that it is available for download & trial almost guarantees that there is a cracked copy floating around on the fringe of net (and most likely infected to boot).

So, if you are concerned about malicious users or want to protect your IP or the data (which I hope you've stored in a proper RDBMS), you can take step to protect against this.

One option is to rely exclusively on the RDBMS's security mechanisms, so the front-end is essentially unsecured, but compiled into a MDE to protect your code. (Note: It can be decompiled for a fee; if you really, really want to protect the code, consider EverythingAccess.com's Code Protector). This is relatively simple way to move all security off the local computer, so it's always up to the server to grant permission or deny it and would require that the bogeyman hack in the server or steal administrator's credentials (in which case it's administrator's darned fault for leaving password around on a paper in a unlocked drawer).

In case where we're using an Access backend, similar functionality could be arrived at by having two separate workgroup files. One for owning and developing the database and another for distribution. If you are content to allow users to open it without logging, you can just use the default system.mdw; you merely need to grant permissions to Admin user to open only forms and reports and deny permissions everywhere else (adjust as need for your case). This will guarantee that even in mde that the end user cannot create new tables or queries and must work within the interface. For extra security, have a .mdw customized to each user. The development .mdw of course must have the user's name and PID exactly identical. Giving each users their own .mdw means that if the password is cracked, it's only one user's password and an unprivileged one at that. This gives the additional benefit of protecting the database from being opened in code or by an external tool because this still requires credentials in place.


It's important to note that perfect security is totally impossible. Therefore, I usually say I've succeeded if I've left the only option to the attacker is to employ social engineering (e.g. deceiving the user into giving the password or granting access to the computer) because brute force would take too long, dictionary attack, even with rainbow tables, isn't faster than brute force. Also, there's a decreasing return for every nuts & bolts you tighten. If all your users are merely bright enough to download a password recovery tool, then that's good enough. If it happened that my user was proficient enough to read and trace the heap dump stack or manage to decompile the binaries, the likelihood of him wasting his good time on my plithy database which only contains health information covered by HIPAA is low compared to hacking the DoD's mainframe and playing a Global Thermonuclear War game. ;)


Anyway, HTH. :)
 
In case where we're using an Access backend, similar functionality could be arrived at by having two separate workgroup files. One for owning and developing the database and another for distribution. If you are content to allow users to open it without logging, you can just use the default system.mdw; you merely need to grant permissions to Admin user to open only forms and reports and deny permissions everywhere else (adjust as need for your case). This will guarantee that even in mde that the end user cannot create new tables or queries and must work within the interface. For extra security, have a .mdw customized to each user. The development .mdw of course must have the user's name and PID exactly identical. Giving each users their own .mdw means that if the password is cracked, it's only one user's password and an unprivileged one at that. This gives the additional benefit of protecting the database from being opened in code or by an external tool because this still requires credentials in place.

I think that having a separate mdw file doesn't help, because you still have to give full permissions to your users otherwise the program just doesn't work. How can you write a program that doesn't make tables or queries? I have come to peace with the fact that Access is just not very secure, and it really is not an appropriate program to use for commercial distribution (but it would be really nice if it was).
 
Well, as Access Security FAQ explains, the security information are kept in two separate places. .MDW file essentially stores the credentials and is what is used for autheniciation, while the permissions are stored in database object themselves. The aim of process is to give .MDW that only has users' credentials and not the administrator's so even if they managed to crack the password, they still are not privileged to do anything but use it as any other user. Two .MDWs should work just fine provided that the PID and username are identical between two files. (This is how the Admin works for all database, in fact.)

I'm not sure what you mean by "full permissions to your users otherwise the program doesn't just work.", but assure that if you only want to give permissions to forms/reports only, you indeed can do so by using RWOP (Run With Owner's Permission) queries as recordsource and thus deny permissions to open the tables directly. (Not sure if you still can open RWOP query directly).

Regarding commerical distribution, I've never thought Access appropriate for this kind of use, and it's not the security that stops it, IMO.

Did that help?
 

Users who are viewing this thread

Back
Top Bottom