Validate NT and LM hashes against Active Directory

2019-05-10 18:52发布

问题:

I'm writing web-application authenticating user using NTLM protocol.

I have successfully get password's NT and LM hashes from client. How I can validate them against Active Directory to ensure that password is correct.

I'm using C#, but I think it will be possible for me to call native library as well.

EDIT: I don't see reason for down-votes. NTLM(v2) protocol is outdated so it's really hard to find relative information on how to handle it. Especially from within such a modern language as C#.

But I have found two possible approaches:

  • use of Windows' native SSPI calls (not recommended by Microsoft), but it's possible with proper wrapping. Lucky, there is an example: http://pinvoke.net/default.aspx/secur32/InitializeSecurityContext.html This approach seems to be working. I was able to verify account. But some questions remain, still. Such as transferring information about server's security context between clients' HTTP requests, call to unsafe code and impossibility to perform such operations on other systems.
  • Trying unwrap calls done via System.Net.Security.NegotiateStream. The idea is nice, but no clue how to achieve this.

回答1:

I would strongly recommend you to do some research - reading the that document from the answer to your other question would be a good start - before this question collects more down-votes.

What you're trying to implement - password validation - is security sensitive which means that it's important to properly understand the underlying technology and modern security concepts.

One important design aspect of modern security architectures is being resistant against so-called replay attacks: prevent someone who's eavesdropping on the connection between client and server from recording the authentication challenge and replaying it at a later time.

NTLMv2 / NTLMv2 Session uses this technique - legacy NT/LM (which is highly discouraged these days) does not.

You just can't take the client's response to some challenge that you generated and pass it one to some tool for validation - as this would completely forfeit to purpose of replay attack resistance: how would that tool distinguish between you and Joe Hacker who either recorded the response that you get or generated his own?

The way how this works is that the entity that's validating the password (ie. Active Directory) generates the challenge, not the web server that wants to authenticate its users.

Please, don't implement legacy NT/LM in your web server and call that "security" - it will, in fact, only give you very little protection over sending the password in plain text - it is really trivial and fast to break the so-called "encryption" using today's modern hardware. Read that davenport document, it lists the problems with legacy NT/LM.

If you really want NTLM (the more secure version of it), there are some external helper programs that you can use. For instance look at Samba, Apache and Squid. Squid uses some external tool to handle NTLM which I think is based on Samba's tool.

Using an external tool that's actively maintained such as Samba's also means that you'll get security updates because if you write your own, it's not just about writing the code, it also needs to be maintained, you need to watch out for security problems and fix them.