Introduction


During a recent IT audit in an enterprise organization, the tasks included verification of database user ID's to ensure they belong to active, valid users. With the continuing trend of deploying more and more applications on WINTEL platforms, the majority of databases are likewise on WINTEL, their user access being set up through centralized Microsoft Windows Active Directory groups.

I faced the problem of how to extract the users belonging to various domain groups: Located in a remote location, having a difficult timezone offset, without access to local user ID verification records and support teams, I had to find a way to extract user ID data independently, which would also be most efficient.

The following three factors have been a great help:

Prerequisites


Let's start with a Windows 7 laptop as a domain member, together with a local domain user account.

The first step of validating users in Windows Active Directory is to become familiar with how to access and extract user data within your local Domain. A Windows domain has a centralized database located on dedicated Windows servers, the Domain Controllers. We need to get the name of our local domain, plus the IP's of the controllers.

Extracting the Domain Name

This step is often unnecessary, since domain names are typically part of the user login and often well-known. To be sure, we can open the Windows builtin command prompt on our destop and run:

C:\>net config workstation
Computer name                        \\HUSDE583752
Full Computer name                   husde583752.frank4dd.com
User name                            frankme

Workstation active on
        NetBT_Tcpip_{4BCFB712-EEBA-45F9-90F2-5275245E4C4B} (F0DEF177C1D1)

Software version                     Windows 7 Enterprise

Workstation domain                   MYDOMAIN3
Workstation Domain DNS Name          frank4dd.com
Logon domain                         MYDOMAIN3

COM Open Timeout (sec)               0
COM Send Count (byte)                16
COM Send Timeout (msec)              250
The command completed successfully.

We note the 'Logon domain' (NetBIOS domain name) and the 'Domain DNS Name' values.

Extracting the Domain Controller IP Address

The next step will give us the local domain controllers IP address, the second important piece of information we need. Here, we use a very helpful program called nltest. In my case it came with Windows 7 pre-installed, XP users possibly need to download a package called Support Tools from Microsoft Technet. More information about 'nltest.exe' is available here: Confirming Domain and Workgroup Membership

C:\>nltest /DCLIST:MYDOMAIN3
Get list of DCs in domain 'MYDOMAIN3' from '\\JPNHOMG001'.
      pdc01.frank4dd.com [PDC] [DS] Site: Default-First-Site-Name
      bdc02.frank4dd.com       [DS] Site: Default-First-Site-Name
                             OLDSERVER2
      bdc03.frank4dd.com       [DS] Site: Default-First-Site-Name
The command completed successfully

With knowledge of the DNS name, let's make a quick translation to the IP through 'ping' or 'nslookup'.

C:\>ping pdc01.frank4dd.com -n 1

Pinging pdc01.frank4dd.com [192.168.100.21] with 32 bytes of data:
Reply from 192.168.100.21: bytes=32 time=1ms TTL=127

Checking domain controller's LDAP network access

After locating the IP's for the domain database, let's review our access options. Active Directory, introduced with Windows 2000, is an LDAP-based directory service. LDAP (Lightweight Directory Access Protocol) is a network service with standard ports '389/TCP' and '636/TCP' (SSL-encrypted).

For more information about LDAP, one of the best presentations is "Directory-enabled Applications" from Netscape.

Windows domain controllers come with LDAP available on port 389 by default. (Ref. Active Directory Domain Services)

The default at port 389 means that Active Directory access is cleartext only, and the encrypted LDAPS protocol needs to be explicitly enabled. (Ref. How to enable LDAP over SSL)

We check if the default LDAP network port is available to us. I am using a simple 'telnet', the technically inclined could use specific tools (i.e. port scanners like nmap).

C:\>telnet bdc02.frank4dd.com 389
...

Access failure could cause this response:

Connecting To bdc02.frank4dd.com...Could not open connection to the host, on port
 389: Connect failed

Note:i In Windows 7 the 'telnet' command is no longer standard, but requires extra installation i.e. by using the "Features" wizard.

Domain controller's LDAP user access

Knowing the Active Directory IP and port, how do we know which users can user access? Since Windows 2003, Microsoft allows default access for *all* authenticated domain users. Before 2003, even anonymous access was accepted. (Ref: Anonymous LDAP operations to Active Directory)

Given that a Windows domain account is a standard, and usually provisioned to all users (often including contractors, etc), there is nothing left in the way of anybody "reading" one of the most critical, central, access-granting databases in the organization.

We will test user access soon, lets first select a suitable client program for LDAP.

LDAP access software


The following LDAP client programs are provide easy data visualization through a graphical interface. Below is a list of three freely available, popular browsers:

1. Softerra LDAP Browser 4.5

Softerra LDAP Browser 4.5

License: free for any use, including commercial

Download: http://www.ldapbrowser.com

+ 'read-only' design for worry-free access
+ Can do Kerberos (GSS) authentication to access DC in remote, trusted domains
- Sometimes showing values as "unspecified" when they are in fact '0' for a reason)

2. Apache Directory Studio

Apache Directory Studio

License: Apache License 2.0

Download: http://directory.apache.org

- Could not connect to remote DC through trusted domains, using Kerberos (GSS)

+ Powerful export functions

+ Java-based, platform independent

3. LDAP Admin

LDAP Admin

License: GNU General Public License

Download: http://www.ldapadmin.org

+ Can do Kerberos (GSS) authentication to access DC in remote, trusted domains
+ Correctly displays true value, i.e. zero vs. unset
- Simple, although sufficient functions

Connecting to AD


With access parameters, and client software, we can now access AD. Let's review the LDAP-typical authentication methods and options:

LDAP login IP or DNS LDAP login user ID

First we specify the IP or DNS name of the Domain Controller (left image). We can use the standard port 389, and additionally we need to give the Base-DN (DN=Distinguished Name). For Windows AD, this typically refers to the Domain's DNS name. In this example, it would be DC=frank4dd,DC=com.

For credentials (right image), the easiest way to connect is to select Currently logged on user (Active Directory only). It is also possible to select "Simple". There, the username is a construct of the Windows user ID, followed by '@' and the Domain DNS name. This construct is called userPrincipalName, and although it may look like an email address, it is not necessarily identical. The 'Simple' authentication method is most useful for scripting against AD's LDAP, and serves only as a example for cases when built-in authentication is not available.

Querying Data in Active Directory


AD LDAP structure

After login, we have to navigate the LDAP structure. Active Directory organizes its data objects (i.e. users, groups, computers) hierarchical, requiring to drill down to the actual records. The records format is predefined through classes and attributes in a specific LDAP schema. (Ref. Active Directory Schema)

Because it is easy to get confused by terminology, let's look at an example domain user account record. Below, a domain user account has been extracted from AD, showing the typically available information. Navigating the tree down to the Users default container, we typically find domain user accounts below it. Under the Users container, administrators could organize accounts in subcontainers by department, role, etc. In our example, the sub-container (OU = organizational unit) called IT_department has been created.

Besides users, we find wealth of information about computers in Active Directory. First, there are the systems that have been joined to the domain: domain members. Then, it is quite typical to run a domain controller also as a DNS server. While DNS security often restricts anonymous zone transfers (which allows to see all systems registered in DNS), don't despair. All DNS records are nicely visible in AD, and we can extract all DNS zone information from there.

Active Directory user ID example:

NameValue
objectClasstop
objectClassperson
objectClassorganizationalPerson
objectClassuser
cnfrankme
snMe
descriptionEmployee ID #A320021
givenNameFrank
distinguishedNameCN=frankme,OU=IT_Department,OU=User,DC=frank4dd,DC=com
instanceType4 [ Writable ]
whenCreated20080215211605.0Z [ 2008/02/15 21:16:05 ]
whenChanged20121217003856.0Z [ 2012/12/17 0:38:57 ]
displayNameFrank Me
uSNCreated21128
memberOfCN=acl_it_staff,OU=Information Technology,OU=User,DC=frank4dd,DC=com
memberOfCN=acl_dept_fileshares,OU=Security - Global,OU=User,DC=frank4dd,DC=com
memberOfCN=acl_it_architecture,OU=Information Technology,OU=User,DC=frank4dd,DC=com
uSNChanged58452002
namefrankme [ this is an obsolete Windows 2000 attribute]
objectGUID{3CE3E514-E038-44E3-8C4C-41D5E37A6099}
userAccountControl512 [ NormalAccount ]
badPwdCount2
codePage0
countryCode0
badPasswordTime130005249549020623 [ 2012/12/21 0:55:54 ]
lastLogoff0 [ unspecified ]
lastLogon130005249613083123 [ 2012/12/19 7:03:43 ]
scriptPathlogonNoProxy.bat
logonHoursFF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
pwdLastSet130001783218449183 [ 2012/12/17 0:38:41 ]
primaryGroupID513
objectSidS-1-5-21-1047594904-1774598210-1845911597-17667
accountExpires0 [ never ]
logonCount21282
sAMAccountNamefrankme
sAMAccountType805306368 [ samUserAccount ]
userPrincipalNamefrankme@frank4dd.com
lockoutTime0 [ unspecified ]
objectCategoryCN=Person,CN=Schema,CN=Configuration,DC=frank4dd,DC=com
lastLogonTimestamp129998313117351145 [ 2012/12/13 0:15:11 ]
mailfrankme@frank4dd.com

The following account attribute records are particularly interesting:

Tip: Avoid getting excited here. It is tempting to test, using your least favorite colleague's credentials and lock them out, all while watching the increase of badPWDCount :-). Remember the Windows eventlog might be reviewed.


In large organisations it is not uncommon to have thousands, or ten thousands of user records. We quickly realize that just browsing our way through the LDAP tree is not efficient. In Active Directory, the number of records returned in one query is limited to 1.000. If the query returns more, a 'limit exceeded' message is returned. Bad luck if our record is number 1001. We really need to learn how to filter and search our data in Active Directory. LDAP search filters have their own syntax, and below are example queries to get started. See also Search Filter Syntax.

Accessing AD in Trusted Domains


In large enterprise organisations, we typically find multiple Windows domains, connected to each other through the principle of "trust". These "trust" relationships allow granting access accross organizational boundaries. The same "trust" will also allow us look into the domain controller of a different part in our organization, listing their users, groups, and systems.

Domain "trust" is also a dangerous feature that could expose remote organizations network file shares, but this discussion is a separate topic. Just be aware that Windows built-in functional ID's such as "Everyone" and "Authenticated Users" work great accross domain boundaries.

If you google the topic about accessing LDAP on a remote, trusted domain, most respondents will say that this is not possible. I did this frequently, and it works. There is one restriction: You'll need to use the Windows-builtin Kerberos authentication mechanism. No other authentication method can connect you, and this rules out a lot of third-party scripts or tools. But lets start. Again, we need to gather some information before we can connect:

  1. What are our trusted domains?

    Here, the nltest command will help us again to identify the available choices:

    D:\Code\DNS>nltest /DOMAIN_TRUSTS
    List of domain trusts:
        0: MYDOMAIN1 amer.partner.net (NT 5) (Direct Outbound) (Direct Inbound) ( Attr: quarantined
        1: D2PRD prd.supplier2.com (NT 5) (Direct Outbound) (Direct Inbound) ( Attr: quarantined )
        2: CHDMP china.f4dd.com (NT 5) (Direct Outbound) (Direct Inbound) ( Attr: quarantined )
        3: MYDOMAIN3 frank4dd.com (NT 5) (Forest Tree Root) (Primary Domain) (Native)
    The command completed successfully
    
  2. What are the trusted domain controllers?
    D:\Code\DNS>nltest /DCLIST:amer.partner.net
    Get list of DCs in domain 'amer.partner.net' from '\\KDQDCP01.amer.partner.net'.
        PSMDCP01.amer.partner.net       [DS] Site: PSM
        PSMDCP02.amer.partner.net        [DS] Site: PSM
        KDQDCP01.amer.partner.net        [DS] Site: KDQ
        B04DCP05.amer.partner.net [PDC]  [DS] Site: B04
    The command completed successfully
    

    And viola, we got all DNS names of the domain controllers. Since the domains are trusted, DNS is often replicated or at least forwarded, so getting the trusted domain controllers IP address should not be an issue. Typically, a simple 'ping' works at this point and returns us the IP.

  3. Are there network restrictions preventing access to LDAP ports?

    For this verification, we simply do another port access check as documented in "Prerequistes" above, just to make sure. Sometimes, a firewall really blocks. This is a mere accident, because internal firewalls are mostly just IT's decorations.

Finally, we connect to the remote domain controllers with our LDAP client, same as if they where local. Remember only the Windows-integrated Kerberos authentication will work. Some clients call it "Windows-integrated", others call it GSS-API. Not all clients handle this method well, I had trouble using it with Apache Directory Studio (Java).

Conclusion


With some background about LDAP technology, Active Directory in its default configuration is a open book to anybody who cares, and the information can be both useful or dangerous. For user verification and auditing, querying the true source is ideal, as it provides core data independent from the auditee.

More information and articles around this topic:

Index:

See Also: