Friday, 27 February 2015

Windows Impersonation and the Double Hop Issue

I've been aware of the Windows Double Hop Issue since a long while ago. I used to think of it as a limitation, but reading lately about it I've found out that it's indeed a security feature, but when trying to understand how it's implemented I've gone through some confusion that I think I've finally defeated.

The idea is that the double hop issue is related to impersonation. Usually, when a Thread in a Server Process is impersonating the user in the client machine, for security reasons, the impersonated thread won't be allowed to access remote resources. This is built upon something that I'd never heard about, the Impersonation Level of the Impersonation Token. Most times the kind of Impersonation Token being used has an Impersonation Impersonation Level, rather than a Delegation one. These types of Impersonation Levels are explained here

  • Delegation: The server process can impersonate the client's security context on remote systems.
  • Impersonation: The server process can impersonate the client's security context on its local system. The server cannot impersonate the client on remote systems.

This looks good when applied to the typical example of a user connection to an Asp.Net application using impersonation and then failing in the second hop when that page tries to connect to a Shared Folder or SqlServer with Windows Authentication.
But my problem with this comes from something that I've done on several times and works like a charm. Let's say I have a Windows Application running on my PC and need to connect to a remote SqlServer DataBase using Windows Authentication. The Windows user running the application has no permissions on that DataBase, so I will impersonate the current thread to an account with access to the DB and open the SqlConnection from this impersonated thread. It works fine, and I do it using the typical code that you can find for example in this example.

Based on the previous explanation on Delegation/Impersonation, the explanation for this to work would be that that this call: WindowsIdentity.Impersonate would be returning an Impersonation token with ImpersonationLevel set to Delegation rather than to Impersonation, but I've checked it (this value: WindowsIdentity.GetCurrent().ImpersonationLevel.ToString()), and the Impersonation Level is Impersonation.

So, how is it that is it that I'm being allowed to access to a remote resource like a remote SqlServer DB or a Shared Folder? This seems to contradict the definition given above. Well, the thing is that such definition was misleading to say the least. You'll find a much better explanation here

.
  • Impersonate: The service can impersonate the client. If the service is on the same computer as the client process, it can access network resources as the client. If the service is on a remote computer, it can impersonate the client only when accessing resources on the service’s computer.
  • Delegate: The service can impersonate the client not only when it accesses resources on the service’s computer but also when it accesses resources on other computers. This level is supported only in Windows 2000 and later versions of the Windows operating system.

Well, putting aside that client/service nomenclature that I think helps quite little here, this makes more sense, but there's still something more to explain. In the end we'll have a thread running with an impersonation token trying to access resources, so how does that "If the service is on the same computer as the client process" really apply to the information contained in that token?

Well, in the same article we'll find a table with the Physical Structure of an Access Token. We can see there that there is a field called Origin.

Origin: Introduced with Windows Server 2003. If the token resulted from a logon using explicit credentials, then the token will contain the ID of the logon session that created it. If the token resulted from network authentication, then this value will be zero.

So in the end my understanding is that the access to a resource from an impersonated thread is granted depending on the Impersonation Level and the Origin.

No comments:

Post a Comment