该漏洞利用程序滥用“dccw.exe”管理“WinSxS”的方式,通过一种衍生自 Leo Davidson 的“Bypass UAC”方法,在无需弹出同意提示的情况下获取管理员 shell。它支持“x86”和“x64”架构。此外,它已在 Windows 8.1 9600、Windows 10 14393、Windows 10 15031 和 Windows 10 15062 上成功测试。
如果你想了解如何执行该脚本,请查看使用方法部分。此外,你还可以在Metasploit中执行它,从而获得一个具有管理员权限的 Meterpreter 会话。
要开发一个新的 bypass UAC,首先我们必须找到系统中的一个漏洞,更准确地说,是自动提权(auto-elevate)进程中的漏洞。为了获取此类进程的列表,我们使用了 Sysinternals 的一个名为 Strings 的工具。之后,我们看到了一些自动提权进程,如“sysprep.exe”、“cliconfig.exe”、“inetmgr.exe”、“consent.exe”或“CompMgmtLauncher.exe”,其中一些(有些至今仍然)存在允许执行“bypass UAC”的漏洞。于是,我们开始研究其他自动提权进程是如何与 Sysinternals 的应用程序 Process Monitor(ProcMon)配合工作的,但重点关注“dccw.exe”进程。
然而,在开始使用 ProcMon 之前,我们首先用另一个 Sysinternals 的应用程序 Sigcheck 检查了这些应用程序的清单(manifest),当然,在我们的案例中,“dccw.exe”就是一个自动提权进程。
然后,我们可以开始用 ProcMon 跟踪“dccw.exe”的执行流程,看看是否会发生一些奇怪的现象,我们立即对此进行了检查。在某些情况下,如果我们在 64 位 Windows 机器上以 64 位进程方式执行“dccw.exe”,它会查找目录“C:\Windows\System32\dccw.exe.Local\”来加载一个名为“GdiPlus.dll”的特定 DLL,就像在 32 位 Windows 机器上执行时一样;而如果我们在同一台机器上以 32 位方式执行它,该进程会查找目录“C:\Windows\SysWOW64\dccw.exe.Local\”。然后,由于该目录不存在,进程总会沿着“C:\Windows\WinSxS\”路径查找一个文件夹来获取所需的 DLL,该文件夹的名称具有以下结构:
[architecture]_microsoft.windows.gdiplus_[sequencial_code]_[Windows_version]_none_[sequencial_number]
如果我们查看“WinSxS”目录,会看到不止一个文件夹符合此结构,这意味着“dccw.exe”可以从这些文件夹中的任意一个加载所需的 DLL。我们唯一能确定的是,如果该应用程序以 x86 进程方式被调用,文件夹名称将以字符串“x86”开头;而如果以 x64 进程方式执行,其名称将以字符串“amd64”开头。
这种情况可以被滥用以执行 DLL 劫持,从而在无需弹出同意提示的情况下以高完整性级别执行代码。
一旦我们在自动提权进程的执行过程中发现了一个错误,就需要验证它是否可以被利用。为此,我们只需在目标路径下创建文件夹“dccw.exe.Local”,并在该文件夹中创建位于“WinSxS”中、可能被该进程调用来加载“GdiPlus.dll”的文件夹,但不放置该 DLL。
现在,如果我们执行“dccw.exe”,会看到该进程找到了“dccw.exe.Local”文件夹和其中一个“WinSxS”文件夹,但没有找到所需的 DLL,从而抛出一个错误。这正是我们所预期的,因为正如前面提到的,这种情况可以被攻击者利用。
此时,我们已经知道可以通过滥用“dccw.exe”在 Windows 10 上执行 bypass UAC,但具体怎么做呢?
绕过 UAC 最常用的方法是 Leo Davidson 开发的那种方法。然而,它会执行进程注入来调用 IFileOperation COM 对象,这可能会被某些杀毒软件检测到,因此更好的方法是使用 Cn33liz 在其自身 bypass UAC 中所用的 Masquerade PEB 方法。
此外,在较新的 Windows 10 版本中,我们必须修改调用 IFileOperation 的方式,因为从 build 15002 开始,Leo Davidson 的方法会触发 UAC。因此,我们调用该操作的方式与原始方式相同,但不使用操作标志“FOF_SILENT”、“FOFX_SHOWELEVATIONPROMPT”和“FOF_NOERRORUI”。
在执行漏洞利用程序之前,检查一些方面很重要,以免执行失败并因此触发警报。我们首先检查 Windows 构建版本,因为某些版本不受我们的漏洞利用程序影响(构建版本低于 7600 的那些)。之后,我们确认自己还没有管理员权限,如果已经有,就没有理由执行该脚本了。然后,我们检查 UAC 设置,确认它没有被设置为“始终通知”,因为如果设置为该值,我们的漏洞利用程序将毫无用处。最后,我们验证用户是否属于管理员组,因为如果不是,漏洞利用将无法成功。
在开发漏洞利用程序时,重要的是它能在尽可能多的系统上工作,这包括 32 位 Windows 系统。为实现这一点,我们需要为这类系统编译我们的漏洞利用程序,因为我们也能够在 64 位系统上执行它。
当我们的 32 位漏洞利用程序在 64 位 Windows 机器上执行时,“dccw.exe”的工作方式会略有不同,因为会调用 WOW64(允许 64 位机器运行 32 位应用程序的 Windows 子系统)。这意味着“dccw.exe.Local”文件夹将在“C:\Windows\SysWOW64\”目录中查找,而不是“C:\Windows\System32\”目录,同时目标的“GdiPlus.dll”也将是 32 位 DLL,这意味着它将在名称匹配“C:\Windows\WinSxS\x86_microsoft.windows.gdiplus_*”模式的文件夹中查找。不过,如果它在 32 位 Windows 系统上执行,漏洞利用程序会按预期工作。
最后,需要重点说明的是,在执行 DLL 劫持时,我们需要考虑所有匹配“C:\Windows\WinSxS\x86_microsoft.windows.gdiplus_*”模式的路径,以确保 100% 的有效性。
要以高完整性级别执行进程,我们需要开发一个将通过 DLL 劫持被调用的 DLL。然而,这并不像看起来那么简单,因为如果我们只做这些,无论是“dccw.exe”还是我们的代码都不会被执行。这是因为“dccw.exe”依赖“GdiPlus.dll”的某些函数,所以我们需要将这些函数的执行实现或转发到合法的 DLL。
最好的选择是将执行转发给合法的 DLL,因为这样我们 DLL 的体积会更小。为此,我们使用程序 ExportsToC++ 将“GdiPlus.dll”的所有导出转换为 C++ 语言。现在的问题是“GdiPlus.dll”的导出数量巨大,准确地说有 631 个。不过,“dccw.exe”并不会导入全部导出,而只是少数几个。为了了解“dccw.exe”从“GdiPlus.dll”导入了哪些函数,我们使用“IDA Pro”对其进行了逆向工程。最终,只有 15 个函数是从“GdiPlus.dll”导入的,因此我们只需在 DLL 中包含这些函数即可。
现在,问题似乎已经解决了,但如果我们把执行转发到“C:\Windows\WinSxS\”中特定的“GdiPlus.dll”,该 DLL 只能在部分系统上工作,因为“WinSxS”内部文件夹的名称会随每个 Windows 构建版本而变化。为了克服这个问题,我们想到了将执行转发到“C:\Windows\System32\GdiPlus.dll”的主意,因为该路径在所有 Windows 10 系统中都是相同的。
我们要做的最后一件事是在执行我们的恶意代码后停止“dccw.exe”的运行,以避免该进程的窗口打开。
现在,一旦我们开发了恶意 DLL,就需要将其放置到目标机器上。为此,我们的 DLL 已被压缩并“base64”编码到漏洞利用程序中,以便在运行时解码和解压缩,并按预期将其投放。
最后,我们精心构造的“GdiPlus.dll”会通过前面提到的 IFileOperation COM 对象复制到目标位置。
当攻击者入侵一个系统时,它希望尽可能长时间地不被发现,这意味着要清除它执行的所有操作痕迹。因此,在漏洞利用程序执行期间创建的所有临时文件,在不再需要时都会被删除。
最后,我们需要确定要以高完整性级别执行哪个进程。在我们的案例中,我们选择了应用程序“cmd.exe”,因为一旦我们拥有管理员权限,它就能让我们以高完整性级别执行任意多的操作;但事实上,我们可以执行任何我们想要启动的应用程序。
要执行漏洞利用程序,你必须确保目标机器满足要求。然后,只需像执行其他命令行脚本一样执行漏洞利用程序即可:
C:\Users\L3cr0f> DccwBypassUAC.exe
此 PoC 的 Metasploit 模块使用 DLL 注入而不是 Masquerading PEB,可在以下位置获取:
- Metasploit Framework: https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/local/bypassuac_injection_winsxs.rb开发此漏洞利用程序是为了展示攻击者如何提升系统权限,而不是用于恶意目的。这意味着,如果有人使用它进行犯罪活动,我不承担任何责任。
用户帐户控制(UAC)是随 Windows Vista 引入的一项技术,它提供了一种将标准用户权限和任务与需要管理员访问权限的任务分离的方法。如果标准用户正在使用系统并尝试执行其未经授权的操作,Windows 会弹出提示并要求输入管理员帐户的密码。如果管理员正在使用系统并尝试执行相同的任务,则只会出现一个警告提示。该提示被称为“同意提示”(Consent Prompt),因为管理员只需在继续之前同意该操作即可。允许绕过“同意提示”的弱点不被视为安全漏洞,因为它不被视为安全边界.
然而,微软还表示,“用户帐户控制(UAC)是微软整体安全愿景的基本组成部分”。
来源:
- 安全漏洞的定义。
- 用户帐户控制的工作原理。