Update your LDAPS connections!!
For those few of you awaiting the second installment of my security maturity series, don’t worry, it’s coming. This post is more of a public service announcement type of post. Fortunately, that means it will theoretically be shorter than the last one 😉
In case you haven’t heard, Microsoft is releasing a patch in March related to LDAP connections to AD. The patch was originally slated for release this month, but was pushed back for various reasons. If you want to check out all of the details, you can do so in the related security advisory posted back in August found here. To save you some time however, I’ll summarize the key points relevant for this post:
- LDAP Channel Binding will be configured as required
- LDAP signing will be configured as required on all clients and servers
- The patch changes system behavior, so current policies to disable or lower these settings will be overridden
So, let’s take a minute to elaborate on what these changes actually do/mean.
LDAP Channel Binding
This setting determines whether or not LDAP binds must use LDAPS. When enforcement is turned on, attempts to bind to LDAP in your domain will be rejected outright. For your direct domain members, this isn’t an issue as they communicate in another manner (which I won’t go into today). LDAPS originally referred to LDAP over SSL, which was introduced to the RFC standard as part of the LDAPv2 specification. This specification was officially superseded by LDAPv3 in March of 2003, and LDAPS now refers to LDAP over TLS. These are largely semantics for most admins, as both technically refer to using SSL certificates to secure a connection, it’s just the means of creating and protecting those certificates that has evolved over time to use improved standards.
LDAP Channel Binding comes into play only when a client attempts to bind to an object in AD via LDAP. AD supports three options for binding to objects; simple, SASL, and Sicily. In a simple bind, it’s exactly that…simple. The client provides a connection request, followed by a single additional communication that conveys the LDAP version, the distinguishedName (DN) of the object, and the password to be validated, which is sent in clear text. If this type of bind is performed with no SSL encryption, it means that anyone sniffing traffic on your network can retrieve those credentials with relative ease. Sicily is not part of the RFC for LDAP, and is instead specific to AD. While this method is still technically supported, it’s mostly just there to support legacy systems that are performing NTLM based LDAP binds, and it isn’t really in scope for this post. As for SASL, that stands for Simple Authentication and Security Layer, and is the more common type of LDAP binding in most cases. I’ll be getting into more detail on this one in the next section.
I have seen a few posts from others, though I’ll not name any names, that advocate simply enabling SSL alone is sufficient to protect these simple binds, but this isn’t actually the case. When you create an SSL connection to a device, all you’re doing is requesting a secure pipe to allow you to send data over. It has nothing to do with the content being sent, and provides no other identification or agreement between the client and the server. Sure, if the client system is properly configured, it will validate that the server it’s connecting to matches the subject name on the certificate, but there’s no validation going the other direction. This seemingly minor distinction means that attackers don’t actually need to decrypt the traffic at all. Because there’s no source validation, it allows attackers to use what’s referred to as a ‘replay attack’. This type of attack involves capturing the SSL encrypted traffic, and then sending those same packets to the server from their own client, which enables the attacker to impersonate the user. For this reason, simple binds, even those sent over LDAPS, will fail after the patch goes live. This is due, in large part, to the second setting…
LDAP Server Integrity
So, the first part of the conversation was on securing the communication channel, and this part now shifts to securing the content. As mentioned above, the reason LDAPS binding alone is insufficient is the inability to validate the source from which the data originated. When server integrity enforcement is enable, it solves this problem by requiring a ‘signature’ of sorts, which is where SASL comes in. Simple binds can’t do multi-part communications to any advanced degree, whereas SASL does. This is important here because, in order to properly protect the content as well as the pipe, the client and the server have to agree on how.
Essentially, the client initiates the bind request, usually with a StartTLS message. After the initial connection is formed, the client tells the server what encryption standard it prefers, and this may result in some back and forth until a common mechanism is identified. Once the two know what language to use (so to speak), the server randomly generates a key for that specific transaction, and sends it to the client. The client system uses this unique key to encrypt the password for the bind request, and then sends along the content over the encrypted connection. Finally, the server sends a response, and you’re off to the races.
In this scenario, an attempt to execute a replay attack with this transaction would fail. This is because the key used for the last transaction is not valid for a new transaction initiated from a different client. Even if the attacker was able to mimic the original client system, the attempt would still fail, because a new transaction, and therefore a new key, would be required. Even should the original transaction still be in progress, the replayed packets would likely be interpreted as a new transaction or, at worst, appear to the server as duplicate. Either way, the attempt fails.
One more note here is a caution regarding SASL. Just because the client system performing the binds uses SASL instead of a simple bind, that does not negate the need for testing. Some poorly written apps or solutions may be mimicking simple bind behavior by sending the password in clear text. If it’s not hard coded, then this behavior would be corrected as part of the transaction during negotiation, but if it does happen to be hard coded, or if the coding doesn’t allow for negotiation, connection will fail.
Wrapping Up
The first and foremost recommendation is to TEST, and to start testing ASAP!! While this patch will implement enforced changes (unless overridden), there’s nothing stopping you from applying the settings ahead of time. If you don’t have an isolated test environment, you can still test, since most LDAP binds are targeted to a particular IP or host address. You can either isolate and existing DC, or stand up a new temp one in a temp AD site. Create a copy of your existing DC policy, and update for the higher security settings, then use security filtering to deny the Apply right for the isolated DC to the old policy, and all the other DCs on the new policy (use systems, not groups – groups require reboots). Once you have that, app and system owners can either repoint a test instance, or temporarily redirect their production instance (during off hours of course), to let you get the testing done.
Inevitably, you’re likely to encounter some systems or apps that just won’t support the updated controls. I would beseech you not to use that as a reason to globally block the change!! Instead, determine how many servers you may need to handle the anticipated load. Isolate those servers to their own site, but instead of changing GPO, precreate the registry entry to disable enforcement as outlined in this article from the Microsoft Core Infrastructure and Security team blog for only the isolated DCs. Finally, set up a mechanism to restrict IPs allowed to form insecure LDAP binds to these DCs to a whitelisted set of client machines, and repoint your problem systems to these DCs. When the patch comes along, your isolated DCs won’t be impacted and connectivity should be fine. By limiting the network connectivity, you reduce the chances that an attacker can use a replay attack without first spoofing the system. If you add in some monitoring to watch for that, hopefully any attempts to do this will be highly visible, and you can react quickly.