ProxyShell 利用分析2——CVE-2021-34523

发布于 2024-08-19 07:20:57 字数 6225 浏览 8 评论 0

0x00 前言

本文将要介绍 ProxyShell 中第二个漏洞的细节,分析利用思路。

0x01 简介

本文将要介绍以下内容:

  • CommonAccessToken
  • Exchange PowerShell Remoting
  • 利用分析

0x02 CommonAccessToken

在上篇文章《ProxyShell 利用分析 1——CVE-2021-34473》提到,我没有找到通过参数指定 EWS 认证用户的方法,但是对于 Exchange PowerShell Remoting,可以通过传入 CommonAccessToken 指定认证用户,访问 Exchange PowerShell Remoting

1.定位参数传入方法

使用 dnsSpy 打开文件 C:\Program Files\Microsoft\Exchange Server\V15\Bin\Microsoft.Exchange.Configuration.RemotePowershellBackendCmdletProxyModule.dll

依次定位到 Microsoft.Exchange.Configuration.RemotePowershellBackendCmdletProxy -> RemotePowershellBackendCmdletProxyModule -> CommonAccessToken CommonAccessTokenFromUrl(string user, Uri requestURI, out Exception ex)

如下图

Alt text

可以看到,通过 X-Rps-CAT 作为参数传入 CommonAccessToken

传递参数的方式可以参考下图

Alt text

2.CommonAccessToken 的生成

使用 dnsSpy 打开文件 C:\Program Files\Microsoft\Exchange Server\V15\Bin\Microsoft.Exchange.Net.dll

依次定位到 Microsoft.Exchange.Security.Authorization -> CommonAccessToken -> Deserialize(Stream stream)

如下图

Alt text

在起始位置下断点

执行命令:

C:\Windows\System32\inetsrv\appcmd list wp

找到 applicationPool:MSExchangePowerShellAppPool 对应的进程 pid

附加到该进程上,等待一段时间,能够捕获到正确的格式

此时,选中 Locals 中的 binaryReader,依次按鼠标右键 -> 选择 Show in Memory Window -> Memory 1,如下图

Alt text

查看该内存区域附近的内容,捕获到了正确的格式,如下图

Alt text

经过分析,捕获的内容结构如下:

V + 版本(\x01\x00) + T + 类型长度(\x07) + 类型(Windows) + C + \x00 + A + 认证类型长度(\x08) + 认证类型(kerberos) + L + 用户名长度 + 用户名 + U + sid 长度 + sid + G + 组个数(4 字节,little endian,\x06\x00\x00\x00) + 分隔符\x07\x00\x00\x00 + 组 1 长度 + 组 1 + 分隔符\x07\x00\x00\x00 + 组 2 长度 + 组 2 + 分隔符\x07\x00\x00\x00 + 组 3 长度 + 组 3 + 分隔符\x07\x00\x00\x00 + 组 4 长度 + 组 4 + 分隔符\x07\x00\x00\x00 + 组 5 长度 + 组 5 + 分隔符\x07\x00\x00\x00 + 组 6 长度 + 组 6 + E + \x00\x00\x00\x00

对于认证类型长度,长度为 1 字节,字节序为 little endian,内容为认证类型的字符串长度,例如认证类型为 basic,那么认证类型长度为\x05

在 Python 代码实现上,计算认证类型长度可以使用如下代码:

authtype = "kerberos"
authlen = (len(authtype)).to_bytes(1, 'little')

经过实际测试,构造 CommonAccessToken 时,有以下技巧:

  • 用户名只要是合法用户即可,可以使用默认邮箱
  • sid 为关键内容,代表认证用户的权限,如果需要认证为管理员用户 Administrator,这里的格式为 S-1-5-domain-500
  • 如果域环境禁用了管理员用户 administrator,仍然能够认证成功
  • group sid 只要是可用的即可,例如随便指定一个 S-1-1-0

关于 sid 的格式可以参考:https://docs.microsoft.com/en-US/windows/security/identity-protection/access-control/security-identifiers

3.CommonAccessToken 的验证

在以正确的方式传入参数 X-Rps-CAT,如果 CommonAccessToken 也有效,那么在访问/Powershell 时会返回状态码 200

0x03 Exchange PowerShell Remoting

参考资料:https://docs.microsoft.com/en-us/powershell/module/exchange/?view=exchange-ps

在之前的文章 《渗透基础——从 Exchange 服务器上搜索和导出邮件》 介绍过 Exchange PowerShell Remoting 的相关用法,这里做一些补充

1.默认设置下,所有域用户都可以连接 remote PowerShell

常用命令:

查看用户是否具有访问 remote PowerShell 的权限:

Get-User -Identity <UserIdentity> | Format-List RemotePowerShellEnabled

列出所有用户是否具有访问 remote PowerShell 的权限:

Get-User -ResultSize unlimited | Format-Table -Auto Name,DisplayName,RemotePowerShellEnabled

列出具有访问 remote PowerShell 权限的用户:

Get-User -ResultSize unlimited -Filter 'RemotePowerShellEnabled -eq $true'

删除指定用户的 remote PowerShell 访问权限:

Set-User -Identity <UserIdentity> -RemotePowerShellEnabled $false

开启指定用户的 remote PowerShell 访问权限:

Set-User -Identity <UserIdentity> -RemotePowerShellEnabled $true

如果想要执行管理 Exchange 服务器的命令,用户需要成为 Organization Management 组的成员

查看 Organization Management 组成员的命令如下:

Get-RoleGroupMember "Organization Management"

2.连接 remote PowerShell 的内置方法

Powershell 示例命令如下:

$User = "test\user1"
$Pass = ConvertTo-SecureString -AsPlainText Password1 -Force
$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $User,$Pass
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exchangeserver.test.com/PowerShell/ -Authentication Kerberos -Credential $Credential
Import-PSSession $Session -AllowClobber
Get-RoleGroupMember "Organization Management"
Remove-PSSession $Session

该方法默认只能从域内主机发起连接,不支持从域外连接

0x04 利用分析

1.CommonAccessToken 的格式

用户 sid 需要设置成 Administrator,默认为 S-1-5-domain-500

这里可以选择其他用户的 sid,但需要满足用户位于"Organization Management"组中

2.使用 PyPSRP 连接 remote PowerShell 的一个问题

使用 PyPSRP 执行 Powershell 命令时,无法执行添加用户的操作

这是因为传递 Password 的值时需要执行 Powershell 命令 convertto-securestring ,而 convertto-securestring 不是 Exchange PowerShell Remoting 支持的命令

如果选择执行 Powershell 脚本,由于默认 Powershell 策略的限制,会提示无法执行 Powershell 脚本

0x05 小结

对于 ProxyShell 中的第二个漏洞 CVE-2021-34523,结合利用思路,不难猜出最简单粗暴的防御方法:将 Organization Management 组内的用户清空,就可以防止攻击者执行高权限的 Exchange Powershell 命令。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

少钕鈤記

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

qq_z5gHLI

文章 0 评论 0

圈圈圆圆圈圈

文章 0 评论 0

alipaysp_h2Vbo4sv6k

文章 0 评论 0

初见你

文章 0 评论 0

清风无影

文章 0 评论 0

云胡

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文