Create file that can be opened only by a Windows Service - c++

Is it possible to select such a security descriptor using a DACL string such that the file can only be opened by a Windows Service, but not by an ordinary process, even if the process is run by the local Administrator account?
To clarify, I just need to make it reasonably hard for a non-technical user to open it in NotePad and tamper with it. It doesn't need to work against a programmer willing to dedicate a month of his life to reverse engineering and cracking it.
I prefer to achieve this using DACL instead of locking the file because then my windows service doesn't need to run all the time for the file to be protected.

Local administrator account = God (at least on the box). There's no way to do this.
You can define a special privileged account for your service to run under, and make the ACLs on the protected file only allow access by that user (and all machine admins). You can disallow interactive login using that service account.
If your primary concern is tampering by interactive users, you may need a policy whereby the local user does not run by default with local admin rights. Unfortunately you cannot allow 'partial' local admin rights - it's all or nothing.

I don't know enough about DACLs to say whether or how you can accomplish what you want with those. I can think of a couple things you can do to make it harder for someone to tamper with the file, in addition to restricting it to the local administrator account:
Have your service start automatically, and open the file immediately with no sharing options. As long as your service has it open, another process won't be able to open it.
Compute a hash of the file contents plus a salt hardcoded into your service and store it somewhere else, e.g., in another file, in the registry, or even online. Next time you open the file, verify the hash, which will tell you if someone tampered with the file since the last time you opened it.
These are not foolproof by any stretch, but it sounds like your goal is simply to make it harder. There's no foolproof method to stop a user with administrator privileges.

Related

Windows : Create directory with permission to my process only (C++)

Create a folder with access granted only to the executing process. The process will delete the data when job is done.
The purpose is to avoid having any other process attempt to manipulate the data in the folder, while the owner process is running.
I already tried giving ACLs and it did not solve the purpose. Basically the current user gets the permission and so if any other process is running under the same user then the other process gets the permissions as well.
// I used the second parameter here to add ACLs
CreateDirectory(lpPath, &sa);
You are right, ACL are used to manage user permissions, not process permissions. It is easy in Windows to limit a file to a running process by opening it with CreateFile with a dwShareMode of 0.
But according to the MSDN page on CreateFile, it is possible to get a directory handle with that function if the dwFlagsAndAttributes parameter contains FILE_FLAG_BACKUP_SEMANTICS. Creation is not possible that way, but maybe keeping the directory open could prevent other processes to access it. Beware I have never tested that.
Anyway, I cannot imagine a real use case where it would be required. If you want to do that for security reasons, the correct way is to use a dedicated user. In addition it allows an administrator to control what happens in the directory. And if it is for synchronization reasons, you should rely on standard synchronization primitives

How To Encrypt A Directory With Application-Specific Keys?

I'm working on a C++ application that stores (and frequently accesses) its data across many files within a single directory via numerous classes, database libraries, etc. I would like to start encrypting all this data on disk using a key managed by the application.
On windows, programmatically enabling EFS for the directory would be perfect if the application could set the encryption key directly rather than using one based on the logged-in user's password. This does not seem possible.
Because there are numerous places in the code that read/write files, some with full random-access, a library that exports something akin to the OS file operation API would be easiest in the absence of direct OS support.
Windows is the biggest user base but something usable on Mac and Linux would be a big plus.
Any suggestions?
Configure the application to run as a service account, intended only for it. Then, configure EFS. Since the application's service account will own the files, its user-specific keys should be the only valid EFS keys for it, so only the application (which will be the only thing running under this new service account) will be able to access the files.
Have you considered storing the files in an encrypted archive, such as a zip file? Not knowing what language you're working in makes it difficult to give a more specific answer.
I am not an expert but I have a few suggestions,
('user' is considered Male here)
In Windows, when an user is logged in, he will have all the rights to manipulate a file or folder which belongs to him.
But, if he tries to manipulate files or folders which belong to other users, he is not allowed to do so. So, he can't manipulate other user's files.
If the user is administrator, he will have all the rights to manipulate the file.
In your case, I believe the user is not administrator.
So, I suggest to you to:
Create a user for this application, say Bob(Bob is not the user who is going to use this application).
Then you create a folder to store your files and give all permission only to Bob(and the admin).
For all others, there no permission to do anything to the folder.
Your application must be installed by administrator.
When you start, Your application asks Bob's password from current user.
If the password is correct,
Using your application allow full access folder permission to the current user. Then application can work as you wish.
If the user quits the application,
Remove all permission for current user so that after quitting this application others can't access that content.
But Administrator can still access this content.
This is similar like Linux user management.
When you are getting a shell you can change user using su username when finishes the work and he quits the shell then others can't use those files. But root user can do anything in Linux.
But there is one problem.
Administrator can get full content and access since he can modify the permissions.
To disallow this, save the files by zipping using any technique and by using a password. That password is only known by the user who uses it. Before saving a file to the folder, zip it using a password. Before using the file, unzip it using the password.
If the zipping password is same as user password, then there is a problem.
The administrator can reset user password to something and open his account.
To prevent this you can use the following technique:
Use zip password as reverse of user password, so that if his password is 1234 the zipping password is 4321, or use hash value of user password as zipping password.
If the zip password is hash value like MD5 hash or SHA-1 then brute force on zip file won't work due to the password length.
I don't know if this is a working solution or not or if this can be implemented or not.
But you can take some ideas out of this, if you think there is some good ideas in this.
Unless I've missed something in your question, TrueCrypt seems to be an ideal solution for you.
It will allow to:
Utilize existing OS file API (as the mounted volume will behave just like regular volume)
Programmatically manage access key (password)
Limit access to the mounted volume (by OS mechanics)
Utilize same principles on all the platforms (Windows, Mac, Linux)
Or, if you want, you can encrypt/decrypt individual files with it.
There's a number of examples on how to use it around.

Can AdjustTokenPrivileges elevate the privilege as Administrator?

Programs under windows need administrator privilege must get user's permission when they start. And they can also run with administrator privilege by right click the EXE and select "Run as Administrator". But, before the EXE start, a message box will show up. It's really disgusting.
Now I want my application to run as the Administrator, and I don't want the popup message box when user click the EXE file.
Now I wonder whether the AdjustTokenPrivileges function can help me achieve this.
Any one can help me?
You're getting confused between rights and privileges. At least from the viewpoint of the Windows API, the two are entirely different (though they're otherwise treated as synonymous a great deal of the time, at least when dealing with "what you can do on Windows").
What you're really looking for is the ability to elevate rights. Short of some defect in the security model of the system, you shouldn't be able to do this. To get administrative rights, the intent is that the code should have to run under an administrative account -- either by the user initially logging in as an administrator, or else by them entering the credentials at run time as you've seen.
Privileges (which are what AdjustTokenPrivileges actually manipulates) are things you have the right to do, but still aren't allowed to do without specifically enabling that privilege. For example, let's assume you start out logged in as an administrator. That gives you the right to adjust the system clock -- but adjusting the system clock is something normal programs almost never have a reason to do, so they added an extra step, before you can do it -- you need to enable the SE_SYSTEMTIME privilege before you can make use of that right.
If you're logged in under an account that doesn't have the right to change the system time, you simply can't do it. If you're logged into an account that can change it, you have to enable the privilege first before you can do it.
Bottom line: AdjustTokenPrivileges won't accomplish what you're trying to do.
Actually there is a way, which allows you to change security credentials for the thread by calling LogonUser API function. It returns handle to a token which could be used in ImpersonateLoggedOnUser and CreateProcessAsUser calls. This technique is called impersonalization.
Howewer, I think you are trying to achieve a different thing - to run a process with elevated administrative rights without UAC user notification. You could either disable UAC completely in msconfig utility, which is a pretty bad solution, or leave your program as it is, because to be quite frank, user has a right to know, when your program is running with superuser privileges, and disabling this notifications should be his decision.

Disable registry access for specific process (WinAPI)

I have a problem I can't seem to find the answer to, though I am sure it is out there. Is there a way I can disable registry and file access for a newly-created process? I am using Job objects ( http://msdn.microsoft.com/en-us/library/windows/desktop/ms682409(v=vs.85).aspx ) and it says to set the permissions for each new job process, and in a few books I have read that things such as registry and file access can be controlled.
While looking for my answer I saw that I needed to add LUIDs for things such as SE_BACKUP_NAME and such (or whatever it is called) but none of those privilege constants seem to reflect the kind of control I want.. So my exact question is: How would I go about disabling registry/file write access for a newly created process in a Job?
I am trying to create a sandboxed-application, btw. This is so I can prevent it from making any changes to the registry or writing any files while it runs.
Any help would be appreciated!
Windows accesses many resources during process startup, so if you successfully disabled access to the filesystem and registry the process wouldn't start.
Ideally, you'd want access to be restricted after process initialization was complete, but Windows doesn't have a mechanism to do this for arbitrary processes. The sandbox in the Chrome browser relies on the cooperation of the sandboxed process.
The documentation for the Chrome sandbox has a nice overview of the various security mechanisms available in Windows and explains how they are used in Chrome. It's a nice solution if you are trying to sandbox your own code.
I don't think you can disable access outright as many susbsystems rely on it (COM, the shell, some DLL initialisation, debugging, etc) An alternative would be to allow access, but to a limited sandbox which can be done with the integrity system. Setting it to low integrity will block most write access and is used by protected mode IE.

What are the access restrictions on accessing a DSN

We are running part of our app as a windows service and it needs to b able to access DSNs in order to import through ODBC. However there seem to be a lot of restrictions found through trial and error on what DSNs it can access. For example it seems that it cannot
1. access a system DSN unless the account that is running the service has admin privileges. (I get an Access Denied error, when trying to connect)
2. access a user DSN that was created by a different user (this one is understandable).
3. access a file DSN across the network
I've read that the purpose of a file DSN is to allow other computers to use it to connect, however i can't seem to make that work.
So does any know, or know where i can find out what all the rules and restrictions on accessing a DSN are when using a windows service.
thanks
This is somewhere between your #1 and #2: sometimes correct file permissions are also necessary. I once had troubles on a Vista machine connecting to a DB2 DSN because, for whatever reason (maybe to write out temp files; although I don't know why it would do such a thing in this location instead of a user-specific one), the driver needed write access to the directory where IBM had installed the client binaries and libs, which had been done by an Administrator and was in the root of the C drive.
I think you've already discovered the three main rules yourself. :-)
Except that you probably don't need admin privileges for your service account. IANANA (I am not a network administrator), but your service account probably just needs read access to one of the ODBC files or directories.
You cannot connect to mapped drives with a service. A mapped drive has to interact with memory called the desktop heap which tracks the icons on the desktop. Services do not have access to that memory. If you have to use a dsn create a systemdsn. better would be to use a connection string and store that in the app.config and use the encryption api to encrypt the user name and password.