0x00 Preface
---
In the previous article 'Penetration Techniques - From Exchange File Read/Write Permissions to Command Execution', we introduced the method of achieving command execution from Exchange file read/write permissions through .Net deserialization of ViewState, sharing development details of three exploitation scripts. This article will specifically analyze the details of generating ViewState and introduce another script development detail for achieving command execution from Exchange file read/write permissions.
References:
http://www.zcgonvh.com/post/weaponizing_CVE-2020-0688_and_about_dotnet_deserialize_vulnerability.html
https://github.com/pwntester/ysoserial.net
0x01 Introduction
---
This article will cover the following:
- Two implementation methods for generating ViewState
- Details of another exploitation script development
- Open-source code
0x02 Background Knowledge
---
1. Implementation Principle of DotNet ViewState Deserialization
If the content of the web.config file can be read to obtain the encryption key and algorithm, valid serialized data can be constructed. If the serialized data is set as a malicious delegate, remote code execution can be achieved when ViewState uses ObjectStateFormatter for deserialization to invoke the delegate.
2. ViewState Generation Process
Using validationkey and generator as parameters, sign the serialized xaml data, place it after the serialized xaml data, and then perform Base64 encoding to form the final ViewState content.
Intuitive understanding:
data = Serialize(xaml) |
For encryption details, refer to:
https://github.com/pwntester/ysoserial.net/blob/master/ysoserial/Plugins/ViewStatePlugin.cs#L255
https://github.com/0xacb/viewgen/blob/master/viewgen#L156
Specific details can be examined by decompiling System.Web.dll using dnSpy, locating the GetEncodedData function in System.Web.Configuration.MachineKeySection.
0x03 Two Implementation Methods for Generating ViewState
---
Test Environment:
Obtained Exchange file read/write permissions, enabling modification of %ExchangeInstallPath%\FrontEnd\HttpProxy\owa\web.config and %ExchangeInstallPath%\FrontEnd\HttpProxy\ecp\web.config, setting the machineKey content as follows:
For .NET deserialization command execution at these two locations, legitimate user credentials are no longer required
The following introduces two programmatic methods for generating ViewState
1. Generating ViewState from XAML data
Process is as follows:
- Construct XAML data
- Generate serialized XAML data
- Generate signature data
- Concatenate serialized XAML data and signature data, then perform Base64 encoding
(1) Constructing XAML data
Four types are introduced here, corresponding to four functionalities respectively
Execute command:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
Write file:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
Note:
Pay attention to XAML escape characters
Set Header:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
Set Response:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
(2) Generate serialized XAML data
Requires Microsoft.PowerShell.Editor.dll
(3) Generate signature data
Reference code:
byte[] validationKey = strToToHexByte(key); |
Note:
Code modified from https://github.com/zcgonvh/CVE-2020-0688/blob/master/ExchangeCmd.cs#L253
(4) Concatenate serialized XAML data and signature data, then perform Base64 encoding
Simply call Convert.ToBase64String()
Complete implementation code has been uploaded to GitHub, address as follows:
An open-source project
The code can read XAML files, compute signatures using validationkey and generator, and generate the final ViewState
Advantages:
Clear process, easy to debug and modify details
Disadvantages:
Requires dependency on the intermediate file Microsoft.PowerShell.Editor.dll, occupying space
Note:
The complete exploitation files for this method have been packaged and uploaded to GitHub, address as follows:
An open-source project
2. Generate ViewState from serialized XAML data
Utilize ysoserial.net to skip the step from XAML data to serialized XAML data, improving development efficiency
Process as follows:
(1) Modify the ysoserial.net source code to directly read usable serialized XAML data
Add the following code at https://github.com/pwntester/ysoserial.net/blob/master/ysoserial/Plugins/ViewStatePlugin.cs#L209:
Console.WriteLine(payloadString); |
Can output Base64-encoded serialized XAML data in the console
Compile ysoserial.net to generate ysoserial.exe, create a new shellPayload.cs in the same directory with the following content:
class E |
Use ysoserial.exe to generate ViewState with the following command:
ysoserial.exe -p ViewState -g ActivitySurrogateSelectorFromFile -c "shellPayload.cs;System.Web.dll;System.dll;" --validationalg="SHA1" --validationkey="CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF" --generator="042A94E8" |
Obtain Base64-encoded serialized xaml data from the output
(2) Calculate the signature of the serialized xaml data to generate the final ViewState data
Code as follows:
static string CreateViewState(byte[] dat,string generator,string key) |
The complete implementation code has been uploaded to GitHub, the address is as follows:
An open-source project
The code implements calculating a signature from serialized XAML data to generate the final ViewState data
Advantages:
Occupies less space, can directly use existing Payloads from ysoserial.net
Disadvantages:
Debugging and modification are relatively cumbersome
Note:
The CreateViewState() functions in the above two implementation methods differ in details, requiring attention
0x04 Another Detail in Exploit Script Development
---
Used to achieve command execution from Exchange file read/write permissions
Following the structure from https://github.com/zcgonvh/CVE-2020-0688/blob/master/ExchangeCmd.cs, encapsulate the serialized XAML data in an array, use validationkey and generator as parameters to sign the serialized XAML data, forming the final ViewState content
The complete implementation code has been uploaded to GitHub, the address is as follows:
An open-source project
The code supports deserialization execution at two locations: the default files %ExchangeInstallPath%\FrontEnd\HttpProxy\owa\auth\errorFE.aspx and %ExchangeInstallPath%\FrontEnd\HttpProxy\ecp\auth\TimeoutLogout.aspx
The code first sends data implemented by ysoserial.net for ActivitySurrogateDisableTypeCheck, then can execute commands and obtain command execution results, sending data via POST with the parameter __Value, using character-by-character XOR encryption for communication data
The supported features are consistent with ExchangeDeserializeShell-NoAuth-ActivitySurrogateSelectorFromFile.py
0x05 Summary
---
This article analyzes the details of generating ViewState, introduces two programmatic methods for generating ViewState, and writes code to implement another exploitation script from Exchange file read/write permissions to command execution