Some notes about Microsoft Exchange Deserialization RCE (CVE-2021–42321)

INTRO

https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-42321
https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-42321
https://www.catalog.update.microsoft.com/Search.aspx?q=Exchange%202016

THE SINK

Microsoft.Exchange.Compliance.Serialization.Formatters.TypedBinaryFormatter
Microsoft.Exchange.Diagnostics.ExchangeBinaryFormatterFactory.CreateBinaryFormatter()
  • strictMode = false
  • allowList = System.DelegateSerializationHolder
  • allowedGenerics = null
ChainedSerializationBinder.BindToType()
ChainedSerializationBinder.ValidateTypeToDeserialize()
  • If the strictMode is False and our class is not in allow list, and in blacklist , Exchange will throw InvalidOperationException
  • In this function, it only catches BlockedDeserializationException so InvalidOperationException will not be caught, so if Exchange through InvalidOperationException our deserialization chain will be broken
  • If there’s a BlockedDeserializationException while ValidateTypeToDeserialize() was thrown, it will be caught in catch block but Exchange only throws that Exception when the value of the flag is True, but remembered that the strictMode value was passed to ChainedSerializationBinder is always False ! So there’s Exchange will catch BlockedDeserializationException safely and Exchange didn’t affect our Deserialization can continue without crashing.
System.Security.Claims.ClaimsPrincipal.OnDeserializedMethod()
System.Security.Claims.ClaimsPrincipal.DeserializeIdentities()
BinaryFormatter.Deserialize()

THE SOURCE

CreateUserConfiguration.Execute()
UserConfigurationCommandBase.SetProperties()
UserConfigurationCommandBase.SetStream()
UserConfigurationCommandBase.SetProperties()
UserConfigurationCommandBase.SetStream()
sample request for setting BinaryData
sample request for GetClientAccessToken

FULL EXPLOIT

  1. Create UserConfiguration with BinaryData as our Gadget Chain
  2. Request to EWS for GetClientAccessToken to trigger the Deserialization
  • We can embed any ysoserial.net gadget chain into System.Security.Claims.ClaimsPrincipal to trigger 2nd Deserialization
  • Or we can use directly use TypeConfusedDelegate Chain (This chain is not in the blacklist of ChainedSerializationBinder and I don’t know why :> )

IMPROVEMENT

This is what we got :)
A snippet of code to eval JScript
We’ve been laughing for hours while making this meme
This is how we call Process.Start()
from TypeConfusedDelegate -> XamlReader.Parse()

Final Thought

  • Microsoft Exchange 2019 CU10, 11
  • Microsoft Exchange 2016 CU21, 22

Nub-boi

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Honest thoughts on my ongoing coding journey

When to use AWS Credentials

5 Tips for Successful Software Outsourcing

KubeCon Day 0 Recap — AWS Container Day

Leetcode 1. Two Sum in python

Hugo Tranquilpeak Gitlab

Podcast: AIOps. What is it?

Demystifying DSLs Part 1: Time is of the Essence

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Peterjson

Peterjson

Nub-boi

More from Medium

Photographer Box Writeup

GAARA — Offensive Security PG Play

Timing-Based Username Enumeration: What’s a fix versus mitigation?

Basic_Pentesting_1 VulnHub