Tuesday, December 4, 2018

Disabling Unauthenticated Binds in Active Directory

In January last year, I wrote a (long) post detailing a curious behavior I stumbled across in Active Directory's LDAP interface. By providing a username, but leaving the password blank, you were authenticated as an 'anonymous user'. This is technically a valid LDAP behavior, and is known as an 'unauthenticated bind'. However it's obscure, not well known, and the cause of many security vulnerabilities.

To recap, the LDAP RFC states the following;
5.1.2. Unauthenticated Authentication Mechanism of Simple Bind
An LDAP client may use the unauthenticated authentication mechanism of the simple Bind method to establish an anonymous authorization state by sending a Bind request with a name value (a distinguished name in LDAP string form [RFC4514] of non-zero length) and specifying the simple authentication choice containing a password value of zero length
The RFC goes on to acknowledge this is an objectively terrible idea, and recommends that servers reject unauthenticated bind requests by default.
Unauthenticated Bind operations can have significant security issues (see Section 6.3.1). In particular, users intending to perform Name/Password Authentication may inadvertently provide an empty password and thus cause poorly implemented clients to request Unauthenticated access. 
Additionally, Servers SHOULD by default fail Unauthenticated Bind requests with a resultCode of unwillingToPerform.
Sadly, Microsoft's Active Directory and Lightweight Directory Services products did not support disabling this behavior at all, let alone having it off by default as suggested by the RFC.

The good news is that in Windows Server 2019, Microsoft have added in the ability to disable unauthenticated binds. So Windows now joins all other major LDAP vendors in providing the capability to turn off this 'feature'

Can be disabled
Disabled by default
Red Hat Directory ServerYesYes
Novell eDirectoryYesNo
Oracle/Sun Directory ServerYesYes
Microsoft AD LDS/ADAMYes* (Server 2019+)
Microsoft Active DirectoryYes* (Server 2019+)No
They stopped short of making it off by default, which would have been preferable, but at least it is an option now.
So, how do you enable it?
Using ADSIEdit, open the Configuration partition, and open the properties of the CN=Directory Service, CN=Windows NT, CN=Services, CN=Configuration object. Modify the msDS-Other-Settings attribute, and add a new entry for DenyUnauthenticatedBind=1

The setting takes effect immediately, and does not require a reboot.
Now, when you attempt to login without a password, it will fail with an Unwilling To Perform error message.

res = ldap_simple_bind_s(ld, 'let me in', <unavailable>); // v.3
Error <53>: ldap_simple_bind_s() failed: Unwilling To Perform
Server error: 00002035: LdapErr: DSID-0C0903AD, comment: The server has been configured to deny unauthenticated simple binds., data 0, v4563
Error 0x2035 The server is unwilling to process the request.
That's all there is to it. You follow the the same process to apply the fix to your LDS instances.
Granted, it's not a perfect outcome  - you still need to upgrade all your domain controllers and/or LDS servers to Windows Server 2019 to take advantage of this capability, but if this is important to you, there is at least a solution available.

Time to start planning those upgrades...

Thursday, July 26, 2018

Announcing the Lithnet LAPS Web App

Microsoft's Local Admin Password Solution (LAPS) is a very important tool that protects against the risk of lateral movement of threats between computers when the same local admin password is used on each machine.

It is an agent that is deployed to each computer that randomises and rotates the local administrator password on each machine, and securely stores it in the Active Directory.

While the LAPS mechanism itself is robust and does exactly what it needs to do, the process of accessing the LAPS passwords, and auditing that access is not so straight forward.

Support staff out in the field may not have easy access to the tools required to get those passwords. You either need to use PowerShell, LAPS client, or another directory tool such as AD Users and Computers.

Auditing access to LAPS passwords is a bit of a nightmare. It requires configuring audit policies on domain controllers for directory object access, which is a very board audit category and can be very noisy. You need to find your LAPS events in this dataset, filter them, and send them off somewhere manageable.

To help address some of these 'client-side' issues, I'm releasing the Lithnet LAPS web app, a mobile-friendly, web-based interface to gaining access to LAPS passwords.

Web-based access to LAPS passwords

The LAPS web app provides a simple web-based and mobile-friendly interface for accessing local admin passwords. There's no need for admins to install custom software, or have access to AD administrative tools to access LAPS passwords. Simply provide the computer name, and if you have access, the password is shown.

Application administrators have the option of forcing an expiry time once a password has been accessed. This ensures the password is rotated after use.

Audit success and failure logs

All success and failure events are logged to the event log and a file. These can be easily shipped off to a SIEM for record keeping or further analysis and reporting. Audit events can also be sent via email, and are configurable based on the LAPS target computer.

Fine grained authorisation

The web app supports authorising access to target passwords at a computer, group, or OU level. Permission can be granted to individual users and groups in the directory. 

Rate limiting

The web app uses a dedicated service account to read LAPS passwords, and does not require individual users to have LAPS password access in the directory. This reduces the risk of a compromised LAPS reader account being able to enumerate all the LAPS credentials they have access to. The web app imposes configurable rate-limits on the number of times per minute, hour and day each user and/or IP address can read a LAPS password.

Modern authentication options - protect your LAPS access with multi-factor authentication!

The web app supports traditional integrated windows authentication, as well as WS-Federation and OpenID Connect. This means you can leverage external authentication providers such as ADFS, Azure AD, and Okta. These providers give you the ability to enhance the security of your application by enabling multi-factor authentication. There are step-by-step guides for setting up ADFS, Azure AD and Okta, to get you up and running in no time.

Getting started

Visit the Lithnet LAPS Web app site today to download the app and get started

Wednesday, March 14, 2018

The LDAP ‘authentication’ anti-pattern

You could walk into just about any organization today, and you’re bound to find an LDAP directory populated with its users. Look a bit further, and you’ll likely find one or more applications using that directory for ‘authentication’. I say 'authentication' with quotes, because LDAP authentication is something of a misnomer. LDAP is a directory access protocol, designed for reading, writing, and searching a directory service. It's not an authentication protocol. LDAP authentication typically refers to the part of the protocol (binding) that is meant to establish who you are in order to determine what privileges you have to the information in the directory. 

Over time, it’s become a de facto authentication service. The wide-spread availability of LDAP services, such as Active Directory, has turned it into an easy win for software developers who are looking to build authentication into their products. LDAP client libraries are available for just about any framework, and it’s relatively easy to get an LDAP integration functioning. 

While using LDAP authentication might solve the development problem of how to authenticate users across an enterprise, it creates a host of other problems. There are inherent weakness and security issues that using LDAP introduces, that are not present in true authentication protocols. 

In order to understand what these issues are, we first need to understand how LDAP authentication actually works.

How LDAP ‘authentication’ works

Consider the following situation (it’s rather absurd but bear with me).

Let’s say I order a parcel from an online store, only to have it delivered when I wasn’t home. The driver leaves a ‘sorry we missed you’ card in my mail box asking me to visit the local parcel pick-up point to collect the package in my own time. I arrive at the collection point, and the person behinds the counter asks for my name and address, and the keys to my house so they can validate who I am. They get in their car and drive to my house. They approach the front door, insert my key, and turn it. The door opens! They have a look inside for some evidence that I actually live there like some photos on the wall, or some mail with my name on it. They drive back to the parcel centre and let me know they have been able to successfully confirm my identity and I can have my package! Great!

Logistical issues aside, there are a quite a few problems with this situation. What if the attendant wasn’t trustworthy, and they took a copy of my key? What if they were trustworthy, but left the key lying around long enough for someone else to copy it? What if they were mugged, and my keys were stolen off them? Once the keys leave my possession, I really can’t be sure who has them and what they will be used for.

Thankfully in the real world, we have documentation like driver’s licenses and passports to prove our identities. I can hand over a piece of documentation that is issued to me by a 3rd party we both trust, such as a government agency, and my identity can be proven without giving away my keys.

In the LDAP world, we still have to hand over our keys to a 3rd party to unlock the door on our behalf. We give our password to the third party and they try to get into the LDAP server with it. If the password works, then you must be the owner of that password. However, now we have the same problem that we have when we hand over our keys. We really don’t know what is going to happen to those credentials and what they could be used for. If the credentials were compromised, the attacker would not just have access to unlock the LDAP door, but any application using those same credentials.

Thankfully, in the wider world of authentication, we have passports and drivers licenses too! Authentication protocols like Kerberos, SAML and OpenID Connect all issue tokens to 3rd parties that prove you are who you say you are, without having to hand them your keys. As LDAP was never designed to be an authentication protocol, it does not have appropriate mechanisms to do this.

LDAP’s weaknesses as an authentication system

Shumon Huque wrote a fantastic article in 2007 - LDAP Weaknesses as a Central Authentication System which he highlights 3 specific problems with the approach of authenticating using LDAP.

1. The application probably isn't secure enough to be touching credentials

Shumon makes the very valid point that it is far easier to defend a small set of authentication servers against an attack, than it is to defend a large population of application servers. 

Authentication servers are generally locked down and run by people with significant expertise in security. 

On the other hand, application servers have a very different security profile, and are more likely to be compromised. They have less rigorous protection, run more complex software stacks and are more likely to have security bugs. They are also more likely to be run by people who do not have an in-depth knowledge of security. That's not a criticism of the hard-working application administrators out there – getting security right is hard, getting it wrong is too easy! 

The problem becomes that if a single application server is compromised, all the credentials that were used during the window of compromise are also compromised. Any other system that those users could log into with those same credentials, can also be considered compromised.

2. The LDAP server cannot enforce the security of the authentication mechanism used to obtain the credentials

The security of the transaction cannot be guaranteed by the LDAP server. While the LDAP server might for example be able enforce binding over TLS to ensure credentials are not transmitted in plain text, it never played a role in capturing those credentials in the first place. The application might be receiving the password over an insecure channel.

3. The user must reveal their authentication secret to a 3rd party 

A user's password, or authentication secret, should remain that, a secret. It should be known only to the authentication system, and the user themselves. When using LDAP for authentication, the user must disclose their secret to a 3rd party, for them to replay that secret against the LDAP directory.

It's probably important to call out here, that with true authentication protocols such as Kerberos, and even the older NTLM, the user secret never passes over the network. The client device and server use cryptographic operations to prove they both have the same secret, without ever exchanging the secret itself.

I'm going to add a few of my own concerns to Shumon's points. These relate to my personal experience, primarily with consumers of Active Directory;

4. Many developers don't know how LDAP works well enough to use it correctly

One of my previous blog posts details how anonymous and unauthenticated binds have tricked many developers into letting unauthorized users into their applications. Unauthenticated binds are one of the subtleties in the protocol that even the most seasoned LDAP professionals are unaware of. 

Directories are complex, and they can store an enormous amount of organizational information and provide a highly customizable way of doing that. I've seen so many cases where the developer of an application assumed a specific object class or attribute existed, and the whole thing falls over when it doesn't. To authenticate a user, you shouldn't need to have a working knowledge of the structure of the data stored in a directory. An authentication protocol should abstract away the detail of the underlying object store.

5. Application administrators often don't configure LDAP clients correctly

One of the frustrating things about managing an Active Directory in a large distributed environment, is that it's difficult to determine when services are using AD as an LDAP directory, and how the application administrators have configured their LDAP client. 

Some of the configuration horrors I’ve seen include;

  • Hardcoding DNs in applications, or using DNs in bind configuration. I've seen countless incidents caused by a rename or move of an object within in the directory, because someone has hard coded a DN somewhere. (A side note to those performing simple binds against AD - you don't need to use a DN to do this. AD also provides alternative DN formats that are more robust than using a traditional DN).
  • Using personal user accounts as a ‘bind’ account instead of a service account (guess what happens when that person leaves the organization)
  • Sending passwords in plain-text over port 389
  • I’ve seen applications with a check box to optionally ‘validate certificate’ when connection to AD using TLS (port 636). Why is this even an option? You are going to throw a password at an endpoint, and you’re not even going to check if it’s the endpoint that you think it is? 

It’s easy to get an LDAP client working, but just because it’s working, doesn’t mean the configuration is correct.

6. LDAP authentication and modern authentication are mutually exclusive

An application using LDAP for authentication will forever be limited to usernames and passwords. Trying to implement modern technologies such as multi-factor authentication and single sign on are virtually impossible (unless you are going to roll your own, which is a bad idea in its own right). The FIDO alliance aims to make passwords a thing of the past. Granted, this is a long term vision, but every application using LDAP authentication is going to stand in the way of an organization going password-less.

What are the alternatives?

Web applications today really have no need to use LDAP for authentication. There are many great web-enabled authentication protocols such as SAML, WS-Federation and OpenID Connect that do not require 3rd party applications having to touch credentials. Any number of products are available that provide these services, including Active Directory Federation Services (built into Windows Server), or hosted offerings such as Microsoft's Azure AD, Okta, Ping, and more. If you don’t have a federated identity provider available in your organization, you need to set one up as a first step.

When you are looking at new software, or going to tender, set a requirement that it must support modern authentication protocols. You may be able to use your organizations purchasing power to negotiate a better security outcome for your users. It’s ok if the vendor pushes back, or the business wants an application that only has LDAP support today. Have the conversation with the vendor anyway and tell them you want them to add support for modern authentication protocols to their product roadmap. It gets the conversation going. The more customers ask for it, the more likely they are to build it. However, if none of their customers ask for it, they’ll never do it.

A trend I’m really happy to see is a growing number of ‘thick-client’ desktop applications supporting modern authentication protocols. These apps have typically been an LDAP authentication stronghold. There are a growing number of SDKs such as the Microsoft Authentication Library (MSAL) that make it easy for developers to drop-in support for modern authentication into their mobile and desktop applications. 

Ultimately, there is a reality to accept in that not all applications today support modern authentication protocols, and perhaps they never will. Implementing a total ban on LDAP authentication is likely not possible in any organization. However, LDAP authentication should be strongly discouraged within the organization. It should only be considered when no other options are available. When going to market for new software, mandate modern authentication support as a requirement. Have vendors or application owners prove that LDAP authentication is the only option before allowing it. Don't offer it as a commodity authentication service.