0x00 Preface
---
The previous article 'ProxyOracle Exploitation Analysis 1—CVE-2021-31195' introduced the method to obtain user cookie information. This article will explain how to recover the user's plaintext password through a Padding Oracle Attack.
0x01 Introduction
---
This article will cover the following:
- Implementation Approach
- Partial Open Source Code
0x02 Implementation Approach
---
Prerequisites for implementing a Padding Oracle Attack:
1. Obtain the ciphertext and its corresponding IV (Initialization Vector)
2. Be able to trigger the decryption process of the ciphertext and know the decryption result
Applied to Exchange, the specific details are as follows:
(1) Obtain the ciphertext and the corresponding IV (Initialization Vector)
The cadata in the Cookie information corresponds to the ciphertext, and cadataIV corresponds to the IV
(2) Be able to trigger the decryption process of the ciphertext and know the decryption result
We can obtain the detailed decryption process by decompiling the DLL using dnSpy, as follows:
Use dnSpy to open the file C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\bin\Microsoft.Exchange.FrontEndHttpProxy.dll
Navigate sequentially to Microsoft.Exchange.HttpProxy -> FbaModule -> ParseCadataCookies(HttpApplication httpApplication)
As shown in the figure below

Obtain the method to trigger the ciphertext decryption process:
Access https:///owa, send a GET request packet, and ensure the Cookie includes cadata, cadataTTL, cadataKey, cadataIV, and cadataSig
Judgment of the ciphertext decryption result:
After sending the GET request packet, a 302 redirect occurs by default, and the response content indicates whether the decryption was successful
The decryption result can be determined by checking the definition of LogonReason
As shown in the figure below

From this, it can be seen that 0 represents None, here it is a format error; 1 represents Logoff; 2 represents InvalidCredentials; 3 represents Timeout; 4 represents ChangePasswordLogoff
When attempting decryption, reason=2 indicates successful decryption
When reason=3, it indicates that the Cookie has expired, and Padding Oracle Attack cannot be performed at this time
Note:
The Cookie validity period for Exchange is 12 hours
0x03 Partial Open Source Code
---
1. Crack the 8th byte of the 0th block
The complete example code implemented in Python is as follows:
#python3 |
Pay attention to the following details:
(1) Traverse from 0x00 to 0xFF
for i in range(0, 256): |
(2) Ciphertext Block
Block length is 16
(3) Set allow_redirects=False when sending GET requests to disable redirection
2. From Padded Plaintext to Actual Plaintext
After completing the entire Padding Oracle Attack, we obtain a segment of padded plaintext
The complete example code for converting padded plaintext to actual plaintext is as follows:
#python3 |
The code execution result is shown in the figure below

The following details require attention:
(1) After obtaining the padded plaintext, PKCS7 must be used for data padding.
(2) The actual plaintext format is username:password.
Although the first two bytes of the plaintext cannot be decrypted, resulting in an incomplete display of the username, this does not cause any impact because the 'lgn' in the Cookie information we obtained displays the complete username.
0x04 Summary
---
This article introduces the method of restoring the user's plaintext password through a Padding Oracle Attack. The key code has been open-sourced, and the remaining parts are left for the reader to complete independently.