0

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

 2 years ago
source link: https://3gstudent.github.io/ProxyShell%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%902-CVE-2021-34523
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

13 Aug 2021

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命令


LEAVE A REPLY


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK