Windows 提权汇总

0x00 程序LoadLibrary提权

加载DLL一般使用 Loadlibrary(),微软官方建议开发者使用绝对路径进行 DLL 的定位。当LoadLibrary传入相对路径的时候,如LoadLibraryExW(L”\123\123.dll”, 0, 0),实际上并不会从程序目录作为起始目录,而是以根目录作为起始目录,即C盘,又因为C盘根目录进行文件夹创建以及文件写入是不需要高权限的,因此如果程序使用了这种不正确的路径参数,且该程序默认以管理员方式运行,就可以达到提权的效果,结合用做权限维持更好。

典型代表:CVE-2020-3535、CVE-2021-22000。

以 CVE-2021-22000 为例,通过 api monitor 挂钩进程,查找 LoadDLL或者LoadLibrary,找到一个使用相对路径作为参数传递的例子:

可以看到先用 RtlUnicodeStringEx 对 “\DummyTLS\dummyTLS.dll” 进行字符串初始化,然后作为参数传递给 LdrLoadDll,且 LdrLoadDll 的返回结果是 STATUS_DLL_NOT_FOUND。

因此在C盘根目录创建一个文件夹并放入dll:

执行 log_monitor 后会自动弹出 cmd,且权限与执行者一致。

0x01 配置提权

1.1 可信任服务路径

Windows 在解析服务的二进制文件对应的路径时,会将空格作为分隔进行执行。windows 服务的权限通常都较高,当服务目录存在空格时,就有可能利用这个空格做到权限提升。

举例:若有服务的启动路径为 C:\Programs Files\App test\123.exe,此时 Windows 的解析规则为:

C:\Programs.exe —> C:\Program Files\APP.exe —>C:\Programs Files\App test\123.exe,,因此若我们有权限对上述前两个目录进行文件上传,就可以在服务重启时获得高权限。

检查是否存在有缺陷的可信任服务:

wmic service get name,displayname,pathname,startmode|findstr /i "Auto" |findstr /i /v "C:\Windows" |findstr/i /v """

使用最后一个,在C:\Users\Public\Photodex 里新建一个exe叫 ProShow.exe

利用管理员身份重启服务,在 ProcMon 中可以看到 ProShow 被启动:

但是由于它不是服务,进程无法长期存在,因此若作为提权应该配合C2进行快速进程迁移。

1.2 系统服务错误权限配置

Windows系统服务文件在操作系统启动时会加载执行,并且在后台调用可执行文件。比如,JAVA升级程序,每次重启系统时,JAVA升级程序会检测Oracle网站,是否有新版JAVA程序。而类似JAVA程序之类的系统服务程序加载时往往都是运行在系统权限上的。所以如果一个低权限的用户对于此类系统服务调用的可执行文件具有可写的权限,那么就可以将其替换成我们的恶意可执行文件,从而随着系统启动服务而获得系统权限。

一般利用通过 powershell脚本或metasploit中集成。

powerup(https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerUp):

powershell.exe -exec bypass -Command "& {Import-Module .\PowerUp.ps1; Invoke-AllChecks}"

metasploit:

exploit/windows/local/service_permissions

1.3 注册表权限配置错误

在Windows中,和Windows服务有关的信息存储在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services注册表项中,服务对应的程序路径存储在HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Vulnerable Service\服务名\ImagePath,如果低权限用户对这个键值有写权限,那么就可以控制这个服务,运行上传的程序,拿到高权限。

测试一般使用的工具为subinacl,使用方法为:

//检测服务的注册表路径是否有写权限
subinacl.exe /key reg "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Vulnerable Service\服务名" /display
//对有写权限的注册表路径进行修改
reg add "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Vulnerable Service\
服务名" /t REG_EXPAND_SZ /v ImagePath /d "C:\test.exe" /f


0x02 MSI安装权限配置错误

当系统配置 AlwaysInstallElevated 权限时,在系统中使用 Windows Installer 安装任何程序时,该参数允许非特权用户以system权限运行MSI文件。

判断是否启用 AlwaysInstallElevated:

reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated

0x03 计划任务路径权限错误

当普通用户对高权限账户的计划任务调用的应用程序目录有写权限时,可以通过覆盖该,当高权限账户执行计划任务时完成提权。

schtasks /query /fo LIST /v // 查看计划任务
accesschk.exe -dqv "D:\test" -accepteula // 查看该目录是否存在写权限

0x04 漏洞提权

Ascotbe/Kernelhub: Kernel privilege escalation vulnerability collection, with compilation environment, demo GIF map, vulnerability details, executable file (提权漏洞合集) (github.com)

Windows内核漏洞有几种类型,比如堆栈溢出、空指针、内存泄露、UAF等等,经过微软的许多缓解措施,需要漏洞都只有PoC,没有公开的EXP,能做到BSOD但是无法做到提权。

各版本Windows都有自己比较流行的EXP,但近几年问题基本都出现在 Win32k组件上。

Win32k驱动由于微软设计原因,在进行图形化处理时需要处理大量用户层回调,用户层函数是可以Hook的,因此如果在用户层对Hook函数进行处理很可能会影响内核执行流,因此Win32K漏洞UAF的占比很大。

Windows内核漏洞的重点除了漏洞原理,还有漏洞利用,在部分情况下,漏洞利用的难度要远大于发现漏洞。通用的漏洞利用手法一般由两部分组成:内核地址泄露+读写原语构造。

内核地址泄露(通过内核地址泄露获取需要的结构体对象内核地址):Ryze-T/windows_kernel_address_leaks: Examples of leaking Kernel Mode information from User Mode on Windows (github.com)

读写原语构造(通过固定地址写漏洞,利用特殊结构体使用API进而获取任意地址读写权限):

  • Bitmap
  • Palette
  • tagWnd
  • Menu

4.1 Windows7

Windows7属于老版本Windows了,可推荐用的提权漏洞比较多。

CVE-2019-0803

典型的Win32K漏洞,漏洞类型UAF,成因是DDE数据交换时,Server端调用的HmgSetOwner函数没有有效设置GDI对象的状态,导致Client端进程退出时错误的释放了外部GDI对象,造成UAF。

参考链接:[[原创]CVE-2019-0803复现调试笔记-二进制漏洞-看雪论坛-安全社区 安全招聘 bbs.pediy.com](https://bbs.pediy.com/thread-252645.htm)

CVE-2020-0787

属于特权文件操作滥用。存在漏洞的组件为后台智能传输服务模块(BITS)。漏洞可以实现将文件写入受限区域。

利用流程为:

  • 本地创建job进行下载,在tmp文件上设置Oplock
  • 恢复执行后该服务会写入TMP文件触发Oplock
  • 此时切换挂载点到对象目录,创建符号链接,tmp文件指向fake.dll,本地文件指向system32文件夹中的dll
  • 释放Oplock,由于是以System权限进行文件移动,因此会将fake.dll移动到system32文件夹下
  • Update Session Orchestrator service 加载dll完成提权

由于不像堆栈溢出类漏洞会影响内核内存空间,此漏洞可以稳定利用不会蓝屏。

参考链接:CVE-2020-0787-Windows本地提权漏洞分析 - 先知社区 (aliyun.com)

4.2 Windows server 2012

MS16-135

Windows 内核模式驱动程序无法正确处理内存中对象 ,导致存在多个权限提升漏洞

参考链接:【漏洞分析】 CVE-2016-7255:分析挖掘Windows内核提权漏洞 - 安全客,安全资讯平台 (anquanke.com)

4.3 Windows Server 2016

Windows 计划任务调度服务的接口函数(schedsvc!SchRpcSetSecurity())用于修改计划任务相关文件访问控制属性,未验证调用者身份。攻击者可主动调用该接口函数,配合“硬链接(HardLink)”,达到修改指定系统文件访问控制属性的目的。当一些系统服务的关键模块(EXE/DLL)被篡改,再次调用该服务,攻击者的代码将得以执行,且为SYSTEM权限。

参考链接:[技术讨论 Windows全版本提权之Win10系列解析 - FreeBuf网络安全行业门户](https://www.freebuf.com/vuls/184090.html)

4.4 Windows10

1607(14393)

CVE-2021-40449

Win32K 漏洞,漏洞原理为:

在 ResetDC 执行过程中,会执行到 hdcOpenDCW,此函数会进行一次用户模式回调,随后利用原hdcobj进行调用,因此如果hook用户模式回调的函数,在hook代码中再次执行一次 ResetDC,利用堆喷的方法获取到原hdcobj 的内存,就可以控制修改原hdcobj,进而获得一次内核模式下函数调用的机会,利用这次调用的机会,通过 RtlSetAllBits 对 _SEP_TOKEN_PRIVILEGES 进行修改实现的提权。

参考链接:[CVE-2021-40449 Ryze-T Blog](http://ryze-t.com/posts/2021/12/14/CVE-2021-40449.html)

1809(17763)

CVE-2021-1732

Win32k组件漏洞,属于设计缺陷。

流程如下:

对 user32!_xxxClientAllocWindowClassExtraBytes 进行 Hook,调用 win32kfull!NtUserConsoleControl,将 tagWnd->pExtraBytes 改为基于内核桌面堆空间的 offset 寻址模式,然后调用 ntdll!NtCallbackReturn 向内核返回一个能过读写检查的可控值,用于设置 ptagWndk->pExtraBytes,然后调用 setWindowsLong 写附加空间,实现基于内核空间桌面堆基址的可控偏移量越界写。

参考链接:[CVE-2021-1732 for win10-1809 Ryze-T Blog](http://ryze-t.com/posts/2021/10/21/CVE-2021-1732-for-win10-1809.html)

1903(18362)

CVE-2020-0796

SMB内存破坏漏洞。

利用过程如下

  1. 验证程序首先创建到SMS server的会话连接(记为session)。
  2. 验证程序获取自身token数据结构中privilege成员在内核中的地址(记tokenAddr)。
  3. 验证程序通过session发送畸形压缩数据(记为evilData)给SMB server触发漏洞。其中,evilData包含tokenAddr、权限数据、溢出占位数据。
  4. SMS server收到evilData后触发漏洞,并修改tokenAddr地址处的权限数据,从而提升验证程序的权限。
  5. 验证程序获取权限后对winlogon进行控制,来创建system用户shell。

参考链接:Windows SMB Ghost(CVE-2020-0796)漏洞分析 (seebug.org)

1909(18363)

CVE-2021-33739

释放CInteractionTrackerMarshaler对象时,只是清除了objChannel保存的对象数组指针,但是没有清除CInteractionTrackerBindingManagerMarshaler对象指向CInteractionTrackerMarshaler地址的指针,导致UAF漏洞。

参考链接:CVE-2021-33739&CVE-2021-26868 内核漏洞分析 - 安全客,安全资讯平台 (anquanke.com)