What part of my post indicated that my hypothetical application makes
system-wide changes? There are a variety of privileges that can
legitimately be used by a user-based application without the need for full
administrative privileges and those privileges do not necessarily need to be
used to make system changes.
The point is not whether the program does system-wide changes by itself, but
rather whether it has the ability to do so. Detecting the intent of an
application is extremely hard since a lot of constituent actions can be used
to do something really bad. Each action, on its own, however, may not be
really bad. Therefore, the isolation decisions are based on privileges held,
as opposed to privileges actually used. I think we fundamentally agree on
that principle.
Bullcrap. The TCB is NOT just the kernel. "[the] SeTcbPrivilege, which
SYSTEM has by default.
You're missing my point. You made the argument that "setting a program up to
run as a service means that the particular program must be designed and
tested to run as a part of the TCB." Not all services are part of the TCB.
Only those that run in a process that has SeTcbPrivilege are. There are 150
services available in Windows Vista Ultimate. Of those, only 74 (if I counted
correctly) run with SeTcbPrivilege in their process tokens.
This is the most powerful privilege in Windows, as it
indicates that you are effectively part of the operating system itself, or
the "trusted computing base," which is where the acronym TCB comes from."
I'm well aware of where the acronym came from. It was from the Orange Book
(TCSEC). That's not really the point though. There are many, many privileges
in Windows that can be just as powerful. If you take over a process that has
only SeTcbPrivilege, and nothing else, you would have to go through a bunch
of hoops to do something interesting. Not that it is impossible, but other
privileges in combination makes the job much easier. There actually are not
that many (public) APIs that you can use just because you have
SeTcbPrivilege. A proccess with SeTcbPrivilege, for example, gives you the
right to open handles to other processes' tokens, but if you can't do
anything with that token, say, assign it to a different process, you are
relatively sandboxed in that approach to hacking the system. Combine
SeTcbPrivilege with SeAssignPrimaryTokenPrivilege and you have a combination
that is lethal, however. By the same token, SeRestorePrivilege, just by
itself, let's you replace any file on the computer. If you have no other
privilege on the system at all, SeRestorePrivilege can be used to completely
compromise the system. The same is true of SeDebugPrivilege.
In the context of our discussion, unless you have configured your service to
run as a different user, it will run in the system context in the system
login session thus making it a part of the TCB since LocalSystem has the
SeTcbPrivilege right.
Sort of, I guess. You have to configure a user context for the service. You
can't avoid that, but I guess if you configure it to run as LocalSystem, with
no other changes, then yes. Of course, on Vista, as you say, you can ask for
a restricted token, and in that case you may not have SeTcbPrivilege right
anyway. Many services do that. For example,
Granted, on Vista one could use the RequiredPrivileges registry entry to
limit the attack surface that a poorly written service will provide to
malicious code, but the fact remains that adding code to the TCB unless
absolutely required is not advisable.
The easier option may be to call ChangeServiceConfig2 at level
SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO. It lets you ask for the privileges
you want, and if you remove most of them you have a fairly well sandboxed
service. For instance, the Microsoft .NET Framework NGEN v2.0.50727_X86
service has only these privileges:
SeChangeNotifyPrivilege
SeCreateGlobalPrivilege
SeIncreaseBasePriorityPrivilege
SeIncreaseQuotaPrivilege
Yet, it runs as LocalSystem.
I don't argue at all that adding code to the TCB is inadvisable though.
No, it doesn't. It gives you the ability to impersonate the security
context of a user using one of the impersonation functions. With the
exception of the ImpersonateAnonymousToken function, this requires that you
have access to a kernel object with different security credentials.
I don't think we're in disagreement there. You create some trojan COM
object, for example; fool someone into connecting to it, and then you can
impersonate them. There are many ways to do the same thing, but they all
require (a) your ability to create or take over some object, and (b) somehow
getting someone to use it.
So your contention is that an application is safe because it can adjust it's
privileges? What is then to stop malicious code from then readjusting the
token privileges *back* to the highest available privileges? Nothing.
I'd have to play with it, but I don't see how you would do that. You'd have
to create a new token, because AdjustTokenPrivileges does not have the
ability to add privileges back to a token if it was previously used to remove
them. The test would be:
1. Create a new token for the user you want
2. Call AdjustTokenPrivileges to remove everything you don't have
3. Call CreateProcessAsUser to create a process with the adjusted token
4. From the new process, try to add privileges back
There is probably some privilege (obviously) that lets you perform step 4,
but I don't think you can do it unless you have
SeAssignPrimaryTokenPrivilege. Again, it is a matter of what all you remove.
If you are extremely strict, you can almost certainly sandbox effectively,
and if you don't, we are back to the fact that a number of privileges can be
used to defeat the sandbox. I'd have to test it though. I wrote a tool that
can be used to strip all the privs (the elevate tool at
http://msinfluentials.com/blogs/jesper/archive/2007/07/11/tools-from-the-vista-security-book.aspx).
It would perform steps 1-3. I don't have time right now to try 4, but it
would be interesting to know what it would take. Note that the Service
Control Manager also takes steps 1-3, so if you specify very strict removal
of privileges in a service it will be a lot harder to break out of the
sandbox.
I'm asking why the manifest file doesn't have a section in the security
element that allows me to enumerate the privileges that my application
needs. When the process is elevated (if required) then my token should be
filtered to only have the requested privileges.
That's a great idea. If you are on the Windows Preview beta (not a beta,
just a submission forum) vote for it. I sent it in as a suggestion.
I wasn't aware of that particular book. Are you the co-author????
Yes.