|Visual C# Tutorials|
|.NET Framework Tutorials|
|© 2005 Pearson Education, Inc.|
|This tutorial—Understanding Impersonation—is from The .NET Developer's Guide to Windows Security, by Keith Brown. Copyright © 2005 Pearson Education, Inc.. All rights reserved. This article is reproduced by permission. This tutorial has been edited especially for C# Online.NET. Read the book review!|
Spiking in eXtreme .NET
Impersonation is one of the most useful mechanisms in Windows security. It's also fragile and easy to misuse. Careful use of impersonation can lead to a secure, easy-to-administer application. Misuse can open gaping security holes.
After an application authenticates a user, the application can take on that user's identity through impersonation. Impersonation happens on a thread-by-thread basis to allow for concurrency, which is important for multithreaded servers as each thread might be servicing a different client. In Figure 31.1, the server process is configured to run as Bob. It contains five threads, two of which are impersonating in order to do work on behalf of authenticated clients.
In this scenario, if one of the three normal threads tries to open a file (or any other secure kernel object), the operating system makes its access-checking and auditing decisions by looking at the process token. If Bob has the requisite access, the call will succeed and any audits will show that Bob opened the file. On the other hand, if the thread impersonating Alice tries to open the same file, the operating system makes its access-check decision based on Alice's token, not Bob's, so Alice, not Bob needs to be granted access to the file in this case. As for auditing, the operating system cares about both identities and will record that Bob was impersonating Alice when the file was opened. Of course, auditing must be enabled for any audits to be generated at all (Item 10)!
It may seem surprising that Bob can impersonate his client and actually become more privileged than before. This (and the reverse) is true. Bob might have very little privilege and have access to very few resources on his own, but think about the benefits of this model. If the server process is somehow hijacked by a bad guy, perhaps via a buffer overflow (Item 1), the bad guy won't immediately obtain access to lots of valuable resources. Instead, he'll immediately be able to use only the few piddly resources that Bob can access. Either he'll have to exploit another hole in the system to elevate privileges or he'll have to wait around until a client connects and use the client's credentials to access those resources (via impersonation!). And unless the client is highly privileged, the bad guy won't immediately have access to all the resources but rather only to the ones that that client can access. This can slow down an attack, giving your detection countermeasures (Item 2) time to kick in and allowing you to react and cut off the attack.
Imagine the opposite scenario, where the server runs as SYSTEM and impersonates incoming clients. If the server process is hijacked, it's pretty much over as far as any local resources go. And you should be aware that impersonating a low-privileged account, even the null session (Item 35), won't stop an attacker from simply removing the impersonation token by calling the Win32 function RevertToSelf before doing his evil deeds. This call requires no special privileges and no arguments. It simply removes the impersonation token from the thread, reverting the thread back to the process's identity.
You see, in the first scenario there's a trust boundary between the server process and the resources it's accessing. The resources won't accept Bob's credentials but rather want proof that an authorized client has connected. There's also a trust boundary between the server process and the operating system. There's none in the second scenario! These trust boundaries become even more important when impersonation turns into delegation (Item 62).
None of this is perfect. Even when Bob is untrusted, he can still do bad things. He can collect client tokens (Item 16), which never time out and so effectively elevate the overall privilege level of his process over time. When Alice connects and asks to read resource A, Bob can instead choose to misuse her credentials and write to resource B. But don't let that dissuade you from running your servers with least privilege (Item 4). Security is a balancing act, and least privilege usually gives the defender an advantage.