2

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?

Soup71
  • 131
  • 8
  • Possible duplicate of [Start process as limited user from elevated script](http://stackoverflow.com/questions/15473015/start-process-as-limited-user-from-elevated-script) – Marged Oct 23 '15 at 19:11
  • No, it is not duplicate.How PsExec can help me? – Soup71 Oct 23 '15 at 20:20
  • Your requirements, particularly the desire to prohibit launching child processes, don't really constitute a "primitive" sandbox - that would require quite a sophisticated sandbox. – Harry Johnston Oct 23 '15 at 21:28
  • I thik it is possible to create such 'sandbox' with standart Windows API, and I'm almost sure that it is possible in Linux, and much easier... – Soup71 Oct 23 '15 at 21:38

1 Answers1

1

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.

Community
  • 1
  • 1
Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
  • Oh, great explanation! Thank you so much! But unfortunately I need such 'sandbox' to run potentially malicious code. I want to use it in programming contest system, so users can submit any code including restricted functions wich should lead to "Security violation error". I saw some systems in Windows, but not open source, so It is possible, but I don't know how. – Soup71 Oct 23 '15 at 22:33
  • Maybe they use some different approach? – Soup71 Oct 23 '15 at 22:34
  • More likely they just don't work as reliably as they would like you to think they do. But unless you have specific reason to think your competitors are likely to attack the system, you don't need a particularly robust solution, just enough to make it a little bit difficult for them to do so, which my latter suggestions should do. Make them submit source code, make sure they know that you will be recording every submission on a separate machine for later inspection, make sure you run the whole thing in a non-admin account, and when you're done, nuke and reinstall to be on the safe side. – Harry Johnston Oct 23 '15 at 22:40
  • I found it quite interesting [link](https://www.chromium.org/developers/design-documents/sandbox#TOC-The-Job-object) .Don't you know what is the difference between SidsToDisable and SidsToRestrict from CreateRestrictedToken()? – Soup71 Oct 24 '15 at 21:57
  • SidsToDisable does the straightforward thing - you specify SIDs that in the access token, and it disables them (sets them to deny-only). SidsToRestrict is more complicated, but if it only contains SIDs that are in the access token, the effect is to disable everything *except* those SIDs. But it can also contains SIDs that are *not* in the access token, and then access is only granted if (1) it would be granted based on the enabled SIDs in the access token **and** (2) it would be granted to an access token that contained just the restricted SIDs. – Harry Johnston Oct 24 '15 at 23:47
  • So for the token described in the Chromium sandbox link, in order to get access the ACL would have to grant it to *both* the logon SID *and* to S-1-0-0. (And also not deny it to any of the disabled SIDs, aka deny-only groups.) – Harry Johnston Oct 24 '15 at 23:49
  • Thank you again, but it seems I still need help =) – Soup71 Oct 27 '15 at 20:50
  • If the process is to have a console or present a GUI, it needs access to the window station and desktop. So you need to leave the user's logon SID enabled, and include it in the restricted SIDs list. – Harry Johnston Oct 27 '15 at 23:30
  • I'm sorry, but I can't find information about "user's logon SID". What is it? And how can I get it? I tried S-1-5-21-2679941110-262057722-3185738920-1002 (current user SID, which I found in registry) but it is not right. – Soup71 Oct 28 '15 at 16:23
  • If you create your own desktop you probably need to explicitly specify the ACL. But I recommend getting it working on the default desktop first, and changing it to use a new desktop later once you've got everything else ironed out. We're getting well outside the scope of the original question at this point, but you can email me (or ask a new question) if you're still stuck. – Harry Johnston Oct 28 '15 at 21:43
  • I am very grateful and and appreciate your help! – Soup71 Oct 28 '15 at 22:18