You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently Organizatrions that have a Channel Binding Token Hardening Level domain policy set to "Strict" ("relaxed" is the default) are unable to authenticate to the WinRM service when using NTLM over SSL (note this has always been the case and is not a recent regression). This is because the strict policy requires a "channel binding token" which binds the outer transport channel (TLS in this case) to the inner channel (NTLM) and povides extra protection against "man in the middle" attacks.
Logistically this involves embedding a hash of the X509 cert (usually SHA-256) in the target_info of the type3 message sent to authenticate the client to the server. This post does a good job clearly explaining how to create the token.
I have managed to get a valid token generated using the above technique and hacked the session class here to validate that it works. Here is the hack:
def blob
@blob ||=
begin
b = Blob.new
b.timestamp = timestamp
b.challenge = client_challenge
b.target_info = inject_cbt
b.serialize
end
end
def inject_cbt
cbt = "\x0A\x00\x10\x00\x04\x0E\x56\x28\xEC\x4A\x98\x29\x91\x70\x73\x62\x03\x7B\xB2\x3C".force_encoding(Encoding::ASCII_8BIT) #hard coded valid `MsvAvChannelBindings` using a self signed cert on a test VM
target_info = challenge_message.target_info
target_info.insert(target_info.length-4, cbt)
target_info
end
This resulted in succesfully authenticating over SSL to a VM with a Channel Binding Token Hardening Level set to strict.
I am starting a PR to this gem with a less "hacky" implementation and want to introduce a high level design for discussion:
Add a optional channel_binding_token to Net::NTLM::Client::Session.init_context which would be a ChannelBinding instance (see next item).
Add a Net::Ntlm::ChannelBinding class with a static create method that takes a options hash. There are different kinds of "outer channels" and even different kinds tls based tokens so one can imagine perhaps different subclasses at some point. This initial implementation would just take a X509 cert and be capable of generating a gss_channel_bindings_struct and a MsvAvChannelBindings MD5 byte stream.
Add a TargetInfo class that can be initialized from target info received in the type2 message and have the ability to add additional AV_PAIR structures. The to_s method of this class will dump a string representation that can be fed to a Blob's target_info accessor.
With this implementation, we can add a trivial change to the WinRM gem that would use its the SSL cert to create a ChannelBinding and feed that to the Ntlm::Session and then successfully authenticate to servers with a strict policy.
I don't have good metrics, only anecdotal experience. I don't think this is a widespread issue but I have run into this a couple times and recently with a well known enterprise customer. Its one of those things that is incredibly unobvious and can consume alot of time troubleshooting why someone cannot connect to winrm even though they seem to have everything wired up correctly and can connect successfully with MS based tools like powershell remoting. Its also interesting to look at this issue where people are complaining about Chrome's lack of implementation (they are implementing it now though) and how that is blocking several enterprise shops.
Currently Organizatrions that have a
Channel Binding Token Hardening Level
domain policy set to "Strict" ("relaxed" is the default) are unable to authenticate to the WinRM service when using NTLM over SSL (note this has always been the case and is not a recent regression). This is because thestrict
policy requires a "channel binding token" which binds the outer transport channel (TLS in this case) to the inner channel (NTLM) and povides extra protection against "man in the middle" attacks.For more info on this topic see:
https://msdn.microsoft.com/en-us/library/dd639324.aspx
https://datatracker.ietf.org/doc/rfc5056/?include_text=1
Logistically this involves embedding a hash of the X509 cert (usually SHA-256) in the
target_info
of thetype3
message sent to authenticate the client to the server. This post does a good job clearly explaining how to create the token.I have managed to get a valid token generated using the above technique and hacked the
session
class here to validate that it works. Here is the hack:This resulted in succesfully authenticating over SSL to a VM with a
Channel Binding Token Hardening Level
set tostrict
.I am starting a PR to this gem with a less "hacky" implementation and want to introduce a high level design for discussion:
channel_binding_token
toNet::NTLM::Client::Session.init_context
which would be aChannelBinding
instance (see next item).Net::Ntlm::ChannelBinding
class with a staticcreate
method that takes aoptions
hash. There are different kinds of "outer channels" and even different kindstls
based tokens so one can imagine perhaps different subclasses at some point. This initial implementation would just take aX509
cert and be capable of generating agss_channel_bindings_struct
and aMsvAvChannelBindings
MD5 byte stream.TargetInfo
class that can be initialized from target info received in thetype2
message and have the ability to add additionalAV_PAIR
structures. Theto_s
method of this class will dump a string representation that can be fed to aBlob
'starget_info
accessor.With this implementation, we can add a trivial change to the WinRM gem that would use its the SSL cert to create a
ChannelBinding
and feed that to theNtlm::Session
and then successfully authenticate to servers with a strict policy.cc @sneal
The text was updated successfully, but these errors were encountered: