This case was originally written in Portuguese back in September 2006, it is about a case where customer was really concern about security. However his application was not that concern about this subject. Here is the scenario:
· Customer has an application that uses LDAP to send query to Active Directory;
· The user that uses this application when tries to connect to Active Directory using LDAP it uses his credentials to bind to the directory;
· This application used to work just fine for years.
· Problem: After the company implemented some security policies this particular application stopped to work.
This sound really familiar with almost of the scenarios where security policies are applied without collect exactly the needs of each application. But, it is our job to fix it and point it where is the breach that needs to be addressed in the application.
2. Understanding the Environment
First of all we had to ask, ask and keep asking about the environment to understand what really changed. In this case the good part was that customer was only starting to make the changes that the security policy had determined. One of changes that he did was to implement restrictions on the workstations that the user can logon (that’s an old one, but useful). You can find this window on the user’s properties, as show in the window below:
Figure 1 – Restricting what workstations the user can use to logon.
You might thing: what this has to do with the LDAP issue? Well, at beginning, when customer showed me that I was like: ok, thanks for let me know. But then, he said some magic words: If I add the Domain Controller in this list, the application works fine. That was really interesting; I didn’t know yet how that could be related. I decided to do another test, which was: run the application from the Domain Controller itself using the user’s credential and it works.
3. Dealing with the Misconception
First thing that customer said was: this is a security vulnerability, looks like it just works if the DC is in this list. I could understand his frustration, because he was the Security Administrator and in one side he had the Developers saying that the Microsoft LDAP is not using the standard LDAP implementation and this is the reason why is failing. In the other side the CEO is saying that the Security Team broke the application. It was at least 10 minutes of stress without do anything technical.
To isolate things the first that I said was: let’s test the same query (LDAP) but using our application (LDAP.EXE), which is available via Windows Server 2003 Support Tools. After open the LDAP.EXE, on the screen below I added the user name, the password and checked NTLM:
Figure 2 – LDAP Tool’s authentication window.
Guess what? It works !! It works without have to add the DC in the logon workstation’s list. Silent…..the conf call remained silent for 30 seconds.
Time to break that silence and then see what’s going on behind the scenes; of course, the best way to do that and see what is passing through the wire.
4. Narrowing Down
To understand what the difference was between the two applications I got a netmon trace on each scenario and let’s see what happened:
Test 1 – Using Microsoft LDAP.EXE Tool
1. Client sends the request (TCP Port 389) and the 3 way handshake happens successfully:
188.8.131.52 184.108.40.206 TCP 4507 > ldap [SYN]
220.127.116.11 18.104.22.168 TCP ldap > 4507 [SYN, ACK]
22.214.171.124 126.96.36.199 TCP 4507 > ldap [ACK]
2. The LDP Tool sends the “Bind Request” and the credentials are sent using NTLM:
188.8.131.52 184.108.40.206 LDAP MsgId=13
Bind Request, DN=(null), NTLMSSP_AUTH, User: DOMAINNAME \TestUser
Lightweight Directory Access Protocol
LDAP Message, Bind Request
Message Id: 13
Message Type: Bind Request (0x00)
Message Length: 225
Response In: 3175
Auth Type: SASL (0x03)
GSS-API Generic Security Service Application Program Interface
NTLMSSP identifier: NTLMSSP
NTLM Message Type: NTLMSSP_AUTH (0x00000003)
Lan Manager Response:
NTLM Response: F2988187EC1C67496EDF4F46313F401E08F688325DC541A8
Domain name: DOMAINNAME
User name: TestUser
Host name: COMPUTER1
Session Key: 33724B7018EADC94650FCAAB1F6741EF
3. Server answers saying that the bind was done successfully:
220.127.116.11 18.104.22.168 LDAP MsgId=13 Bind Result
LDAP Message, Bind Result
Message Type: Bind Result (0x01)
Message Length: 9
Response To: 3174
Time: 0.001953000 seconds
Result Code: success (0x00) <----------------------
Matched DN: (null)
Error Message: (null)
Test 2 – Using Third Party LDAP Application
2. The LDAP Application sends the “Bind Request”, but now check the difference:
22.214.171.124 126.96.36.199 LDAP MsgId=1 Bind Request, DN=CN=TestUser,OU=Test,DC=domainname,DC=local
Message Id: 1
Message Length: 83
Response In: 998
Auth Type: Simple (0x00) <---------------- Authentication Method
4. Server answers with the error:
188.8.131.52 184.108.40.206 LDAP MsgId=1 Bind Result, invalidCredentials
Message Length: 94
Response To: 997
Time: 0.001954000 seconds
Result Code: invalidCredentials (0x31) <-------------- ERROR
Error Message: 80090308: LdapErr: DSID-0C090334, comment:
AcceptSecurityContext error, data 531, vece
The LDAP Protocol implemented by Microsoft can use the following methods:
Authentication with a simple clear-text password.
Windows NT® LAN Manager
Distributed password authentication (used by Microsoft Membership System)
Generic security services (GSS) (Snego). Does not provide any authentication services, instead chooses the most appropriate authentication method from a list of available services and passes all authentication information on to that service. Use with Windows® 2000
This constant is obsolete and is included for backward compatibility only. Using this constant selects GSS (Snego) negotiation service.
Table extracted from the document Understanding LDAP.
Now the question: what the authentication method have to do with the LDAP problem?
Let’s see the authentication process on the third party LDAP Application:
1) The application sends the authentication using LDAP_AUTH_SIMPLE. This method sends only the user name and the password.
2) When the DC receives the authentication requests it checks not only the user’s credential, but also the User-Workstations attribute. This attribute contains list of computers that the user can logon.
3) Since the application doesn’t send the location (domain or computer name) the DC uses his own name to check (DCNAME\User) to check that.
4) DC checks if his own NetBIOS name is present on that list and since it is not it will refuse with an Access Denied.
Now it makes sense that if we add the DC’s name to that list it will work, right? J
With the Microsoft LDP Tool this doesn’t happen because we send the credential using LDAP_AUTH_NTLM. When we do this, the computer’s name is present in the request, as showed below:
The problem was not with the Microsoft LDAP Standard, neither was a security vulnerability in the system. The problem was on this particular LDAP Application that was using an unsecure authentication method. This is another prove that security is not only one piece, when we think about security we have to cover all areas. In this case there was an extreme concern about protecting the domain with security policies, do not leave breaches, be diligent!!! However, the main company’s application was using clear text authentication method.