I am trying to run program.exe in a very restricted mode (Windows). This means program.exe should have access to five .txt files, and no other permissions like staring new process, shutdown, edit other files, etc.
I've spent a month trying to achieve it, but there is still no results. I tried to run it as constrained user: runas /trustlevel:10000 "program.exe"
, and then added permissions:icacls program.exe /grant *S-1-5-12:F
But it seems such user still have some rights, for instace he can run notepad.exe and explorer.exe, and this is unacceptable in my case. Also I played with CreateProcessAsUser() winapi function, but it lead to same result.
So my question is: how can I run program.exe with this limitations, maybe I should create new user with restrictions? How?
P.S: Basically I want to get primitive sandbox.
Thank you.
So thanks to your help, I've written this code:
hToken = NULL;
OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);
SID_AND_ATTRIBUTES sidsToDisable;
ConvertStringSidToSid(L"S-1-1-0", &sidsToDisable.Sid);
sidsToDisable.Attributes = NULL;
SID_AND_ATTRIBUTES sidsToRestrict;
ConvertStringSidToSid(L"S-1-1-0", &sidsToRestrict.Sid);
sidsToRestrict.Attributes = NULL;
CreateRestrictedToken(hToken,NULL,1,&sidsToDisable,0,NULL,1,&sidsToRestrict,&hToken);
PROCESS_INFORMATION pi;
if (CreateProcessAsUser(hToken, wszPath, NULL, NULL, NULL,TRUE, CREATE_NEW_CONSOLE /*| CREATE_SUSPENDED*/, NULL, NULL, &si, &pi))
{
//...
//ok process created
}
But it does not work. 0xc0000022 errors occur all the time, or 0xc00000142 when using admin SID. When I create hToken by SaferComputeTokenFromLevel() it works fine. What am I doing wrong?
Sandboxing that thorough is believed to be impossible. See also the linked PDF.
If this needs to be robust, your only option is a fully-fledged VM. Of course if the sandboxed application has to be a Windows executable, that has licensing implications.
If it doesn't need to be all that robust, it should be possible in principle to put something together that might be sufficient. You would need administrative privilege to do so, but a system service could launch the sandboxed application on a non-privileged user's behalf.
The hard part, I think, will be creating a suitable token. I think that ideally, you want a token that has a unique logon session SID but nothing else.
Using the LSA API is probably the best approach, since it allows you to synthesize an arbitrary token, but it is complicated and not terribly well documented.
You could experiment with duplicating and/or modifying the token you get from ImpersonateAnonymousToken, but I'm not sure whether it would be possible to include a unique logon session SID.
Combining LogonUser (against a user account created for the purpose) with CreateRestrictedToken should be both straightforward and adequate. This is probably the place to start.
You should also make sure the integrity level for the token is suitably low. I would assume that either S-1-16-0
or S-1-16-1
is the lowest level possible.
You'll want to create a new window station for the sandboxed process. That's why we need the logon session SID, so we can grant the token permissions to the window station. Otherwise, the process won't be able to run.
If the process generates a GUI, you'll have to remote it somehow. Ideally you would modify the process itself so that the GUI part is separate and does not need to be sandboxed. Failing that, it should be possible in principle to copy the bitmap from the sandboxed desktop, and forward mouse clicks and keystrokes back to it. I'm not sure how reliable this would be.
To prevent the sandboxed process from launching child processes, put it in a job object. You can set the active process limit for the job to 1 to prevent child processes from being created. (This isn't really necessary IMO since the child processes would have all the same restrictions as the parent, but it can be done.)
Your last comment suggests that perhaps you don't need even this level of robustness. If so, you could save yourself the trouble of remoting the GUI by running the process in the user's own desktop and window station.
You would still need to generate a suitable token, but you might not need to use a separate user account and logon session; if so, CreateRestrictedToken should be sufficient. You can use the interactive user's own token as the source.
You will still need to lower the token's integrity level to protect against shatter attacks.
You can still use a job object to prevent child processes being launched.
JOBOBJECT_BASIC_UI_RESTRICTIONS can be used to provide some level of protection against attacks on the user interface.
In this scenario, you might not even need admin access. I'm not sure offhand.
This approach is not robust enough for running potentially malicious executables, but if the sandbox is only intended as a backup precaution it may be adequate.
User contributions licensed under CC BY-SA 3.0