3

I want to create a Windows mutex by using WinAPI, CreateMutex() and OpenMutex(). But for security concern, I want the mutex be opened by those processes who know the "password" or the hard-code magic code. I don't want the mutex be accessed by every processes.

For example, Create mutex with name "Globel\cd689f00-0462-11e5-b939-0800200c9a66". So only the process who know the mutex name can access this mutex. But this is not a good solution because you can simply use Winobj.exe and you still have some chance to find this mutex. I want this mutex be protected by something like ACL (Access Control Lists). The problem is, I can't find a way to create my own SID for ACL.

Here is what I know and what I want: 1. I know I can make mutex be accessed by many process by naming it likes "Global\MyMutexName". 2. I also try to understand ACL and SID mentioned on MSDN. But I still can't find a way to create my own SID (maybe that doesn't make sense?). 3. I don't want to elevated my processes to Admin.

Calvin Wu
  • 142
  • 10

2 Answers2

5

What you're trying to do isn't natural to the security model that Windows uses. Permissions are always granted based on who is running the executable, not on the executable itself. However, depending on your scenario, there may be suitable options.

If all of the processes involved will be in the context of the same user, then you can use IPC (e.g., named pipes) to identify your "friendly" processes and DuplicateHandle() to pass a handle to an unnamed mutex between processes.

If the processes must be in different user contexts, one option would be to have a system service running in a privileged context to act as a broker. Of course, that requires that the system service be installed with admin privilege, but this is usually acceptable; it only has to be done once.

If the application must be portable (no installation, or able to be installed without admin access) and must cross user boundaries then I think you would have to use IPC to implement your own mutex. Of course, that would be very inefficient.

Keep in mind that in any of these scenarios, a malicious user can still get access to the mutex - the best you can do is make it slightly more difficult. If you use an actual mutex, for example, the attacker could enumerate the handles of one of the processes, identify the mutex, and duplicate the handle. (Or simply inject malicious code into one of the supposedly "friendly" processes to use the handle directly.) Even the IPC could be spied upon and duplicated.

You should seriously consider whether the marginal security benefit is worth the significant increase in complexity. IMO, it isn't likely to be.

(The proper solution, by the way, is for a system service to do all the work that requires access to the mutex; the application that the users run would typically be a thin client that does nothing but provide the GUI.)

Harry Johnston
  • 33,445
  • 6
  • 56
  • 142
  • 1
    Thanks for the answer. It looks like this will need a lot of effort to implement. Therefore, ACL may not be suitable for me. I just found another API call `CreatePrivateNamespace`. I will try it later and update here if I find something. – Calvin Wu Jun 01 '15 at 08:30
  • 1
    I think you'll find that WinObj can still see objects inside a private namespace. But it's worth a try. – Harry Johnston Jun 02 '15 at 00:20
  • Ok! Thanks for the information. I think there is no other better solution so far. Thanks a lot for helping :) – Calvin Wu Jun 03 '15 at 01:39
3

You'd let Windows create a new SID; don't try to create one yourself. With that SID, you can then build an ACL (Access Control List) which grants access to all processes holding that SID, and (implicitly) denies everyone else that right. This ACL can then be applied to the mutex, which protects it.

Now to get access, you'd need to create an impersonation token for that SID. If I understand MSDN, the process is to open your thread token, set the TokenUser via SetTokenInformation, and then apply the modified token via SetThreadToken.

This impersonation token is now used when checking the ACL of the mutex.

MSDN isn't entirely clear on the process of creating a valid user SID; it might be necessary to replace "User SID" with "Group SID" in the process above.

MSalters
  • 159,923
  • 8
  • 140
  • 320
  • Does that means I need to use `SetThreadToken` to impersonate to get the mutex, and I need to use `RevertToSelf` after I release the mutex? – Calvin Wu May 27 '15 at 12:49
  • I don't know if releasing a mutex is a protected operation, so you might be able to `RevertToSelf` directly after acquiring the mutex. – MSalters May 27 '15 at 12:51
  • Ok, I see. But maybe this impersonation operation will have some performance impact? I have anther question. Is the last sentence means I can create a "Group SID" for my own and no one else can get this "Group SID"? – Calvin Wu May 27 '15 at 13:06
  • It had never occurred to me to try to use `SetTokenInformation` to try to directly change the security principals in the token. It might work, I suppose, but if so it will definitely require privileges that even an administrative user doesn't have. (You might also need to duplicate the token and work on the duplicate rather than on a token that is already in use.) Since the OP doesn't want to be elevated, this definitely won't meet his specifications. – Harry Johnston May 27 '15 at 22:24