Token Kidnapping in Windows
Microsoft has just released MS09-012 to address this issue in it’s entirety. Get further details here.
You have probably heard about the Token Kidnapping vulnerability in Windows and read Microsoft's security advisory on it and are wondering why there isn’t an update for this yet. Although this is not an IIS issue but a Windows issue, the fact that IIS can be used as a vector for this vulnerability increases my concern for seeing an update for this soon. But obviously that does not assuage concerns of our customers and so in the interest of transparency I thought it would be prudent to explain the issue, what the update would do and why it is taking time. Just to make it absolutely clear … Microsoft is going to release an update to address this issue, and the workarounds mentioned in the advisory are still applicable and help mitigate the issue. In the case of IIS, some of these “workarounds” are actually recommended best practices.
Before there were service accounts, there was LocalSystem and it was too highly privileged to host un-trusted code, no matter how much we try to sandbox it. So we implemented service accounts like NetworkService that did not have all the privileges possessed by the LocalSystem account and a lot of products and features embraced the idea of running under this identity for several reasons. For the sake of simplicity let’s split the users of this feature into 2 buckets, both being valid uses.
1. Isolating un-trusted code.
Some products like Internet Information Services (IIS) need the ability to host un-trusted user code running inside their worker processes. In the case of a buffer overrun or any other error, we would like to ensure that the user code does not have high enough privileges to affect the entire system and are sufficiently sand-boxed by the worker process identity.
2. Following least privilege practices.
Other products followed the practices of least privilege to harden the security of their features.
These service accounts need a client impersonation privilege (SeImpersonatePrivilege), so that the process or service can run as a specific authenticated user if need be. The act of “impersonation” leaves a “token” that identifies this authenticated user in the process or service. The two valid uses above have different characteristics though. The first would not expect privileged users like Administrators to be impersonated while the second might be prone to it. This leaves us with a scenario where 2 different processes / services running as the same service account identity would have very different sort of tokens in them. In some cases these tokens may be long-lived or it would be easy to perform an action that would result in a privileged token being acquired by a process or service. Also, these different processes and services are not wholly isolated from each other in every case. The combination of these two factors gives rise to an issue where an un-trusted code being hosted in a process running with a service account identity (say in group 1 above) would now be able to access a privileged token from a process running with the same service account identity (likely in group 2 above) leading to an elevation of privilege.
You can read more about this in the finder’s document on http://www.argeniss.com/research/TokenKidnapping.pdf
There are different levels at which changes would be needed to address this issue.
1. Service isolation.
The first issue to address is to make sure that two services running with the same identity not be able to access each other’s tokens freely. This concern has been mostly addressed with service hardening done in Windows Vista and above. There are some minor changes that would need to be done to strengthen service hardening to close some gaps identified during our investigation of this issue.
2. Processes running as service accounts.
There are cases where the service hardening work done above does not apply. In these cases changes need to be made to prevent processes from holding on to privileged tokens or from being induced to acquire one by unprivileged means.
Both the changes above come with their own set of challenges.
1. Service isolation.
The changes required for to address concerns in this space need to occur at a very low level in the OS. As a result, it has a high impact on the system and requires rigorous testing on the part of multiple teams within Microsoft.2. Processes running as service accounts.
The changes required here are even more complex, mostly because of design decisions and dependencies by various other components on the component in question. Software engineers read “design” and “dependencies” in the statement above and wince … and rightfully so. Even if the issue does not pervade a lot of components (as is the case here) and affects just one component that a lot of other components depend on, or if the issue is ingrained in the design of the component, the changes required are difficult to engineer. Not impossible, just difficult. And the impact of any of these changes would be pervasive and would require coordination between several different teams at Microsoft to address. These teams are going through great lengths at identifying these components, making sure the fixes are adequate and not just a band-aid and testing every component to make sure that no undesired behavior is introduced in the process.
Microsoft is committed to providing a comprehensive and high quality update with minimal user impact for this issue. The nature of this issue requires thoroughness on our part for issuing an update. The workarounds provided in the advisory are still applicable in mitigating the issue.