Why Windows Time is bad for Logging and Detection: And How to Fix it

Clark Austin J
6 min readJan 23, 2021

Overview

By default, W32Time, which I will refer to as “Windows Time,” is not accurate enough for log correlation and detection. When designing detections using Sysmon and Windows Event logs, the host performing the local logging uses its own time for the timestamp. The Windows Time Service primary specification was for Kerberos authentication and just had to be with +/- 5 minutes of the Primary Domain Controller (PDC) time. What this has resulted in can be a substantial time skew between hosts. When logs are brought together into a SIEM, an important consideration is “Time.” Many Security Operations Centers (SOC) will have all hosts log in UTC to correlate various logging and alerting sources.

A SOC that uses Suricata or Snort as an Intrusion Detection System (IDS) and logs those alerts to the SIEM and Sysmon logs from their Windows domain expect to perform accurate correlation. This becomes extremely difficult when all of the Windows hosts can be skewed (and still operational) for up to 10 minutes. You may even see certain devices logging in the “future”. In contrast, Chronyd, the newest Linux time service, hardcodes its time limit to only allow up to 3 seconds offset.

Windows Server 2016 / Windows 10 (version 1607+) implements the ability to use “highly accurate time.” This is not enabled or configured out of the box. Microsoft even says in their documentation, not every organization needs highly accurate time. As detection engineers, we most certainly should be concerned about accurate time. How do we ensure the Windows hosts, Linux servers, IDS, and network devices can all have accurate time to correlate?

Choosing an Accurate Time Source

First, determine the outside time source that you want your primary internal NTP server to sync with. You want this to be a Stratum 1 server, as those must be synchronized within milliseconds to a Stratum 0 hardware clock. I’m using the Stratum 1 server provided by a University in Berlin, Physikalisch-Technische Bundesanstalt. They provide one of the few World Atomic Clocks and are known for keeping time well. You also want it to be geographically close to you because network latency plays a large role. Here are the PTB NTP servers.

Configure the Domain Controller as an NTP Server

You’ll need to point the PDC to an outside time source, the one chosen to be your Stratum 1, which will, in turn, make your Domain Controller a Stratum 2 server.

Modify this registry key to change the source NTP servers the domain controller will receive time from:

Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Parameters\NtpServer
Value: ptbtime1.ptb.de,0x1 ptbtime2.ptb.de,0x1 ptbtime3.ptb.de,0x1

Make the PDC an Authoritative Server for non-windows systems.

You can also modify the PDC to be an NTP server for non-windows clients; this is possible because you can configure the system to provide highly accurate time. To do this, modify a few more registry keys, and find the reference to the windows documentation here.

Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Parameters\Type
Value: NTP
Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config\AnnounceFlags
Value: 5
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer\Enabled
Value: 1
Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config\MaxPosPhaseCorrection
Value: 1800 (decimal)

Then run a command to update, restart, and validate w32time with the new config changes:

w32tm /config /update
net stop w32time && net start w32time
w32tm /query /status

Configure the PDC to Provide Highly Accurate Time for every NTP client

Now, make a few important changes to the Windows Time Service, so extreme time drift is less common in your Enterprise environment. The documentation for configuring highly accurate time is here.

Determine what your NTP latency is

See if the system will support highly accurate time by measuring latency because if it is too slow, you won’t be within the supported tolerances, see documentation here.

“The target computer must have better than 0.1 ms of network latency between its time source”

Validate that the network latency is not too high by calculating the average total round trip time. Run this command on the windows 10 client to the domain controller as the NTP server:

w32tm /stripchart /computer:dc.domain.local /rdtsc /samples:450 > c:\temp\Target_TsB.csv

Run this command on the Windows domain controller to the Stratum-1 time source:

w32tm /stripchart /computer:ptbtime1.ptb.de /rdtsc /samples:450 > c:\temp\Target_TsA.csv

Calculate the average in the column “RoundTripDelay.” For B, I got 0.021106824, and for A, I got 0.023619754, which summed together is 0.045, less than .1 ms, and sufficient for a highly accurate time.

Make the Registry Changes necessary for Accurate time.

Configure these registry keys for W32time to provide a more accurate time:

Key: HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Config\MinPollInterval
Value: 6
Key: HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Config\MaxPollInterval
Value: 6
Key: HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Config\UpdateInterval
Value: 100
Key: HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Config\FrequencyCorrectRate
Value: 2
Key: HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient\SpecialPollInterval
Value: 64

Then run the commands to update the config, restart the service and validate the changes:

w32tm /config /update
net stop w32time && net start w32time
w32tm /query /status

Configure Windows 10 Clients

By default, a standalone Windows 10 client will connect to the Microsoft time source: time.windows.com, and a domain-joined client will get time from the domain controller unless it can’t be contacted. On an individual client to see its currently connected time source run this command:

w32tm /query /source

If its currently receiving time from time.windows.com, then run this command to force it back to domain NTP:

w32tm /config /syncfromflags:domhier /update
net stop w32time && net start w32time

If many clients on the domain need to be changed, force them to use the NT5DS (domain) time source and no other. Using the NT5DS time will be as accurate as possible and prevent insecure time configurations because Windows inherently use (S)NTP with Kerberos. You can force all clients in a large enterprise with an NTP Client GPO. See the NTP GPO documentation here. Create a group policy called NTP_Clients and link it to the domain. The NTP client settings are found here: Computer Configuration > Administrative Templates > System > Windows Time Service > Time Providers > Configure Windows NTP Client

Configure these settings in the GPO:

NtpServer: dc.domain.local
Type: NT5DS
CrossSiteSyncFlags: 2
ResolvePeerBackoffMinutes: 15
ResolvePeerBackoffMaxTimes: 7
SpecialPollInterval: 64
EventLogFlags: 0

Also set NTP client to enabled: Computer Configuration > Administrative Templates > System > Windows Time Service > Time Providers> Enable Windows NTP Client

Then perform a “gpupdate /force” on a Windows 10 client to validate it received the GPO changes.

Configure Non-Windows NTP Clients

You may have a setup where you don’t want to run multiple NTP servers or do not have the resources. Now that Windows can provide accurate time usable for all NTP clients, it's possible. This increases the ease in correlation because everything is receiving time from the same source.

Configure Linux Clients

Chronyd has replaced NTPd on RedHat and CentOS systems. You may run this Linux distribution for your open-source IDS software. Chronyd will have issues with a Windows NTP server if it hasn’t been configured to provide the accurate time described above. Chronyd will refuse to use an NTP source if it is over 3 milliseconds off; see here. Modify /etc/chrony.conf and add this line with the domain controller FQDN:

server dc.domain.com prefer

Restart the Chrony service: systemctl restart chronyd

Configure Cisco Network Devices

Network devices can vary in how they are configured as NTP clients, but a common Cisco way is with the following commands:

enable
configure terminal
ntp server dc.domain.com prefer
exit
write memory

Closing Thoughts

After your NTP servers are configured and NTP clients on a tolerant offset, modify the firewall to block rogue NTP servers. Only allow the authorized NTP server to communicate out over port 123 to the designated Stratum-1 time source. Then review your firewall logs in the SIEM to identify rogue devices you may not have been accounting for. This will help you perform Identify and know the devices on your network better. Everything needs NTP, and it's even prevalent to see it hardcoded on IoT devices. Block port 123 outbound on your home network, and things will certainly break. For me, my Chromecast, AV Reciever, and AppleTV all stopped functioning without communicating to their respective NTP time sources.

May your detections be accurate and your time be in sync, and configured to UTC. Happy correlating!

--

--