Token delegation using LOGON32_LOGON_NETWORK_CLEARTEXT

2k views Asked by At

How safe is it to use LOGON32_LOGON_NETWORK_CLEARTEXT?

We have the following scenario:

Web server A is using Win32 LogonUser. Then it needs to invoke an asmx method on server B.

If the used logon type is LOGON32_LOGON_INTERACTIVE it works well. However the customer rejects this because it requires interactive access.

If we use LOGON32_LOGON_NETWORK this does not allow token delegation to the remote server and we get 401 (as expected, according to the MSDN).

Attempting to use DuplicateToken to "upgrade" the token to interactive fails. This attempt was based on this article where it states:

"When you request an interactive logon, LogonUser returns a primary token that allows you to create processes while impersonating. When you request a network logon, LogonUser returns an impersonation token that can be used to access local resources, but not to create processes. If required, you can convert an impersonation token to a primary token by calling the Win32 DuplicateToken function."

But it seems that if we use LOGON32_LOGON_NETWORK_CLEARTEXT as stated in this old thread, delegation works. But how safe is it for usage? According to MSDN:

"This logon type preserves the name and password in the authentication package, which allows the server to make connections to other network servers while impersonating the client. A server can accept plaintext credentials from a client, call LogonUser, verify that the user can access the system across the network, and still communicate with other servers."

Are the credentials used in this format visible in anyway to sniffers (we're using Windows Integrated security, sometimes with SSL but not always).

Please advise.

1

There are 1 answers

2
bmm6o On

I had the same question, and though I haven't found a definitive answer I've done some investigating and reading between the lines, and this is my conclusion (corrections welcome):

The ideal/safest use case is if your code looks like this pseudocode:

success = LogonUser(username, domain, password,
    LOGON32_LOGON_NETWORK_CLEARTEXT, provider, out token)
if (success) {
    StartImpersonation(token)
    remoteConnection = AuthenticateToRemoteServer()
    StopImpersonation()
    CloseHandle(token)

    // continue to use remoteConnection
}

The plaintext credentials associated with the LogonUser session will be destroyed when you close its handle (I haven't found a reference for this, but it doesn't make sense to me that they wouldn't). So for the lifetime of the token there was a copy of the user's credentials and it was used to authenticate to the remote server. But your application already had the credentials in memory in plaintext (in the variables username, domain and password) so this doesn't really present a additional security risk.

Any authentication with a remote server that uses Windows authentication will be using NTML or Kerberos and neither protocol sends the credentials on the wire, so that's not a concern. I can't say for sure what would happen if the remote server asked for basic authentication, but I think it's more likely that it would fail than your credentials would be sent over.

If you need to keep the token around longer, the documentation does state that the credentials are stored in plaintext (somewhere). I took a dump of a test process and wasn't able to find them in the dump file, so I don't know if that means that they are stored in kernel memory or what. I would be a little worried if I had to keep this token around for a long time.