Digging deep into the AD DS workstation logon process – Part 1

Hi everyone. The holidays are over, spring is quickly approaching, and it’s been far too long since I’ve had a chance to do a deep dive. This year I have some work on the agenda for Microsoft Active Directory Domain Services (AD DS). That work will require a very strong understanding of the network flows, ports, and protocols that provide the service. While there are many different resources on the web, I haven’t found one that gets to the level I’d like to see. This made for the perfect opportunity for a series of blog posts.

Many of us have faced the challenge where there is a requirement to separate the domain controllers providing the AD DS service and the domain members with a firewall. Microsoft does a wonderful job defining the ports and protocols required for this scenario in this link (https://technet.microsoft.com/en-us/library/dd772723(v=ws.10).aspx). The integration is pretty straightforward with the only decision typically being whether to define static RPC ports or leveraging a firewall which is capable of handling dynamic RPC ports.

One of the things I’ve always wondered is when are each of these ports and protocols used? What better place to start than a common source for troubleshooting? For this series of blogs I will do a deep dive into the flows a domain-joined machine uses and what happens within those connections. Yeah I know, AD DS isn’t that glamorous in the year 2017, but all the moving parts, protocols, standards, and functions that power something as seemingly simple as a logon are fascinating and worth a deeper look.

To provide for this scenario I built a small lab in Azure with three Windows Server 2016 Standard VMs. Each VM is configured as seen below:

Name: DCSERVER
Roles: Active Directory Domain Services, DNS
IP: 10.0.10.101

Name: DC2
Roles: Active Directory Domain Services, DNS
IP: 10.0.10.102

Name: MEMBER
Roles: None
IP: 10.0.10.100

The AD DS forest uses the CONTOSO.LOCAL DNS namespace and has one custom site defined named FAKESITE. DCSERVER is servicing the Default-First-Site-Name and DC2 is servicing FAKESITE. FAKESITE has been assigned a subnet range that includes MEMBER. For tools I used Procmon to capture the registry entries that a domain-joined member’s Active Directory site is cached to. Additionally I used netsh to perform a network capture at boot up

Beyond the network flows, I was interested in observing the DCLocator (DSGetDcName) API behavior. I cleared the three registry entries listed below to ensure MEMBER would perform a DCLocator query at boot up. Additionally I used netsh to get a network capture at boot up (https://blogs.msdn.microsoft.com/canberrapfe/2012/03/30/capture-a-network-trace-without-installing-anything-capture-a-network-trace-of-a-reboot/) and Microsoft Network Monitor to analyze the capture.

– HKLMSystemCurrentControlSetServicesTcpipParametersDomain
– HKLMSystemCurrentControlSetServicesNetlogonParametersSiteName
– HKLMSystemCurrentControlSetServicesNetlogonParameterDynamicSiteName

With the background information taken care of, let’s jump into workstation authentication process.

  1. Source: Domain-joined machine
    Destination: Primary DNS Server
    Connection: UDP
    Port: 53
    Protocol: DNS
    Purpose: DsGetDcName API on domain-joined machine uses the information collected from the registries entries listed at the bottom of this step to issue a DNS query for an SRV record to the machine’s primary DNS server for a server offering an LDAP service _ldap._tcp.dc_msdsc.contoso.local. The primary DNS server returns the results of the SRV query.

    • HKLMSystemCurrentControlSetServicesTcpipParametersHostname
    • HKLMSystemCurrentControlSetServicesTcpipParametersDomain
    • HKLMSystemCurrentControlSetServicesTcpipParametersNameServer
    • HKLMSystemCurrentControlSetServicesTcpipParametersDhcpNameServer
    • HKLMSystemCurrentControlSetServiesNetlogonParametersSiteName
    • HKLMSystemCurrentControlSetServiesNetlogonParametersDynamicSiteName
  2. Source: Domain-joined machine
    Destination: Primary DNS Server
    Connection: UDP
    Port: 53
    Protocol: DNS
    Purpose: DSGetDcName API on domain-joined machine issues a DNS query for the A record of a domain controller from the results of the SRV query. The primary DNS server returns the results of the A record query.

  3. Source: Domain-joined machine
    Destination: Domain Controller
    Connection: UDP
    Port: 389
    Protocol: LDAP
    Purpose: DsGetDcName API on domain-joined machine issues a specially crafted LDAP query (referred to by Microsoft as an LDAP Ping) to the domain controller querying the RootDSE for the NetLogon attribute. The detail query is as follows:

    • Filter: (&(DnsDomain=)(Host=HOSTNAME)(DomainSID=)(DomainGUID=)(NtVer=)(DnsHostName=))
    • Attributes: NetLogon

    The domain controller passes the query to the NetLogon service running on the domain controller which evaluates the query to determine which site the server belongs in. The domain controller returns information about its state and provides the information detailed below (https://msdn.microsoft.com/en-us/library/cc223807.aspx):

    • Flags:
      • DSPDCFLAG – DC is PDC of the domain
      • DSGCFLAG – DC is a GC of the forest
      • DSLDAPFLAG – Server supports an LDAP server
      • DSDSFlag- DC supports a DS and is a domain controller
      • DSKDCFlag DC is running KDC service
      • DSTimeServFlag – DC is running time service
      • DSClosestFlag – DC is in the closest site to the client
      • DSWritableFLag – DC has a writable DS
      • DSGoodTimeServFlag (0) – DC is running time service
      • DSNDNCFlag – DomainName is a non-domain NC serviced by the LDAP server
      • DSSelectSecretDomain6Flag – the server is a not an RODC
      • DSFullSecretDomain6Flag – The server is a writable DC
      • DSWSFlag – The Active Directory Web Service is present on the server
      • DSDNSControllerFlag – DomainControllerName is not a DNS name
      • DSDNSDomainFlag – DomainName is not a DNS name
      • DSDNSForestFlag – DnsForestName is not a DNS name
    • DomainGuid:
    • DnsForestName: contoso.local
    • DnsDomainName: contoso.local
    • DnsHostName: DCSERVER.contoso.local
    • NetbiosDomainName: CONTOSO
    • NetbiosComputerName: DCSERVER
    • Username:
    • DcSiteName: Default-First-Site-Name
    • ClientSiteName: FAKESITE
    • NextClosestSIteName: Default-First-Site-Name

    The client caches this information to its DCLocator cache and will perform another LDAP Ping to another domain controller if it was determined the domain controller is not within the client’s site.

  4. Source: Domain-joined machine
    Destination: Same Site or Closest Site Domain Controller
    Connection: TCP
    Port: 445
    Protocol: SMB
    Purpose: The domain-joined workstation sends an SMB2 NEGOTIATE Request to the domain controller and receives back an SMB2 Negotiate Response. This process allows the machines to agree upon an authentication mechanism. This SMB session will be leveraged through the logon process to communicate with a domain controller’s SYSVOL to process group policy and run any startup scripts.
    Links:

  5. Source: Domain-joined machine
    Destination: Primary DNS Server
    Connection: UDP
    Port: 53
    Protocol: DNS
    Purpose: DsGetDcName API issues a DNS query for an SRV record to the machine’s primary DNS server for a domain controller offering the Kerberos service using the SRV record of _kerberos._tcp.dc._msdcs.contoso.local. The primary DNS server returns the results of the SRV query.

  6. Source: Domain-joined machine
    Destination: Domain Controller
    Connection: UDP
    Port: 389
    Protocol: LDAP
    Purpose: DsGetDcName API on domain-joined machine issues a specially crafted LDAP query (referred to by Microsoft as an LDAP Ping) to the domain controller querying the RootDSE for the NetLogon attribute. The detail query is as follows:

    • Filter: (&(DnsDomain=)(Host=HOSTNAME)(DomainGUID=)(NtVer=)(DnsHostName=))
    • Attributes: NetLogon

    The domain controller passes the query to the NetLogon service running on the domain controller which evaluates the query to determine which site the server belongs in. The domain controller returns information about its state and provides the information detailed below (https://msdn.microsoft.com/en-us/library/cc223807.aspx):

    • Flags
      • DSPDCFLAG – DC is PDC of the domain
      • DSGCFLAG – DC is a GC of the forest
      • DSLDAPFLAG – Server supports an LDAP server
      • DSDSFlag- DC supports a DS and is a domain controller
      • DSKDCFlag DC is running KDC service
      • DSTimeServFlag – DC is running time service
      • DSClosestFlag – DC is in the closest site to the client
      • DSWritableFLag – DC has a writable DS
      • DSGoodTimeServFlag (0) – DC is running time service
      • DSNDNCFlag – DomainName is a non-domain NC serviced by the LDAP server
      • DSSelectSecretDomain6Flag – the server is a notan RODC
      • DSFullSecretDomain6Flag – The server is a writable DC
      • DSWSFlag – The Active Directory Web Service is present on the server
      • DSDNSControllerFlag – DomainControllerName is not a DNS name
      • DSDNSDomainFlag – DomainName is not a DNS name
      • DSDNSForestFlag – DnsForestName is not a DNS name
    • DomainGuid:
    • DnsForestName: contoso.local
    • DnsDomainName: contoso.local
    • DnsHostName: DCSERVER.contoso.local
    • NetbiosDomainName: CONTOSO
    • NetbiosComputerName: DCSERVER
    • Username:
    • DcSiteName: Default-First-Site-Name
    • ClientSiteName: FAKESITE
    • NextClosestSIteName: Default-First-Site-Name

    The client caches this information to its DCLocator cache and will perform another LDAP Ping to another domain controller if it was determined the domain controller is not within the client’s site.

  7. Source: Domain-joined machine
    Destination: Same Site or Closest Site Domain Controller
    Connection: TCP
    Port: 88
    Protocol: Kerberos
    Purpose: The domain-joined machine attempts to verify its identity with the domain controller by sending a KRB-AS-REQ without pre-authentication data. The domain controller checks the object that represents the principal to determine if the account has the “Do not require Kerberos preauthentication.” If the option is not checked, the domain controller returns KRB_ERROR (25) indicating preauthentication data is required.

  8. Source: Domain-joined machine
    Destination: Same Site or Closest Site Domain Controller
    Connection: TCP
    Port: 88
    Protocol: Kerberos
    Purpose: The domain-joined machine re-attempts to verify its identity with the domain controller by sending a KRB-AS-REQ with pre-authentication data. The domain controller validates the principal’s identity and responds with a KRB-AS-REP which includes a Kerberos TGT for the principal to use to obtain additional Kerberos service tickets.

  9. Source: Domain-joined machine
    Destination: Same Site or Closest Site Domain Controller
    Connection: TCP
    Port: 88
    Protocol: Kerberos
    Purpose: The domain-joined machine requests a service ticket for CIFS service running on the domain controller by sending a KRB-TGS-REQ for the CIFS service principal. The domain controller validates the machine’s Kerberos TGT and returns a service ticket for the CIFS service. The domain-joined machine will use the service ticket to authenticate to the SMB service in order to access the SYSVOL share.

  10. Source: Domain-joined machine
    Destination: Same Site or Closest Site Domain Controller
    Connection: TCP
    Port: 88
    Protocol: Kerberos
    Purpose: The domain-joined machine requests a service ticket for CIFS service running on the domain controller by sending a KRB-TGS-REQ for the CIFS service principal name. The domain controller validates the machine’s Kerberos TGT and returns a service ticket for the CIFS service. The domain-joined machine will use the service ticket to authenticate to the SMB service in order to access the SYSVOL share.

  11. Source: Domain-joined machine
    Destination: Same Site or Closest Site Domain Controller
    Connection: TCP
    Port: 88
    Protocol: Kerberos
    Purpose: The domain-joined machine requests a Kerberos TGT by sending a KRB-TGS-REQ for the KRBTGT service principal name. I have to admit, I’m pretty clueless on this one. The only usage I can find online references cross realm.

As you can see, there’s a ton of interesting chatter that only gets more interesting once we begin breaking down the SMB conversation. The SMB portion involved a ton of reading on my end, because I haven’t often done any deep dive troubleshooting into the protocol. As always, I’ll include the links that helped me along the learning path as we cruise through those sections. See you on the next post!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s