Exchange Powershell基于PowerShell Remoting,通常需要在域内主机上访问Exchange Server的80端口,限制较多。本文介绍一种不依赖域内主机发起连接的实现方法,增加适用范围。
注:
该方法在CVE-2022–41040中被修复,修复位置:C:\Program Files\Microsoft\Exchange Server\V15\Bin\Microsoft.Exchange.HttpProxy.Common.dll中的RemoveExplicitLogonFromUrlAbsoluteUri(string absoluteUri, string explicitLogonAddress),如下图
本文将要介绍以下内容:
实现思路
实现细节
常规用法下,使用Exchange Powershell需要注意以下问题:
所有域用户都可以连接Exchange PowerShell
需要在域内主机上发起连接
连接地址需要使用FQDN,不支持IP
常规用法无法在域外发起连接,而我们知道,通过ProxyShell可以从域外发起连接,利用SSRF执行Exchange Powershell
更进一步,在打了ProxyShell的补丁后,支持NTLM认证的SSRF没有取消,我们可以通过NTLM认证再次访问Exchange Powershell
在代码实现上,我们可以加入NTLM认证传入凭据,示例代码:
在执行Exchange Powershell命令时,我们可以选择pypsrp或者Flask,具体细节可参考之前的文章《ProxyShell利用分析2——CVE-2021-34523》和《ProxyShell利用分析3——添加用户和文件写入》
pypsrp或者Flask都是通过建立一个web代理,过滤修改通信数据实现命令执行
为了增加代码的适用范围,这里选择另外一种实现方法:模拟Exchange Powershell的正常通信数据,实现命令执行
可供参考的代码:https://gist.github.com/rskvp93/4e353e709c340cb18185f82dbec30e58
代码使用了Python2,实现了ProxyShell的利用
基于这个代码,改写成支持Python3,功能为通过NTLM认证访问Exchange Powershell执行命令,具体需要注意的细节如下:
1.Python2和Python3在格式化字符存在差异
(1)
Python2下可用的代码:
以上代码在Python3下使用时,需要将Str转为bytes,并且为了避免不可见字符解析的问题,代码结构做了重新设计,Python3可用的代码:
(2)
Python2下可用的代码:
以上代码在Python3下使用时,需要将Str转为bytes,Python3可用的示例代码:
(3)
Python2下可用的代码:
以上代码在Python3下使用时,需要将Str转为bytes,为了避免不可见字符解析的问题,这里不能使用.decode('utf-8'),改为使用.decode('ISO-8859-1')
Python3可用的示例代码:
2.支持Exchange Powershell命令的XML文件格式
XML文件格式示例1:
对应执行的命令为:Get-RoleGroupMember "Organization Management"
XML文件格式示例2:
对应执行的命令为:Get-Mailbox -Identity administrator
通过格式分析,可得出以下结论:
(1)属性Cmd对应命令名称
例如:
(2)传入的命令参数需要注意格式
如果只传入1个参数,对应的格式为:
如果只传入2个参数,对应的格式为:
如果传入4个参数,对应的格式为:
为此,我们可以使用以下代码实现参数填充:
构造XML文件格式的实现代码:
结合以上细节后,我们可以得出最终的实现代码,代码执行结果如下图
本文介绍了远程访问Exchange Powershell的实现方法,优点是不依赖于域内主机上发起连接,该方法在CVE-2022–41040中被修复。
相关阅读: