This site uses advanced css techniques
Microsoft's Active Directory is an enormous repository of information about an enterprise, and it's available programmatically via LDAP. Much of the information is not terribly accessible to the common user, but the contact list and address book are commonly used with email.
Though it's mainly intended for use inside an enterprise, some administrators wish to expose AD/LDAP to the public internet for various reasons (often related to address-book support in non-Windows email clients).
Our belief is that exposing AD/LDAP to the internet is just too risky even when secured with SSL because the attack surface is very large. But rather than issue a blanket prohibition, we've created this Tech Tip that addresses the factors at play, and they can be considered when weighing this kind of decision.
All Microsoft LDAP/AD servers will give up metadata about the server itself to all callers via an anonymous connection: this is the RootDSE that describes the directory itself, and we can query this information remotely with any LDAP query tool.
Using the open source OpenLDAP project's ldapsearch tool, we can bind to the root of the directory and get a raft of useful information:
$ ldapsearch -x -s base -b "" -H ldap://192.168.1.7 # extended LDIF # # LDAPv3 # base <> with scope baseObject # filter: (objectclass=*) # requesting: ALL # # dn: currentTime: 20080524034826.0Z subschemaSubentry: CN=Aggregate,CN=Schema,CN=Configuration,DC=unixwiz,DC=lan dsServiceName: CN=NTDS Settings,CN=myserver,CN=Servers, CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=unixwiz,DC=lan namingContexts: DC=unixwiz,DC=lan namingContexts: CN=Configuration,DC=unixwiz,DC=lan namingContexts: CN=Schema,CN=Configuration,DC=unixwiz,DC=lan namingContexts: DC=DomainDnsZones,DC=unixwiz,DC=lan namingContexts: DC=ForestDnsZones,DC=unixwiz,DC=lan defaultNamingContext: DC=unixwiz,DC=lan schemaNamingContext: CN=Schema,CN=Configuration,DC=unixwiz,DC=lan configurationNamingContext: CN=Configuration,DC=unixwiz,DC=lan rootDomainNamingContext: DC=unixwiz,DC=lan supportedControl: 1.2.840.113556.1.4.319 ... supportedLDAPVersion: 3 supportedLDAPVersion: 2 supportedLDAPPolicies: MaxPoolThreads ... highestCommittedUSN: 1234 supportedSASLMechanisms: GSSAPI supportedSASLMechanisms: GSS-SPNEGO supportedSASLMechanisms: EXTERNAL supportedSASLMechanisms: DIGEST-MD5 dnsHostName: myserver.unixwiz.lan ldapServiceName: myserver.unixwiz.lan:myserver@UNIXWIZ.LAN serverName: CN=myserver,CN=Servers,CN=Default-First-Site-Name,CN=Sites, CN=Configuration,DC=unixwiz,DC=lan supportedCapabilities: 1.2.840.113556.1.4.800 ... isSynchronized: TRUE isGlobalCatalogReady: TRUE domainFunctionality: 2 forestFunctionality: 2 domainControllerFunctionality: 2 # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1
One can accomplish the same thing from Windows with a friendly GUI by using LDP.EXE, available in Support Tools (see sidebar). Launch the tool and enter the remote IP address, and click [OK].
This obtains all the same information as shown with the ldapsearch command, and the LDP tool is documented in the Microsoft Knowledge Base:
Much of this information is entirely innocuous, but it does give a pretty clear idea of the server's hostname (myserver.unixwiz.lan) and the default LDAP naming context (DC=unixwiz,DC=lan) is the root of the real directory.
If this server is already known to be associated with the enterprise in question (IP address block ownership or inverse DNS), then this information leakage may well be of no consequence.
The default LDAP port is 389/tcp, and though this is easy to set up and configure, it may pass the binding name and password in cleartext. An intermediary with a network sniffer wont have any trouble snagging the credentials from the wire in this case:
# tcpdump -A -s0 host 192.168.1.7 listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes ... 13:35:32.054594 IP xscan.unixwiz.lan.58667 > myserver.unixwiz.lan.ldap: P 1:81(80) ack 1 win 23 <nop,nop,timestamp 1814733662 0> E...R.@.@._.@..e.....+...............]..... l*.^....0N...`I....: CN=Steve,OU=Users,OU=MyBusiness,dc=unixwiz,dc=lan..mypass ...
This is as easy to sniff as a telnet connection, and once a user's credentials are known, they may provide substantial leverage for additional access via Remote Desktop, Outlook Web Access, Remote Web Workplace, a VPN, or other routes to the server.
Most LDAP servers support one or more authentication mechanisms that do not send the password unencrypted, and this is strongly recommended if available. We're fuzzy on the various options available, and it does require that both the client and the server agree on a method in common: such agreement may not be possible for every client and server combination.
In addition, AD can support encrypting (Microsoft calls it "sealing") the data stream itself via the ldapclientintegrity and ldapserverintegrity registry keys, though it's not clear that non-MSFT clients would be able to use them. Unencrypted responses likely provide many additional clues about the enterprise (including other usernames in the directory, providing grist for the brute-force mill, as noted in the next section).
But even without these other avenues of access, having known credentials allows for walking huge swaths of the LDAP tree — this would be a gold mine of information about the enterprise. Our first instinct would be to fetch the list of all users in the directory.
To forestall this, it's possible to instead use LDAPS, which is LDAP over SSL, via port 636/tcp. Unfortunately, this requires installation of a certificate on the server side, and there doesn't appear to be an easy GUI method to accomplish this.
Microsoft's knowledge base again has the instructions for doing this:
After configuring and testing LDAPS, be sure to firewall the insecure 389/tcp port from the internet at large.
Even without the ability to sniff a connection — as an attacker typically won't — it's still possible to make use of an open LDAP/LDAPS port by attempting to brute-force account credentials.
Active Directory's LDAP server is very high performance, and it can support many concurrent connection attempts. We wrote a simple LDAP brute-force tool in perl (sorry, this tool is not publicly available), and even a single-threaded connection can do 10 guesses per second across the internet on a residential DSL circuit. Writing a multithreaded version would be far faster.
Allowing public access to a service that's allows high-speed brute-forcing is, in our view, the single factor that militates against exposing LDAP (SSL-protected or not) to the public internet at all.
See also the rate-limiting suggestion in the next section.
Just because one decides to firewall LDAP/LDAPS from the internet doesn't mean that there's still not a technical problem to solve (remote access to the directory), so we'll discuss some approaches that may help on this front.
service ldap { disable = no flags = REUSE socket_type = stream protocol = tcp wait = no user = root groups = yes interface = 192.168.7.2 — optional - interface to listen on redirect = 10.0.1.2 ldap — IP of the real server instances = 50 — max concurrent connections cps = 15 10 — max connections-per-second rate per_source = 10 — max connections per IP }
First published: 2008/07/09