利用 VPN — 探讨 VPN 后利用技术
执行摘要
在本博文中,Akamai 研究人员将重点介绍通常被忽视的 VPN 后利用威胁。也就是,我们将探讨攻击者在入侵 VPN 服务器后可以利用哪些技术来进一步扩大入侵。
我们的发现包括影响 Ivanti Connect Secure 和 FortiGate VPN 的几个漏洞。
除了这些漏洞,我们还将详细介绍一套可能影响 Ivanti Connect Secure 和 FortiGate 产品以及其他 VPN 服务器的攻击手段,目前尚无修复方法。
我们的研究表明,在许多情况下,攻击者可以通过利用已入侵的 VPN 服务器来轻松控制网络中的其他关键资产。
本博文意在提高人们对这些风险的认识,并说明了防御者应该采取哪些最佳做法来尽可能降低 VPN 后利用技术的风险。
简介
我们以前都听过这样的故事:某个 VPN 服务器中发现一个严重漏洞,该漏洞被攻击者广泛利用,管理员急于修补,恐慌情绪在社交媒体上蔓延。
对于 VPN 安全领域来说,去年是相当艰难的一年,似乎 每隔 一个 月 就有严重漏洞被修补或发现,而且都是在遭到攻击者广泛利用后。尽管此类活动在 2023 年显著增加,但并不是什么新鲜事。攻击者长期以来一直在寻求利用 VPN 服务器,因为 VPN 服务器可以通过互联网访问,有着丰富的攻击面,并且通常缺乏安全和监控措施。
在过去,攻击者滥用 VPN 服务器基本上是为了实现一个目的,即获取初始访问权限。攻击者会入侵面向互联网的 VPN 服务器,并将其作为进入内部网络的滩头阵地来实施进一步的入侵。
虽然这种方法非常有效,但我们不禁想问:控制 VPN 服务器只是作为进入内部网络的敲门砖吗?
我们想看看还有没有别的可能性。
以下博文内容将探讨 VPN 后利用技术,攻击者在通过其他手段(利用漏洞、被盗凭据等)入侵 VPN 服务器后,可能会利用这些技术来实现其他目的。
利用 VPN
攻击者用来实施后利用技术的主要手段是 攻击设备的操作系统。获得远程代码执行 (RCE) 权限后,攻击者可以向设备操作系统投放自定义植入程序。然后,攻击者就可以控制 VPN 的各个方面;例如,可以利用钩子函数来泄露敏感信息、通过操纵日志来逃避检测或者修改系统配置来确保长期存在于设备上。
虽然这种方法有很多优点,但也有一个主要缺点,也就是成本高昂。由于 VPN 设备通常运行经过加固的自定义操作系统,因此开发和维护针对 VPN 设备的自定义植入程序所需的工作量可能很大。这意味着通常只有顶级的民族国家攻击者才会使用 VPN 后利用技术。
探索其他方法
我们决定探索其他方法,寻找一种“更简单”的 VPN 后利用技术。与其依赖于在操作系统中运行自定义植入程序,不如对设备的现有功能进行滥用。我们开始思考:在只使用 VPN 管理接口的情况下,攻击者可以做什么?
这种方法我们称之为“利用 VPN”,它至少有两个优点。
相比完整的 RCE 权限,此类访问权限更容易获得,可以通过身份验证绕过漏洞、安全系数低的凭据或网络钓鱼获得对管理接口的访问权限。
这种方法更具成本效益,因为避免了在开发自定义攻击载荷上的投入。
我们选择市面上的两款主流 VPN 服务器(Ivanti Connect Secure 和 FortiGate)作为测试对象。我们发现了两个 CVE 和一套目前尚无修复方法的攻击手段,攻击者在控制 VPN 服务器后可能会利用这些手段来接管网络中的其他关键资产,从而 可能使 VPN 入侵进一步演化为整个网络的入侵。
虽然我们的研究结果主要针对 FortiGate 和 Ivanti,但我们认为已发现的这些技术经过演变后可能会威胁其他 VPN 服务器和边缘设备。
滥用远程身份验证服务器
在 VPN 服务器处理的资产中,外部凭据最值得关注。尽管 VPN 服务器支持使用本地用户数据进行身份验证,但很多情况下会使用外部身份验证服务器。
管理员可以选择使用现有的身份提供方来验证用户身份,而不是为每个用户保存一组单独的凭据。用户将其“常用”凭据发送到 VPN 服务器,然后远程身份验证服务器会对这些凭据进行验证(图 1)。
有几种类型的身份验证服务器可用于此目的,LDAP 和 RADIUS 是其中的两种主要选项。
我们发现攻击者可以通过一些技术利用这种身份验证方式来窃取这些外部凭据,从而让攻击者获得对网络中其他资源的访问权限。
拦截 LDAP 凭据
一种常用于 VPN 的身份验证服务器选项是 LDAP,最常见的是 Active Directory (AD) 域控制器。在这种配置下,用户可以使用自己的域凭据访问 VPN,这样操作非常方便。
在配置 LDAP 身份验证服务器时,需要提供 AD 服务帐户的凭据以允许 VPN 查询用户信息。FortiGate 中该配置的示例如图 2 所示。
当用户尝试使用 LDAP 凭据向 FortiGate 或 Ivanti 进行身份验证时,VPN 会联系 LDAP 服务器来验证用户身份。这两者的具体实现略有不同,下面我们来逐一探讨。
FortiGate LDAP 身份验证
为了验证凭据,FortiGate 会尝试使用凭据向远程服务器进行身份验证。此过程使用 简单身份验证 执行,也就是说 FortiGate 以明文形式将密码发送到服务器 (图 3)。
在此过程中,将传输两组凭据:FortiGate 上配置的 LDAP 服务帐户的凭据,以及进行身份验证的用户提供的凭据。两组凭据均以明文形式发送。
虽然默认配置是 LDAP,但 FortiGate 也支持 LDAPS 和 TLS,这应该可以防止明文通信。
Ivanti LDAP 身份验证
Ivanti 的 LDAP 身份验证实现方式略有不同,它支持两种类型的 LDAP 身份验证服务器:标准 LDAP 和 Active Directory(图 4)。
LDAP 身份验证服务器
使用 LDAP 身份验证服务器时,过程与 FortiGate 的验证过程非常相似;换句话说,在使用非加密 LDAP 时,将执行简单绑定,AD 服务帐户和用户身份验证凭据都以明文形式传输(图 5)。
但是,在配置 LDAP 身份验证服务器时,默认设置是 TLS,并且也支持 LDAPS。因此,Ivanti 实例不太可能使用非加密 LDAP。
AD 身份验证服务器
第二种可以配置的 LDAP 身份验证服务器是 AD 服务器。选择该选项时,将使用 Kerberos 进行身份验证,意味着不会传输任何密码(图 6)。
捕获明文形式的 LDAP 凭据
对于 FortiGate 和 Ivanti,在使用明文 LDAP 对用户进行身份验证时,发送到 VPN 的任何凭据都可能会被窃取。位于 VPN 和 LDAP 服务器之间的攻击者或控制了 VPN 服务器的攻击者都可以窃取这些凭据。
如何在不向设备投放植入程序的情况下捕获凭据?凑巧的是,FortiGate 和 Ivanti 都包含内置的数据包捕获功能。通过使用该功能捕获 LDAP 数据包,攻击者可以拦截所有经过 VPN 传输的凭据(图 7)。
在使用安全协议的情况下,不会从服务器发送任何明文凭据。尽管如此,控制了 VPN 的攻击者仍然可以轻松捕获这些凭据。 因为只要控制了 VPN,就可以直接修改配置,降级为使用明文 LDAP。
对于标准 LDAP 服务器,我们可以直接将配置更改为明文 LDAP。要想对 Ivanti 的 AD 服务器进行降级,我们可以使用 AD 连接的详细信息配置新的标准 LDAP 服务器来代替现有服务器。在两种情况下,这种更改对用户来说应该都是不可见的,因此会导致 VPN 以明文形式发送密码。
最终结论是,如果使用 LDAP 身份验证,无论配置如何,攻击者只要入侵了 VPN 就能够轻松获取凭据并进入该域。
注册恶意身份验证服务器
我们前面提到,在对远程用户进行身份验证时,VPN 将联系相应的身份验证服务器来验证用户提供的凭据。我们发现了一种方法可以对此身份验证流程进行滥用以窃取 用户向 VPN 提供的任何凭据 。
此技术的原理是注册一个恶意身份验证服务器供 VPN 在验证用户身份时使用。为便于您理解此技术的具体实施方式,我们先介绍这两种 VPN 上的身份验证过程的一些细节。
FortiGate 用户组
对于 FortiGate 用户,可以向他们授予不同的权限以及应用不同的策略。可以将用户添加到用户组中,而无需单独管理每个用户。换句话说,可以向多组用户应用策略和权限。
在配置用户组时,我们可以包含远程组(远程身份验证服务器上的组)中的用户。例如,我们可以包含特定 AD 组中的用户(图 8)。
我们观察到,在使用远程组时会发生一个值得关注的行为。假设我们配置的用户组包含两个实体:一个本地 FortiGate 用户和 LDAP 服务器上的一个远程组。
就身份验证而言,我们期望的行为如下:
当组中的本地成员向 FortiGate 进行验证身份时,系统将使用 FortiGate 的本地用户数据库来验证他们的凭据。
当远程组的成员向 FortiGate 进行验证身份时,系统将使用远程组 LDAP 服务器来验证他们的凭据。
但结果证明, 事实并非如此。 在我们将远程组添加到用户组后,每当用户组的 任何 成员验证身份时,FortiGate 都会尝试同时使用本地用户数据库 和 远程身份验证服务器来验证用户的凭据。此外,如果我们向用户组添加了多个远程服务器,FortiGate 在验证用户身份时将尝试使用 所有已配置的身份验证服务器。
这就是说,FortiGate 不会将特定的用户与相应的身份验证方法相匹配,而是会尝试所有方法。如果任何方法成功,表示用户通过了身份验证。
Ivanti 身份验证领域
Ivanti 为用户组实施了类似的功能,称为 身份验证领域。与 FortiGate 的用户组不同,每个 Ivanti 身份验证领域只使用一个身份验证服务器。要管理来自不同服务器的用户,必须使用单独的领域。
尽管有此限制(对我们来说很方便),但 Ivanti 还允许配置“附加身份验证服务器”(图 9)。该选项的本意是为了支持某些 SSO 配置。
配置了附加身份验证服务器后,Ivanti 将尝试使用两个服务器来验证凭据。只有 两个 服务器都批准了凭据,身份验证才会成功。
创建恶意身份验证服务器来泄露凭据
攻击者可以滥用这些行为来泄露使用任何类型的远程身份验证服务器向 FortiGate 或 Ivanti 进行身份验证的任何用户的凭据。通过向用户组或领域添加恶意身份验证服务器,我们可以让 VPN 服务器将凭据泄露给攻击者控制的服务器(图 10)。
这些凭据可能是连接到 VPN 的客户端的凭据,也可能是连接到管理接口的管理员的凭据。 可以使用这种方法来劫持任何通过用户组或领域进行管理的身份验证。
为了对 FortiGate 实施这种方法,我们创建了一个使用恶意服务器的远程组,然后将该远程组添加到目标用户组中。对于 Ivanti,我们只需将恶意服务器添加为目标领域的附加身份验证服务器即可。
现在,只要目标用户组/领域的成员进行身份验证,VPN 就会尝试使用我们的服务器来验证用户凭据(图 11)。
为了捕获凭据,我们将使用 RADIUS 身份验证服务器。在这种情况下,RADIUS 身份验证很方便,原因有两个:
凭据是在初始请求期间发送到服务器的,而不会先验证用户是否存在于服务器上。
凭据使用由攻击者确定的密钥加密后发送到服务器,以便于攻击者将其恢复为明文凭据(图 12)。
以下脚本(基于 RFC 2865)可以解密 RADIUS 密码:
import hashlib
# Authenticator value can be obtained from the PCAP
authenticator = bytearray.fromhex("98f245b6e3724f5873fa74e576323c67")
enc = bytearray.fromhex("15644ca055b817ce683083fecebc2902016f2890660d0dfcaee214a0dbaa1046")
# Pre-shared key configured by the attacker when setting up the rogue server
secret = bytes("verygoodpsk", "utf-8")
chunk_len = 16
enc_chunks = []
dec = ""
for i in range(0, len(enc), chunk_len):
enc_chunks.append(enc[i:i+chunk_len])
for chunk in enc_chunks:
dec_chunk = b""
chunk_key = hashlib.md5(secret + authenticator ).digest()
i = 0
for enc_byte in chunk:
dec_chunk += (enc_byte ^ chunk_key[i]).to_bytes(1,"big")
dec += chr(enc_byte ^ chunk_key[i])
i+=1
authenticator = chunk
print(dec)
最后一点:我们前面提到,当 Ivanti 使用附加身份验证服务器时, 两个 服务器都需要批准用户的凭据,身份验证才会成功。如果我们的服务器不批准用户提供的凭据,用户将无法完成向 Ivanti 的身份验证。为了避免发生这种情况,我们需要确保 RADIUS 服务器批准用户提供的任何凭据,这很容易通过配置来实现。
提取配置文件机密信息
最令我们担忧的发现涉及 VPN 配置文件。
在配置文件中,我们可以找到许多重要的设置,其中最引人关注的是机密信息。VPN 会在其配置中存储很多机密信息,包括本地用户密码、SSH 密钥、证书,甚至第三方服务帐户的凭据。
攻击者可以通过两种主要方式获得这些敏感信息:
在获得 VPN 控制权后,攻击者可以通过管理接口导出设备配置。
他们可以找到以前导出的配置文件,这些文件通常保存在共享文件夹等公共位置中。
为了避免泄露,这些机密信息会以加密形式存储在配置文件中。图 13 显示 FortiGate 配置文件中已加密信息的示例。
现在,我们来解密这些机密信息!
解密 FortiGate 配置文件中的机密信息
有人可能会认为这些机密信息已经过散列处理,所以无法恢复,但事实并非如此。我们以集成密码为例,由于连接到第三方需要明文密码,因此在存储时必须使用可逆加密方法。
这一点在 Bart Dopheide 所撰写的一篇深入研究 FortiGate 密码加密 过程的博文中得到了证实。FortiGate 使用 AES 对配置中的所有机密信息进行加密。执行加密时使用什么密钥?Dopheide 发现,所有 FortiGate 设备都使用 一个硬编码密钥 。该密钥无法更改。原博文中未分享该密钥,但通过 Google 搜索可以快速找到它。
Fortinet 为该问题分配了 CVE 编号 CVE 2019–6693 ,并提供了 修复方法, 就是允许用户将硬编码密钥更改为自定义密钥。
甚至在实施修复后,该问题现在仍然有价值。如果未更改密钥,那么 默认情况下,FortiGate 设备仍然使用之前的密钥。 这意味着,如果攻击者获得了采用默认配置的 FortiGate 设备的配置文件,他们将能够解密设备上存储的所有机密信息。 该代码 可以实现解密过程。
但是,如果 FortiGate 管理员采用了最佳实践,将默认密钥更改为自定义密钥,又会怎么样?我们发现,如果控制了 VPN,仍然可以轻松获取这些机密信息。
设备配置中使用 private-data-encryption 设置来控制自定义加密密钥。但令人意外的是,管理员可以直接禁用该设置。这样做 不需要知道当前配置的密钥,而且会将所有机密信息的加密密钥恢复为原始的硬编码密钥。
恢复原始加密密钥
要恢复原始加密密钥,我们可以使用以下 FortiGate 命令行界面命令:
FGT # config system global
FGT (global) # set private-data-encryption disable
FGT (global) # end
这时候,我们可以下载配置文件并使用已知的默认密钥对机密信息进行解密(方法与前面展示的一样)。
使用这种方法可以窃取很多有价值的机密信息。FortiGate 通过“外部连接器”功能支持与各种应用程序进行集成。这些连接器有多种用途,但大多数都有一个重要的共同点,也就是它们需要应用程序的凭据(图 14)。
这意味着 FortiGate 可能存储了云提供商、SAP、Kubernetes、ESXi 等关键服务的凭据。
在某些情况下,这些凭据需要相关应用程序的高级权限。例如,“Poll Active Directory Server”集成 需要具有域控制器管理权限的帐户的凭据,这可能造成攻击者入侵 FortiGate 后直接入侵整个域。
解密 Ivanti 配置文件中的机密信息
Ivanti 的情况非常相似。实际上,甚至可能更糟。
Ivanti 也使用可逆加密方法来存储机密信息。我们从设备中提取代码并进行深入研究,很快便找到了用作加密密钥的密文,它同样是一个静态字符串(图 15)。
我们并未展示完整密钥,但通过查看密钥的开头部分,可以推断至少从 2015 年(当时 Connect Secure 还属于 Juniper 所有)到现在,该密钥可能都未更改过。
Ivanti 似乎在保护存储的机密信息方面付出了更大的努力,实施的加密算法比 FortiGate 更复杂。尽管如此,其加密过程显然还是可逆的。也就是说 所有 Ivanti 实例中的机密信息都使用一个无法更改的静态密钥进行加密。只要知道了这个密钥,攻击者就 可以对任何 Ivanti 配置文件进行解密。
让 Ivanti 为我们进行密码解密
我们最初的方法是对加密过程进行逆向工程来创建解密器。这自然是可行的,但在花了几个小时查看反编译代码后,我们决定采用另一种方法以进行概念验证。我们让 Ivanti 来完成这项繁重的工作。
此方法的主要思路是利用攻击者控制的专用 Ivanti 实例,通过“提供”加密的密码来让其完成解密工作(图 16)。
该解密过程可通过以下步骤完成:
从 Ivanti 配置文件中获取加密的密码
在实验室环境中,设置 Ivanti 实例和 LDAP 服务器(例如,运行 Active Directory 的 Windows 服务器)
在实验性 Ivanti 实例上,将 LDAP 服务器配置为使用简单身份验证的身份验证服务器
将实验性 Ivanti 配置导出到文件中
将配置文件中现有的已加密 LDAP 密码替换为我们尝试解密的密码
将修改后的配置文件重新导入 Ivanti 实例中
现在,如果我们向 LDAP 服务器发起身份验证尝试,Ivanti 将对配置中的密码进行解密并以明文形式发送到 LDAP 服务器。通过捕获数据包,我们便获得了已解密的密码(图 17)。
我们使用了 LDAP 服务器身份验证作为解密过程的“接口”,但需要注意的是,这种方法并不局限于 LDAP 密码。我们的测试表明,此技术 适用于存储在配置文件中的所有机密信息, 包括(但不限于)AD 密码、RADIUS 预共享密钥和 API 密钥。
MDM 服务器的明文密码
Ivanti 支持使用一些常用的移动设备管理 (MDM) 服务器作为身份验证方法(图 18)。
与其他身份验证服务器一样,此集成也需要 MDM 服务器的凭据。检查 MDM 服务器的配置时,我们发现了两个值得关注的字段:“password-encrypted”和“password-cleartext”。尽管名称有所暗示,但这两个字段的值都以明文形式存储(图 19)。♂️
广泛利用的 VPN 后利用技术
我们在本文中介绍的一些技术很可能已遭到了攻击者的广泛利用。Mandiant 研究人员在他们的 《Cutting Edge》 报告中介绍了一系列针对 Ivanti 设备的攻击活动,并提到攻击者能够窃取 Ivanti 设备上配置的 LDAP 服务帐户(图 20)。
尽管 Mandiant 的报告没有详细说明攻击者如何能够窃取帐户,但我们认为 攻击者很有可能使用本文中介绍的方法之一获取了凭据, 也就是说攻击者要么从配置文件中提取了凭据信息,要么通过嗅探网络流量获取了这些信息。
这些类型的技术很容易实现,并且我们相信各种熟练程度的攻击者都能够使用它们。
关于使用 VPN 服务器时的建议
为了尽可能降低我们所介绍的技术带来的风险,我们建议在使用 VPN 服务器时遵循以下四个原则:
采用 Zero Trust Network Access 技术
限制服务帐户权限
使用专用身份进行 VPN 身份验证
监控配置更改
1.采用 Zero Trust Network Access 技术
传统 VPN 的一个主要问题是在授予网络访问权限时采用了“全有或全无”方法,用户只要可以进入网络,就可以访问整个网络,而如果无权进入网络,便无法访问任何内容。
这两种选项都有问题。一方面,我们必须为用户提供内部应用程序的远程访问权限。另一方面,我们又不希望攻击者在入侵 VPN 服务器后获得整个网络的完整访问权限。
Zero Trust Network Access(ZTNA) 提供了解决办法。通过按照实体来定义网络访问策略,我们可以在允许用户执行已批准的远程操作的同时,降低潜在入侵的影响。
Akamai Enterprise Application Access 是一种 ZTNA 解决方案,可精准地根据用户身份和情境提供对私有应用程序的访问权限。该解决方案使用基于身份的策略和实时数据(例如,用户位置、时间和设备安全)来确保用户只能访问所需要的应用程序,并且消除了网络级访问权限。它可与 Akamai MFA 无缝搭配使用,以实现强用户身份验证。
2.限制服务帐户权限
正如我们在这篇博文中所述,要恢复存储在 VPN 服务器上的服务帐户的明文密码很容易。目前没有什么办法可以避免这种情况,因为 VPN 在某些情况下需要使用明文密码。
为了降低 VPN 遭到入侵的潜在影响,我们建议使用具有有限权限(最好是只读权限)的服务帐户。防御者应该尽量了解攻击者如何利用 VPN 上存储的凭据,并确保 VPN 遭到入侵不会导致其他关键资产遭到入侵。
某些集成需要具有高级权限的服务帐户才能运行。在可能的情况下,应避免使用这类集成。
3.使用专用身份进行 VPN 身份验证
现在我们知道,对于控制了 VPN 的攻击者来说,窃取 VPN 用户的身份验证凭据非常容易。虽然使用现有的身份验证服务(例如 AD)向 VPN 进行用户身份验证可能很方便,但我们建议不要这样做。控制了 VPN 的攻击者将能够窃取凭据并使用它们侵入内部资产,从而导致 VPN 成为单点故障。
我们建议使用单独、专用的身份验证方法向 VPN 进行用户身份验证。例如,使用专门为身份验证而颁发的证书来执行基于证书的身份验证。
4.监控配置更改
本文中介绍的技术都会以某种形式反映在设备配置中。网络设备配置通常不会频繁更改,所以此类更改提供了重要的检测机会。
为了识别配置更改,我们建议定期提取设备配置并与预配置的虚拟机模板 (Golden Image) 进行比较。大多数设备还提供了系统和安全事件的内部日志记录功能。我们建议收集和分析所有可用的日志,并使用它们来识别对设备配置的可疑更改。
这四个原则可以归结为一点:不要盲目信任 VPN。
总结
攻击者始终都觊觎着 VPN。这是事实。防御者应该认识到,攻击者获得 VPN 访问权限只是时间问题,现在就应该开始采取有效的应对措施。防御者一定要确保 VPN 遭到入侵不会导致整个网络遭到入侵。
披露时间表
Ivanti
2024 年 3 月 26 日:向供应商提供初始报告
2024 年 4 月 5 日:Ivanti 确认收到报告并已经着手修复
2024 年 6 月 3日:向 Ivanti 发出关于我们预定 8 月 7 日发布研究结果的初始通知
2024 年 6 月 27 日:Ivanti 表示正在尝试修复,但无法确认能否在发布日期前完成问题修复
2024 年 7 月 8 日:Ivanti 为硬编码密钥问题和 MDM 明文密码问题分别分配了 CVE 编号 CVE-2024-37374 和 CVE-2024-37375,但尚未发布补丁
2024 年 7 月 15 日:向 Ivanti 发出关于预定发布时间的附加通知
2024 年 8 月 7 日:发布研究结果
Fortinet
2024 年 3 月 22 日:向供应商提供初始报告
2024 年 4 月 17 日:Fortinet 初步回应,认为报告所述问题不需要修复
2024 年 4 月 21日:向 Fortinet 发出关于我们预定 8 月 7 日发布研究结果的初始通知
2024 年 4 月 30 日:Fortinet 表示打算修复自定义加密密钥绕过问题
2024 年 7 月 15 日:向 Fortinet 发出关于预定发布时间的附加通知
2024 年 7 月 23 日:Fortinet 表示可能无法在研究结果发布日期前发布补丁
2024 年 8 月 2 日:Fortinet 表示,经过进一步考虑,他们决定不修复自定义加密密钥绕过问题,因为该问题“未跨越安全边界”
2024 年 8 月 7 日:发布研究结果